2015-05-14 73 views
0

我想创建一种使用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是一个异步调用获取新数据的结果,此代码是函数的回调中。

+1

您需要为'.data()'指定一个键函数,否则它将按索引匹配,例如。 '.data(data.items,function(d){return d;})'来匹配数据。 –

+0

完美的是答案,谢谢! – Mark

回答

1

您需要指定一个键功能.data(),否则它将按索引匹配。例如。 .data(data.items, function(d) { return d; })以匹配实际数据。