How to cancel scheduled transition in d3?

2019-04-21 16:03发布

问题:

Transition Code,

d3.select('chart').select('svg')
    .selectAll("circle")
    .data(sampleData)
    .enter().append('circle')
    .each(function (d,i) 
           {
                d3.select(this)
                  .transition()
                  .delay(i*50)
                  .attr('cx', function(d) {return d.x;})
                  .attr('cy', function(d) {return d.y;})
                  .attr('r', 4);
           });

How can I stop/cancel the scheduled/delayed transactions?

回答1:

As pointed out in the other answer, all you need is to schedule a new transition. However, the whole thing is much easier than what you're doing in your code -- there's no need for the separate .each() function. To schedule the transitions initially, you can simply do

d3.select('chart').select('svg')
  .selectAll("circle")
  .data(sampleData)
  .enter().append('circle')
  .transition()
  .delay(function(d, i) { return i*50; })
  .attr('cx', function(d) {return d.x;})
  .attr('cy', function(d) {return d.y;})
  .attr('r', 4);

The function to stop all transitions (scheduled and running) is simply

d3.selectAll("circle").transition();

Complete demo here.



回答2:

The accepted answer does not work with the most recent version of d3. If you're using d3 v4, you should call .interrupt() on your selection.



回答3:

Starting a new transition on the element stops any transition that is already running. You can pause/stop a d3 transition by setting a new transition with duration as 0.

function stopCircleTransitions(){
    if(startedApplyingTransitions)
       d3.select('chart').select('svg')
         .selectAll("circle")
         .each(function(d,i){
             d3.select(this)
               .transition()
               .duration(0);
         });
    }
} 

If you would like to stop the transition if and only if it is started applying, you can try the code below.

 var startedApplyingTransitions = false;
 d3.select('chart').select('svg')
   .selectAll("circle")
   .data(sampleData)
   .enter()
   .append('circle')
   .each(function (d,i){
       d3.select(this)
           .transition()
           .delay(i*50)
           .attr('cx', function(d) {return d.x;})
           .attr('cy', function(d) {return d.y;})
           .attr('r', 4)
           .each("end", function(){ //this code will do the trick
               startedApplyingTransitions = true;
           });
   });