简单SVG,x轴上的时间刻度为最后5秒,每隔一秒我添加一个圆圈,每隔100ms从右向左移动所有现有圆圈。
var data = [];
setInterval(function() {
var now = new Date();
var fiveSecAgo = new Date(now.getTime() - 5000);
x.domain([fiveSecAgo, now]);
svg.selectAll("circle")
.transition()
.ease("linear")
.duration(100)
.attr("cx", function(d) {
return x(d.date);
});
}, 100);
// add circle every second
setInterval(function() {
data.push({
date: new Date()
});
svg.selectAll("circle")
.data(data).enter()
.append("svg:circle")
.attr("r", 4)
.attr("cx", function(d) {
return x(d.date);
})
.attr("cy", height / 2);
}, 1000);
现在这一切都很好,但是在前5秒之后,将会有负x值(超过5秒)的元素,所以我想删除它们,保持最后5个内现有元素的平滑过渡秒。
所以我的方法是让我的数据数据只包含最后5秒:
for (var i = 0; i < data.length; i++) {
if (data[i].date < fiveSecAgo) {
data.shift();
} else {
break;
}
}
在转换现有的圈子然后执行.exit()。remove()之前。虽然旧元素将被删除,但转换不再平稳。
答案 0 :(得分:2)
问题是默认情况下,D3是按索引匹配数据。也就是说,您修改的数据与错误的DOM元素匹配,因此您会看到它们以奇怪的方式移动。通过向.data()
提供关键功能可以很容易地解决这个问题,告诉D3如何进行匹配:
.data(data, function(d) { return d.date; })
此外,修改迭代的数组是不安全的,所以不要在循环内部.shift()
。在你的情况下,它足以做到
if(data[0].date < fiveSecAgo) data.shift();
完整演示here。我也清理了其他一些东西。