我正在尝试在一个svg元素中动态创建不同类型的nvd3图表(主要是因为我想动态切换图表类型)。为此,每次更改图表类型时,我都会删除svg-Element的每个子项并添加新图表。
这一切都很有效,问题出现在我调整窗口大小并通过chart.update
调用nv.utils.windowResize
时。出于某些奇怪的原因,在此过程中,旧图表会再次添加到DOM中,并显示2个图表。
这是一个带有行为的示例plunker: Plunker。 只需单击按钮即可将图表类型从一行更改为条形图,并调整预览窗口的大小,应该这样做。
之前有任何人遇到此问题或知道我可以尝试解决此问题吗?
非常感谢您的帮助!
答案 0 :(得分:0)
在我看来,你宣布图表的方式存在问题。 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;
});
}
答案 1 :(得分:0)
我可以通过将自定义回调函数传递到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();
});