What is the correct way of chaining transitions in d3?

南笙酒味 提交于 2019-12-11 09:14:15

问题


Inspired by this other question, I created an animation (jsfiddle) that draws a circle, then a line that connects it to another circle. I read that D3 v3 doesn't need to listen the the end event to chain transitions.

The code below works, but how should I refactor it so it doesn't use end events?

var margin = {top: 40, bottom: 40, left: 40, right: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.bottom - margin.top;

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var t0 = svg.append("circle")
    .attr("r", 0)
    .attr("cx", 40)
    .attr("cy", 40)
    .attr("class", "point")
  .transition()
    .duration(500)
    .attr("r", 4);

var t1 = t0.each("end", function(){ 
    var t2 = svg.append("path")
        .style("stroke", "#000")
        .style("stroke-width", 2)
        .style("fill", "none")
        .attr("d", "M40,40L40,40")
      .transition()
        .ease("linear")
        .duration(500)
        .attr("d", "M40,40L80,80");

    t2.each("end", function(){ 
        svg.append("circle")
            .attr("r", 1)
            .attr("cx", 80)
            .attr("cy", 80)
            .attr("class", "point")
          .transition()
            .duration(500)
            .attr("r", 4);
    });
});

回答1:


Ok, thanks to the comments I realized I can just do this:

  • append the first item and create the first transition with t0 = svg.transition(),
  • append the second item and create the second transition (which will trigger after t0 ends) t1 = t0.transition()
  • repeat for the third item t2 = t1.transition()

Note that if you want to change the duration of each transition, it must be done when you define it. This is wrong:

var t1 = t0.transition()
    .ease("linear");
t1.select("path.line")
    .duration(500)
    .attr("d", "M40,40L80,80");

It should be:

var t1 = t0.transition()
    .ease("linear");
    .duration(500)
t1.select("path.line")
    .attr("d", "M40,40L80,80");

This is the final code (jsfiddle):

var margin = {top: 40, bottom: 40, left: 40, right: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.bottom - margin.top;

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.append("circle")
    .attr("r", 0)
    .attr("cx", 40)
    .attr("cy", 40)
    .attr("class", "point-start")

svg.append("path")
    .style("stroke", "#000")
    .style("stroke-width", 2)
    .style("fill", "none")
    .attr("class", "line")
    .attr("d", "M40,40L40,40");

svg.append("circle")
    .attr("r", 0)
    .attr("cx", 80)
    .attr("cy", 80)
    .attr("class", "point-end")

var t0 = svg.transition()
    .duration(100);

t0.select("circle.point-start")
    .attr("r", 4);

var t1 = t0.transition()
    .duration(500)
    .ease("linear");
t1.select("path.line")
    .attr("d", "M40,40L80,80");

var t2 = t1.transition()
    .duration(100);
t2.select("circle.point-end")
    .attr("r", 4);


来源:https://stackoverflow.com/questions/26319711/what-is-the-correct-way-of-chaining-transitions-in-d3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!