我们的想法是拥有一个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
答案 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)
答案 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。