我想创建一种使用D3.js的时间线图表。我已经掌握了大部分控制逻辑,但是当我在页面之间移动时,我的数据点不像预期的那样运行。时间表显示持续一周的数据收集的3小时窗口。用户可以点击左侧和右侧的箭头以三小时的方式向前和向后移动。由于在每次点击中获取接下来三个小时的数据,我期望exit()函数包含所有先前的数据点,因为它们都应该离开屏幕,但是这不会似乎发生了。相反,它将删除第一页上的10个点中的5个。我可以通过不使用exit()并手动强制删除所有点来获得我想要的行为,但我更愿意理解它为什么不能使用exit()。在同一时间过渡xAxis和数据 - D3.js
使事情复杂化,随着数据退出并进入图表,它将从右向左转换。与此同时,我转换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是一个异步调用获取新数据的结果,此代码是函数的回调中。
您需要为'.data()'指定一个键函数,否则它将按索引匹配,例如。 '.data(data.items,function(d){return d;})'来匹配数据。 –
完美的是答案,谢谢! – Mark