我尝试使用D3.js创建一种时间线图表。我已经完成了大部分控制逻辑,但是当我在页面之间移动时,我的数据点的行为并不像预期的那样。时间线显示持续一周的数据收集的3小时窗口。用户可以单击左右箭头,在三个小时的时间内向前和向后移动。
由于每次点击都会获取接下来三个小时的数据,我希望exit()函数包含所有以前的数据点,因为它们都应该离开屏幕,但是这并没有。似乎发生了。相反,它会删除第一页上的10个点中的5个。我可以通过不使用exit()并手动强制删除所有点来获得我想要的行为,但我更理解为什么它不能使用exit()。
使问题复杂化,当数据退出并进入图表时,它会从右向左转换。同时,我转换xAxis的域边界,以使用户的外观及时向前移动。我开始怀疑它的这种转变导致exit()函数混淆了应该和不应该在图表上的内容。
我已经包含了我的代码部分,用于处理从图表中删除元素的问题。如果需要任何其他代码段,请告诉我。
elements = svg.selectAll('.news').data(data.items);
// Remove
var exitingLabels = elements.exit(),
updatingLabels = elements,
creatingLabels = elements.enter();
console.log(exitingLabels.selectAll('rect'));
console.log(updatingLabels.selectAll('rect'));
console.log(creatingLabels);
exitingLabels.selectAll('circle')
.transition()
.duration(1500)
.ease('sin-in-out')
.attr('cx', function(d){return x($window.moment(d.date, 'YYYY-MM-DDTHH:mm:ss.000Z').clone().subtract(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).format('x')) + 29;});
exitingLabels.selectAll('line')
.transition()
.duration(1500)
.ease('sin-in-out')
.attr('x1', function(d){return x($window.moment(d.date, 'YYYY-MM-DDTHH:mm:ss.000Z').clone().subtract(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).format('x')) + 29;})
.attr('x2', function(d){return x($window.moment(d.date, 'YYYY-MM-DDTHH:mm:ss.000Z').clone().subtract(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).format('x')) + 29;});
exitingLabels.selectAll('rect')
.transition()
.duration(1500)
.ease('sin-in-out')
.attr('x', function(d){return x($window.moment(d.date, 'YYYY-MM-DDTHH:mm:ss.000Z').clone().subtract(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).format('x'));});
exitingLabels.selectAll(function() { return this.getElementsByTagName('foreignObject'); })
.transition()
.duration(1500)
.ease('sin-in-out')
.attr('x', function(d){return x($window.moment(d.date, 'YYYY-MM-DDTHH:mm:ss.000Z').clone().subtract(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).format('x'));});
exitingLabels.transition()
.delay(1600)
.each('end', function(a){console.log(a);})
.remove();
data.items是异步调用以获取新数据的结果,此代码位于该函数的回调中。
答案 0 :(得分:1)
您需要为.data()
指定一个键功能,否则它将按索引匹配。例如。 .data(data.items, function(d) { return d; })
与实际数据匹配。