【问题标题】:updating a line graph in d3 is not working在 d3 中更新折线图不起作用
【发布时间】:2013-12-06 04:08:11
【问题描述】:

我正在尝试更新折线图,它没有抛出任何错误,但也没有更新图表。

我正在删除一个点并添加一个新的点,其速率增加,created_at 日期增加一秒(尝试关注http://bl.ocks.org/benjchristensen/1148374

function redrawWithoutAnimation() {

    for (var i in chart_data) {
        linedata = chart_data[i];
        //delete first element of array
        linedata.points.reverse().shift();
        //create a new point
        rate = linedata.points[0].rate + 1;
        created_at = linedata.points[0].created_at + 6000;
        new_point = {};
        new_point.rate = rate;
        new_point.created_at = created_at;
        linedata.points.push(new_point);
        console.log(linedata);

    }

    // static update without animation
    svg.selectAll("path")
        .data([linedata.points]); // set the new data
    line(linedata.points); // apply the new data values
}

redrawWithoutAnimation();
setInterval(function () {
    redrawWithoutAnimation();
}, 8000);

这是我的代码 http://jsfiddle.net/yr2Nw/8/

【问题讨论】:

    标签: javascript svg d3.js nvd3.js


    【解决方案1】:

    工作小提琴:http://jsfiddle.net/reblace/GsaGb/1

    这里有几个问题...

    首先,您在 for 循环中更新了所有 chart_data,但在循环之外,您只是尝试更新循环执行后仍存储在 linedata 变量中的行。你应该尽量避免变量的范围比他们需要的更大。它可能会导致像这样的错误:

    svg.selectAll("path").data([linedata.points]);
    line(linedata.points);
    

    您应该改为使用 D3 的数据连接,以声明方式一次将新数据重新连接到所有路径:

    linesGroup.selectAll("path")
        .data(chart_data)
        .attr("d", function(d){ return line(d.points); });
    

    该代码所做的是选择路径,然后将每个路径连接到 chart_data 元素,然后将适当的行生成器绑定到适当路径的“d”属性。

    然后,您需要更新您的 x 轴和 y 轴,否则绘图只会从绘制的区域射出。此代码正在更新域,然后将轴重新绑定到 dom 元素,以便它们重绘:

    xAxis.scale().domain([ 
        d3.min(chart_data, function (c) { return d3.min(c.points, function (v) { return v.created_at; }); }),
        d3.max(chart_data, function (c) { return d3.max(c.points, function (v) { return v.created_at; }); })
    ]);
    
    yAxis.scale().domain([
        0,
        d3.max(chart_data, function (c) { return d3.max(c.points, function (v) { return v.rate; }); })
    ]);
    
    svg.select(".x.axis").call(xAxis);
    svg.select(".y.axis").call(yAxis);
    

    我在 Fiddle 中修复了一些其他错误。例如,您需要根据数组中的最后一个元素而不是第一个元素来计算新点的时间,否则该线无法正确插值,因为它不再是一个连续函数......这有点多进行线路更新的简洁方法:

    for (var i=0; i<chart_data.length; i++) {
        linedata = chart_data[i];
        //delete first element of array
        var removedPoint = linedata.points.shift();
    
        //create a new point
        var lastpoint = linedata.points[linedata.points.length-1];
        var new_point = {
            rate: removedPoint.rate,
            created_at: lastpoint.created_at + 6000
        };
        linedata.points.push(new_point);
    }
    

    还请注意,您不应该对数组使用 for(var in) 循环,因为它是用于迭代对象中的属性。

    仍然存在一些问题,但我认为这应该可以帮助您克服遇到的障碍。无论如何,它看起来很酷!

    【讨论】:

    • 非常感谢,非常有帮助!!
    【解决方案2】:

    Fine fenac.. 您面临很多问题,因为您的数据格式不符合您的要求..

    按照http://bl.ocks.org/benjchristensen/1148374,x轴数据必须是(data[](数据数组))

    你的数据是这样的

    [objects,object,object] 其中每个对象都拥有一个 xaxis 值的元素.. 所以推和移是不可能的..

    尝试将数据 (linedata.points) 的格式更改为数组 (data[]) 并尝试一下,确保它有效..

    您只需将 linedata.points 中的所有值放入数组 data[] 并使用此data[] to animate your line..

    既然你的多行......你需要创建2D array并且必须相应地传递它们......

    干杯..

    我更新了你的 jsfiddle

    setInterval(function () {
        console.log(linedata.points);
        var v = linedata.points.shift(); // remove the first element of the array
    linedata.points.push(v); // add a new element to the array (we're just taking the number we just shifted off the front and appending to the end)
        redrawWithoutAnimation();
    }, 3000);
    

    http://jsfiddle.net/yr2Nw/9/

    但在你完成这项工作之前它仍然无法工作......

    个人建议:先试试单线图,再循环多线...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      • 1970-01-01
      • 2013-06-15
      • 2016-03-21
      • 1970-01-01
      相关资源
      最近更新 更多