D3.js:停止转换被中断?

Ric*_*ard 9 javascript d3.js

我正在和D3.js一起工作 我有很好的转换工作,但我只有一个问题:如果第二次转换在第一次转换结束之前开始,

这是一个证明问题的JSFiddle:http://jsfiddle.net/kqxhj/11/

它在大多数情况下都能正常工作 - 随着数据的变化,CDG和LAX会被追加和删除 - 但如果你快速连续点击两次按钮,你会发现新的元素没有出现.

这是我的代码的核心:

function update(data) { 

  var g = vis.selectAll("g.airport").data(data, function(d) { 
    return d.name;  
  });
  var gEnter = g.enter().append("g")
  .attr("class", function(d) {    
    return "airport " + d.name;
  });
  // Perform various updates and transitions... 
  [...]

  // Remove exited elements. 
  g.exit().transition()
    .duration(1000)
   .attr("transform", "translate(0," + 1.5*h + ")");
  g.exit().transition().delay(1000)
   .remove();
}

d3.select('#clickme').on("click", function() {  
  update(current_data); 
});
Run Code Online (Sandbox Code Playgroud)

我试图添加一些调试语句来弄清楚发生了什么,但我只能看到,当它发生时,退出选择有4个元素,而不是3 - 我不明白为什么会这样.

有没有办法,无论是在D3还是在基本的JavaScript中,我都可以确保转换不重叠?

Pab*_* EM 9

更新:自D3版本3.5(2014年10月)以来,可以通过使用命名转换对元素执行并发转换.您只需为每个转换添加一个不同的名称.

  • 我发现这很有用.当向对象添加两个具有相同名称的转换时,转换是独占的,即第二个中断/取消第一个转换. (3认同)
  • 这是我一直在寻找的答案 (3认同)

Ago*_*gop 8

发生了什么是数据表示在从DOM中删除之前"重新进入"(因为你的remove()调用是在转换时链接的).但是,如果尚未从DOM中删除数据表示,则enter()选择将不包含该数据,因为它已经存在!然而,您的过渡将继续执行,您的数据表示将在没有机会"重新进入"的情况下消失.

您需要做的是为现有元素提供某种标识符.例如:

g.exit().classed('exiting', true);
Run Code Online (Sandbox Code Playgroud)

然后,当您更新选择时,如果元素"重新进入",则取消退出转换并将其恢复为原始状态:

g.filter('.exiting')
    .classed('exiting', false)
    .transition() // new transition cancels the old one so that remove() isn't called
        .attr('foo', 'bar'); // return to original state
Run Code Online (Sandbox Code Playgroud)

我已经调整了你的小提琴来演示解决方案:http://jsfiddle.net/hX5Tp/

这是一个简单的小提琴,可以清楚地展示问题(和解决方案):http://jsfiddle.net/xbfSU/


Art*_*hur 5

在D3中,较新的转换总是中断并覆盖较旧的转换.您可以通过在选择中使用each()方法来解决您的设计问题.例如

d3.select('.animated')
.transition()
.duration(1000)
.attr({
    ... // Change something
})
.each('end', function () {
    d3.select(this)
    .attr({
        ... // Change something else, after previous transition
    });
});
Run Code Online (Sandbox Code Playgroud)