动态更新D3图表

时间:2016-02-10 16:25:33

标签: d3.js

我们的想法是拥有一个d3垂直条形图,该条形图将提供实时数据。 我使用setInterval函数模拟实时数据,该函数更新数据集中元素的值:

var updateData = function(){
    a = parseInt(Math.random() * 100),
    b = parseInt(Math.random() * 100),
    c = parseInt(Math.random() * 100),
    d = parseInt(Math.random() * 100);
    dataset = [a, b, c, d];
    console.log(dataset);
};

// simullate live data input
var update = setInterval(updateData, 1000);

我想每2秒更新一次图表。 为此,我需要一个获取新数据集的更新函数,然后设置转换动画以显示新结果。 像那样:

var updateVis = function(){
   ..........
};

var updateLoop = setInterval(drawVis,2000);

我不想简单地删除图表并再次绘制。我想为每个条形的新旧条形高度之间的过渡设置动画。

结帐fiddle

2 个答案:

答案 0 :(得分:1)

这是要走的路。 想想你为获得初始图表所做的工作: 1)获取数据 2)将它绑定到元素(.enter()) 3)将元素属性设置为数据的函数。

嗯,你再次这样做: 在函数updateData中,您获得了新的dataset,这是第一步。 然后,重新绑定它:

d3.selectAll("rect").data(dataset);

最后更新属性:

d3.selectAll("rect").attr("y",  function(d) {
        return y(d);
    })
    .attr("height", function(d) {
        return h - y(d);
    });

(想要过渡吗?去吧。很容易在代码中添加,但如果你想深入了解它,最好阅读this tuto

Check it on fiddle

答案 1 :(得分:1)

由于您没有更改栏数,因此可以这么简单:

var updateVis = function(){
   svg.selectAll(".input")
    .data(dataset)
    .transition()
    .attr("y",  function(d) {
            return y(d);
        })
        .attr("height", function(d) {
            return h - y(d);
    });
};

更新了fiddle

但你的下一个问题是,如果我需要不同数量的酒吧怎么办?这是您需要处理输入,更新,退出更好的地方。您可以编写一个函数进行初始绘制或更新。

function drawVis(){

 // update selection
 var uSel = svg.selectAll(".input")
        .data(dataset);

 // those exiting
 uSel.exit().remove();

 // new bars
 uSel
        .enter()
        .append("rect")
        .attr("class", "input")
        .attr("fill", "rgb(250, 128, 114)");

 // update all
 uSel
        .attr("x", function(d, i) {
            return i * (w / dataset.length) + 2.5/100 * w;
        })
        .attr("width", w / dataset.length - barPadding)
        .attr("height", y(0))
        .transition().duration(750).ease("linear")
        .attr("y",  function(d) {
            return y(d);
        })
        .attr("height", function(d) {
            return h - y(d);
});

}

fiddle