d3: How to properly chain transitions on different selections

后端 未结 1 1665
野趣味
野趣味 2020-12-08 01:17

I am using V3 of the popular d3 library and basically want to have three transitions, followed by each other: The first transition should apply to the exit selection, the se

相关标签:
1条回答
  • 2020-12-08 01:46

    Sure. Here are two ways.

    First, you could use an explicit delay, which you then compute using selection.empty to skip empty transitions. (This is only a minor modification of what you have already.)

    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

    One tricky thing here is that you have to create the transition on the updating elements before you create the transition on the entering elements; that’s because enter.append merges entering elements into the update selection, and you want to keep them separate; see the Update-only Transition example for details.

    Alternatively, you could use transition.transition to chain transitions, and transition.each to apply these chained transitions to existing selections. Within the context of transition.each, selection.transition inherits the existing transition rather than creating a new one.

    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

    I suppose the latter is a bit more idiomatic, although using transition.each to apply transitions to selections (rather than derive transitions with default parameters) isn’t a widely-known feature.

    0 讨论(0)
提交回复
热议问题