timer example?

3,180 views
Skip to first unread message

wimdows

unread,
Jun 17, 2011, 8:07:17 AM6/17/11
to d3-js
Does anyone know of, or have a working example of how the d3.timer is
used?
Based on the documentation alone, I'm still a bit in the dark about
it's usage.

Much obliged!

Jason Davies

unread,
Jun 17, 2011, 8:38:27 AM6/17/11
to d3...@googlegroups.com

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/

Jamie Popkin

unread,
Jun 17, 2011, 11:31:48 AM6/17/11
to d3...@googlegroups.com
Great example Jason.... And thanks for the explanation.

--
Jamie Popkin
Little Earth

wimdows

unread,
Jun 17, 2011, 4:06:53 PM6/17/11
to d3-js
Thanks, Jason. I really should have found those myself. I looked for
d3.timer via Google, but that didn't deliver any results.

Having looked at the example, I still don't get it. I expected
something more like javascript timers, I guess. For instance: why is
there no explicit interval being set anywhere?

In my code there is this while loop that should cycle through colors
depending on the year that is fed in, like so:
function animeerMij (form) {

currentYear = form.jaarmenu.value;

d3.timer(function() {

if (currentYear == 2009) { currentYear = 1981; };

while (currentYear <= 2008) {

currentYear++;

currentcountrydata = countrydata.filter(function(d) { return
d.YEAR==currentYear; });

var bars1 = vis.selectAll("g.bar1")
.data(currentcountrydata);

bars1.transition()
.select("rect")
.delay(0)
.duration(250)
.style("fill", function(d) kleur(d.CON));


var bars2 = vis.selectAll("g.bar2")
.data(currentcountrydata);

bars2.transition()
.select("rect")
.delay(250)
.duration(250)
.style("fill", function(d) kleur(d.POL));


var bars3 = vis.selectAll("g.bar3")
.data(currentcountrydata);

bars3.transition()
.select("rect")
.delay(500)
.duration(250)
.style("fill", function(d) kleur(d.SOC));


d3.select("#jaarkop").html(currentYear);

}
})
}

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?

Jason Davies

unread,
Jun 18, 2011, 5:59:56 AM6/18/11
to d3...@googlegroups.com
On Fri, Jun 17, 2011 at 01:06:53PM -0700, wimdows wrote:
> Having looked at the example, I still don't get it. I expected
> something more like javascript timers, I guess. For instance: why is
> there no explicit interval being set anywhere?

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. :-)

wimdows

unread,
Jun 18, 2011, 8:51:02 AM6/18/11
to d3-js
Thanks, Jason, that's the sort of thing I mean. I will go and try and
implement it right away. It could have been quite a while before I had
figured that one out myself! :)

wimdows

unread,
Jun 18, 2011, 9:00:55 AM6/18/11
to d3-js
Wonderful! That works like a charm! I haven´t fine tuned the timings
yet, so I can´t see whether I need to go for a version in which i
catch the ´end´ events, but in principle this seems to do what I want
it to do.
Reply all
Reply to author
Forward
0 new messages