【问题标题】:nvd3 passing wrong event on stateChange (when clicking legend) after chart is reloaded重新加载图表后,nvd3 在 stateChange 上传递错误事件(单击图例时)
【发布时间】:2014-05-25 18:09:52
【问题描述】:

我有一个 nvd3 多条形图(但饼图也会出现同样的问题)。

我想在用户启用或禁用系列时保存图例的状态,方法是在图例中单击它。所以我正在监听 stateChange 事件。

在下面的示例代码中有两个系列。当用户单击 series1 以禁用它时,控制台应记录:

New State: {"disabled":[true,false]}

使用来自服务器的新数据刷新图表后,问题开始出现(由以下代码中的 setInterval 模拟)。第一次刷新后,我总是收到错误事件,即 disabled 属性的值搞砸了

也许我刷新图表的方式不对?

这里是示例代码:

  var initialData = [
      { key: 'series1', values: [
            { x: 0, y: 10},
            { x: 1, y: 44}
          ]},
      { key: 'series2', values: [
            { x: 0, y: 25},
            { x: 1, y: 11}
          ]}
    ];

  var chart;
  nv.addGraph(function() {

      chart = nv.models.multiBarChart()
        .delay(0);

      d3.select('#chart1 svg')
          .datum(initialData)
          .call(chart);

      nv.utils.windowResize(chart.update);

      chart.dispatch.on('stateChange', function(e) {
        nv.log('New State:', JSON.stringify(e));
      });


      setInterval(function ()
      {
        var newDataFromServer = [
          { key: 'series1', values: [
                { x: 0, y: Math.floor((Math.random()*100)+1)},
                { x: 1, y: Math.floor((Math.random()*100)+1)}
              ]},
          { key: 'series2', values: [
                { x: 0, y: Math.floor((Math.random()*100)+1)},
                { x: 1, y: Math.floor((Math.random()*100)+1)}
              ]}
        ];

        d3.select('#chart1 svg')
          .datum(newDataFromServer)
          .call(chart);

        nv.utils.windowResize(chart.update);

      }, 5000);

      return chart;
  });

【问题讨论】:

    标签: javascript d3.js charts nvd3.js


    【解决方案1】:

    我找到了一个可行的解决方案。我没有时间进一步调查,但在以下代码中 (nvd3/legend.js):

      .on('click', function(d,i) {
        dispatch.legendClick(d,i);
        if (updateState) {
           if (radioButtonMode) {
                // etc ...
           }
           else {
                // Note: this 'd' doesn't belong to the 'data' array in the current scope
               d.disabled = !d.disabled;
               // etc ...
           }
           dispatch.stateChange({
              // The old data is notified as event
              disabled: data.map(function(d) { return !!d.disabled })
           });
        }
      })
    

    当它行为不端时(即第一次更新后),d 对象不属于此范围内的 data 数组(它应该这样做)。我猜这个 data 总是指向初始数据数组。

    作为更新图表的解决方法,我获取初始数组并就地更新它:

    // Get reference to data array object
    var chartDatum = d3.select('#chart1 svg')
                            .datum();
    // Clear array and copy new data into it                        
    chartDatum.length = 0;
    angular.extend(chartDatum, newDataFromServer); // Or jQuery extend, or equivalent
    chart.update();
    

    【讨论】:

    • 我想知道您的问题是否与两个数据集具有相同的键有关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    相关资源
    最近更新 更多