NVD3折线图与实时数据

时间:2012-09-22 23:57:22

标签: d3.js nvd3.js

我有一个非常简单的折线图,使用NVD3.js编写。我写了一个基于计时器的简单重绘,从我见过的例子中提取,但我得到了错误

未捕获的TypeError:无法读取未定义的属性“y”

JS是

    var data = [{
        "key": "Long",
        "values": getData()
    }];
    var chart;

    nv.addGraph(function () {
          chart = nv.models.cumulativeLineChart()
                      .x(function (d) { return d[0] })
                      .y(function (d) { return d[1] / 100 })
                      .color(d3.scale.category10().range());

        chart.xAxis
            .tickFormat(function (d) {
                return d3.time.format('%x')(new Date(d))
            });

        chart.yAxis
            .tickFormat(d3.format(',.1%'));

        d3.select('#chart svg')
            .datum(data)
            .transition().duration(500)
            .call(chart);

        nv.utils.windowResize(chart.update);

        return chart;
    });


    function redraw() {
        d3.select('#chart svg')
            .datum(data)
          .transition().duration(500)
            .call(chart);
    }

    function getData() {
        var arr = [];
        var theDate = new Date(2012, 01, 01, 0, 0, 0, 0);
        for (var x = 0; x < 30; x++) {
            arr.push([theDate.getTime(), Math.random() * 10]);
            theDate.setDate(theDate.getDate() + 1);
        }
        return arr;
    }

    setInterval(function () {
        var long = data[0].values;
        var next = new Date(long[long.length - 1][0]);
        next.setMonth(next.getMonth() + 1)
        long.shift();
        long.push([next.getTime(), Math.random() * 100]);
        redraw();
    }, 1500);

3 个答案:

答案 0 :(得分:11)

第二个答案(评论后)

我看了source for cumulativeLineChart。您可以看到在创建图表期间创建了display.y属性。它依赖于私有方法:“indexify”。如果该方法的某些派生词被公开,那么在重绘之前你可能会做chart.reindexify()之类的事情。

作为临时解决方法,您可以在每次更新时从头开始重新创建图表。如果你删除过渡,这似乎工作正常。示例jsfiddle:http://jsfiddle.net/kaliatech/PGyKF/

第一个答案

我相信cumulativeLineChart中存在错误。似乎cumulativeLineChart动态地将“display.y”属性添加到系列中的数据值。但是,在将新值添加到重绘的系列中时,它不会重新生成此属性。我不知道为了做到这一点,尽管我是NVD3的新手。

你真的需要CumulativeLineChart,还是正常的折线图是否足够?如果是这样,我必须对您的代码进行以下更改:

  • cumulativeLineChart更改为lineChart
  • 从使用2维数据数组转换为使用数据对象(具有x,y属性)
    • (我对NVD3不太熟悉,不知道期望什么数据格式。二维数组显然适用于初始加载,但我认为它无法用于后续重绘。这可能与您遇到的相同问题有关使用cumulativeLineChart。我认为更改为对象也会修复cumulativeLineChart,但似乎没有。)

我也改变了以下内容,但并不重要:

  • 将getData函数修改为创建日期的新实例,以避免在日期增加时共享引用的意外后果。

  • 修改了更新间隔函数,以y(天数)为增量生成新数据,y值与getData函数的范围相同。

这是一个有效的jsfiddle:

答案 1 :(得分:1)

我发现了我认为更好的解决方案。出现此问题的原因是累积图表在处理期间设置y函数。每当您想要刷新图表时,首先将其设置回默认值,返回正确的原始y。在重绘功能中,请在更新前执行此操作:

chart.y(function (d) { return d.y; });

如果累积图表可以为自己执行此操作,那就更好了(在设置新的访问函数之前存储原始访问函数,并在重新编制索引之前将其放回)。如果我有机会,我会尝试推动修复。

答案 2 :(得分:0)

我遇到了同样的问题。我改变了

行上的y()函数
.y(function(d) { return d.display.y })

.y(function(d) { return d.display ? d.display.y : d.y })

这摆脱了错误。显然它不会在错误情况下显示(不存在的)索引值,但根据我的经验,图表会在显示定义的情况下再次更新,看起来是正确的。