Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Have `transition().duration(0)` execute immediately? #1951

Closed
vicapow opened this Issue Jul 23, 2014 · 4 comments

Comments

4 participants

vicapow commented Jul 23, 2014

I have a visualization that normally animates (using transition()) when the document resizes but whenever the user prints the visualization, I'd like to be able to set the dimensions of the visualization immediately by setting .duration(0) when the window.matchMedia('print') event fires. However, because the update doesn't happen immediately (in the current JS execution cycle) the resize never makes it to the printed rendering of the document.

Here's a quick little demo that shows the current behavior:

var body = d3.select('body')
  .style('background-color', 'blue')
  .style('width', '100%')
  .style('height', '100%')
  .transition()
  .duration(0)
  .style('background-color', 'green');
alert('test'); // => body background color is still blue (would like this to already be green.)
setTimeout(function(){ alert('test'); }); // body background color is now green.

It wasn't too hard to come up with a workaround for now but I wanted to see what others think about this proposed behavior and if it sounded desirable, I'd be happy to submit a diff.

The workaround:

function transition(sel) {
  if(shouldTransition) return sel.transition();
  return sel;
}
Collaborator

jasondavies commented Jul 24, 2014

Duplicate of #48. The solution is to call d3.timer.flush() after any zero-duration transitions to flush the timer queue synchronously.

Owner

mbostock commented Jul 28, 2014

Another related technique is to use d3.transition(selection):

function changeBackground(color) {
  d3.transition(d3.select("body")).style("background-color", color);
}

// Set background color to green, immediately.
changeBackground("green");

// Fade background to red.
d3.transition().each(function() {
  changeBackground("red");
});

@jasondavies, sorry, can't find any example on this. Should i do is as follows?

myCircles.transition()
    .duration(playing?500:0)
    .ease("linear")
     // if playing is true, these should animate 
     // if playing is false, these should not animate
    .attr("cy", function(d) { return d.y; })
    .attr("cx", function(d) { return d.x; })
    .attr("r", function(d) { return d.r; });

d3.timer.flush();

Thanks!

Collaborator

jasondavies commented Nov 13, 2014

Yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment