It's used in the polar clock example in examples/clock/clock.js.
It's primarily for animations, and it calls your callback as many times
as it can to render the animation smoothly. Your callback is called
with an "elapsed" argument which gives the time since the last call in
milliseconds. This is useful for rendering smooth transitions so you
can compute the appropriate interpolation.
Behind the scenes it uses requestAnimationFrame in browsers that support
it, so the browser can optimise concurrent animations into a single
reflow/repaint. Also, it doesn't fire at all if the tab is not
currently visible, so it saves on CPU/GPU usage, which is nice!
The clock example doesn't need the elapsed parameter as it just
recomputes the current date/time fields for each frame of the animation.
And of course, the .transition() operator makes use of d3.timer() to
queue the interpolated transitions i.e. it sets up the callbacks to fire
so that the relevant attributes are updated appropriately during the
animated transition.
I use d3.timer in my animated bézier curves demo and it's a lot smoother
than using setTimeout: <http://www.jasondavies.com/animated-bezier/>.
Hope that helps,
--
Jason Davies, http://www.jasondavies.com/
d3.timer is not a replacement for setInterval or setTimeout, so there is
no explicit interval. Its primary purpose is for animations, where you
want as many frames per second as possible. So you don't want to set an
interval, you just want it to fire as many times as is reasonably
possible.
> This approach doesn?t work, in the sense that there is no smooth year
> by year transition (there is only one or two per bar, while the header
> jumps to the last year). This, I guess, is a consequence of how while
> loops work (yes, I sort of knew that from way back, but still gave it
> a try), but I was hoping that the d3.timer would offer a way of
> getting around this by having the loop cycle in a timed fashion.
> This begs the question: was I wrong in hoping this, am I using the
> d3.timer wrong (obviously, maybe), or am I going at this the wrong
> way?
Yeah, I don't think you want d3.timer here. d3.timer is for animations,
and it's used internally by your use of .transition() anyway.
I'm not entirely sure what you're trying to achieve, but it sounds like
you want to cycle through some data one step at a time, and animate the
transitions between each step?
Here is one approach:
var currentYear = 2000,
targetYear = 2010;
function step() {
var currentData = data.filter(...);
d3.selectAll("g.bar1")
.data(currentData)
.transition()
.duration(250)
.style(...);
currentYear++;
if (currentYear < targetYear)
setTimeout(step, 250 + 100);
}
step();
This will animate a whole sequence of transitions, with 100ms delay
between each step. If you don't want a delay between each step, it
might be better to listen for transition "end" events instead to create
the next transition in the chain. Perhaps Mike can shed some light on
the best way to do this. :-)