调用resize事件时,NVD3将旧图表添加到svg

时间:2017-04-03 09:31:02

标签: angular nvd3.js

我正在尝试在一个svg元素中动态创建不同类型的nvd3图表(主要是因为我想动态切换图表类型)。为此,每次更改图表类型时,我都会删除svg-Element的每个子项并添加新图表。

这一切都很有效,问题出现在我调整窗口大小并通过chart.update调用nv.utils.windowResize时。出于某些奇怪的原因,在此过程中,旧图表会再次添加到DOM中,并显示2个图表。

这是效果图: enter image description here

这是一个带有行为的示例plunker: Plunker。 只需单击按钮即可将图表类型从一行更改为条形图,并调整预览窗口的大小,应该这样做。

之前有任何人遇到此问题或知道我可以尝试解决此问题吗?

非常感谢您的帮助!

2 个答案:

答案 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;
  });
}

https://plnkr.co/edit/pwiO8FCpGyd2JLG4hllW?p=preview

答案 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();
    });