NVD3 добавляет старый график в SVG, когда вызывается событие изменения размера
Я пытаюсь динамически создавать различные типы диаграмм nvd3 в одном элементе svg (в основном потому, что я хочу переключать типы диаграмм на лету). Для этого каждый раз, когда я меняю тип диаграммы, я удаляю каждого дочернего элемента моего svg-элемента и добавляю новую диаграмму.
Это все работает отлично, проблема возникает, когда я изменяю размер окна и звоню chart.update
через nv.utils.windowResize
, По какой-то странной причине во время этого процесса старые диаграммы снова добавляются в DOM, и отображаются 2 диаграммы.
Вот пример плунжера с поведением: Плункер. Просто нажмите кнопку, чтобы изменить тип диаграммы со строки на линейку, и измените размер окна предварительного просмотра.
Кто-нибудь имел эту проблему раньше или знает что-нибудь, что я могу попытаться решить это поведение?
Большое спасибо за любую помощь!
1 ответ
Мне удалось обойти это, передав пользовательскую функцию обратного вызова в nv.utils.windowResize
метод. При изменении размера диаграммы кажется, что она мигает, так как она много раз удаляется и перестраивается, но я не мог придумать альтернативного способа сделать это.
var removeChart = function(element) {
d3.select(element).selectAll('*').remove();
d3.selectAll('.nvtooltip').style('opacity', '0');
};
nv.utils.windowResize(function() {
// chartElement is a reference to the chart's <svg> element
removeChart(chartElement);
chart.update();
});
Мне кажется, что есть проблема с тем, как вы объявляете график. Оператор let использует область видимости, поэтому ваш оригинальный код:
if(that.useLine) {
let chart = nv.models.lineChart();
} else {
let chart = nv.models.discreteBarChart();
}
не сработает Диаграмма будет определена только в блоке if. Вы можете сделать это вместо этого (обратите внимание, что диаграмма объявлена вне замыкания):
private addGraph(): void {
let that = this;
let chart;
nv.addGraph(() {
d3.selectAll(`svg > *`).remove();
if(that.useLine) {
chart = nv.models.lineChart();
} else {
chart = nv.models.discreteBarChart();
}
let myData = that.testData();
d3.select('#chart svg')
.datum(myData)
.call(chart);
//Update the chart when window resizes.
nv.utils.windowResize(function() { chart.update() });
return chart;
});
}