【问题标题】:d3: How to properly chain transitions on different selectionsd3:如何正确链接不同选择的过渡
【发布时间】:2013-06-09 19:12:04
【问题描述】:

我正在使用流行的 d3 库的 V3,并且基本上希望有三个转换,依次为:第一个转换应该应用于退出选择,第二个转换到更新选择,第三个转换到进入选择。它们应该以这样的方式链接,即当其中一个选择为空时,跳过其各自的转换。 IE。当没有退出选择时,更新选择应该立即开始。到目前为止,我已经想出了这段代码(使用delay 函数)。

// DATA JOIN
var items = d3.select('#data').selectAll('.item');
items = items.data(data, function(d){ 
    return d.twitter_screenname;
});


// EXIT
items.exit().transition().duration(TRANSITION_DURATION).style('opacity', 0).remove();

// UPDATE
// Divs bewegen
items.transition().duration(TRANSITION_DURATION).delay(TRANSITION_DURATION * 1)
    .style('left', function(d, i) {
        return positions[i].left + "px";
    }).style('top', function(d, i) {
        return positions[i].top + "px";
    });

// ENTER
// Divs hinzufügen
var div = items.enter().append('div')
    .attr('class', 'item')
    .style('left', function(d, i) {
        return positions[i].left + "px";
    }).style('top', function(d, i) {
        return positions[i].top + "px";
    });

 div.style('opacity', 0)
    .transition().duration(TRANSITION_DURATION).delay(TRANSITION_DURATION * 2)
    .style('opacity', 1);

首先它不允许“跳过”转换,其次我认为有比delay 更好的方法。我查看了http://bl.ocks.org/mbostock/3903818,但我并没有真正理解发生了什么。

此外,不知何故,仅编写 items.exit().transition().duration(TRANSITION_DURATION).remove() 不适用于 items,可能是因为它们不是 SVG 元素,而是 divs。

【问题讨论】:

    标签: animation d3.js transition


    【解决方案1】:

    当然。这里有两种方法。

    首先,您可以使用显式delay,然后使用selection.empty 计算以跳过空转换。 (这只是对您已有的内容的微小修改。)

    var div = d3.select("body").selectAll("div")
        .data(["enter", "update"], function(d) { return d || this.textContent; });
    
    // 2. update
    div.transition()
        .duration(duration)
        .delay(!div.exit().empty() * duration)
        .style("background", "orange");
    
    // 3. enter
    div.enter().append("div")
        .text(function(d) { return d; })
        .style("opacity", 0)
      .transition()
        .duration(duration)
        .delay((!div.exit().empty() + !div.enter().empty()) * duration)
        .style("background", "green")
        .style("opacity", 1);
    
    // 1. exit
    div.exit()
        .style("background", "red")
      .transition()
        .duration(duration)
        .style("opacity", 0)
        .remove();
    

    http://bl.ocks.org/mbostock/5779682

    这里有一个棘手的问题是,您必须在更新元素上创建转换您在进入元素上创建转换之前;这是因为enter.append 将输入元素合并到更新选择中,并且您希望将它们分开;详情请见Update-only Transition example

    或者,您可以使用transition.transitionchain transitionstransition.each 将这些链式转换应用到现有选择。在transition.each 的上下文中,selection.transition 继承现有的过渡而不是创建一个新的。

    var div = d3.select("body").selectAll("div")
        .data(["enter", "update"], function(d) { return d || this.textContent; });
    
    // 1. exit
    var exitTransition = d3.transition().duration(750).each(function() {
      div.exit()
          .style("background", "red")
        .transition()
          .style("opacity", 0)
          .remove();
    });
    
    // 2. update
    var updateTransition = exitTransition.transition().each(function() {
      div.transition()
          .style("background", "orange");
    });
    
    // 3. enter
    var enterTransition = updateTransition.transition().each(function() {
      div.enter().append("div")
          .text(function(d) { return d; })
          .style("opacity", 0)
        .transition()
          .style("background", "green")
          .style("opacity", 1);
    });
    

    http://bl.ocks.org/mbostock/5779690

    我认为后者更惯用一些,尽管使用 transition.each 将转换应用于选择(而不是使用默认参数派生转换)并不是一个广为人知的功能。

    【讨论】:

    • 如果我错了,请纠正我,但我认为使用delay()-方法的代码中有一个小错误。当没有更新转换(即没有元素改变位置)时,items.enter().empty() 仍然等于false,所以元素退出,然后,duration 毫秒内没有任何反应,然后进入转换开始。但是,如果没有发生视觉更新转换,我希望退出转换立即跟随进入转换。因此,我将更新转换保存如下:
    • var updatedItems = div.transition() .duration(duration) .delay(!div.exit().empty() * duration) 并将.delay((!div.exit().empty() + !div.enter().empty()) * duration) 更改为.delay((!div.exit().empty() + !updatedItems.empty()) * duration)。这样它就可以根据需要工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多