Zoom transitions when d3 is driving a canvas

752 views
Skip to first unread message

Andrew Mao

unread,
Sep 22, 2012, 10:01:35 PM9/22/12
to d3...@googlegroups.com
I have a zoom-and-pan visualization using d3, which uses both SVG and canvas. Whenever there is a zoom or a pan, a draw function is called to update the SVG elements and the canvas.

http://korhal.andrewmao.net:9294/#/sources/APH10154043
controls: mousewheel, drag, drag on bottom context area, touch events

This is just basically a fancier example of Mike's response to my SO post, in that a redraw() function is called when a zoom behavior triggers any event.

http://bl.ocks.org/3681006

I basically want to figure out a way to animate the abilities from some of the controls programmatically: for example, zooming in to a particular area. I'm having trouble figuring out how to animate some zooms using the d3 API. It seems that all the transition() stuff requires me to select some elements that have some data. Why can't I just make a transition like so:

zoom_behavior.transition().duration(foo).scale(new_scale).translate([new_x, new_y])
and it would go from the current scale/translation to the new one, update my scales, and call the redraw() function (which is pretty fast) along the way? What's the easiest way to do what I want above?

Thanks,
Andrew

Andrew Mao

unread,
Sep 24, 2012, 4:51:07 PM9/24/12
to d3...@googlegroups.com
Bump? Anyone?

Mike Bostock

unread,
Sep 24, 2012, 5:59:26 PM9/24/12
to d3...@googlegroups.com
If you want to create a transition independent of a selection, did you
try d3.transition()?

https://github.com/mbostock/d3/wiki/Transitions#wiki-d3_transition

Mike

Andrew Mao

unread,
Sep 25, 2012, 3:17:45 PM9/25/12
to d3...@googlegroups.com
Thanks. For other people's reference, here's what I did. I have a function that redraws the zoom for a specified domain, so when zooming from one domain to another:

    gz = @graph_zoom
    d3.transition()
      .duration(1000)
      .tween "zoom", ->
          interp = d3.interpolate(current_dom, target_dom)
          (t) -> gz interp(t)
Message has been deleted

Andrew Mao

unread,
Sep 25, 2012, 3:21:00 PM9/25/12
to d3...@googlegroups.com
One more quick question: what happens when one of these transitions is called when another one is already currently animating?

Kai Chang

unread,
Sep 25, 2012, 5:38:38 PM9/25/12
to d3...@googlegroups.com
From the API docs:

Only one transition may be active on a given element at a given time.
However, multiple transitions may be scheduled on the same element;
provided they are staggered in time, each transition will run in
sequence. If a newer transition runs on a given element, it implicitly
cancels any older transitions, including any that were scheduled but
not yet run. This allows new transitions, such as those in response to
a new user event, to supersede older transitions even if those older
transitions are staged or have staggered delays. Multi-stage
transitions (transitions that are created during the "end" event of an
earlier transition) are considered the same "age" as the original
transition; internally this is tracked by monotonically-increasing
unique IDs which are inherited when multi-stage transitions are
created.

Also check out the transition source:

https://github.com/mbostock/d3/blob/master/src/core/transition.js

Andrew Mao

unread,
Sep 26, 2012, 1:32:42 AM9/26/12
to d3...@googlegroups.com, kai.s...@gmail.com
I saw that, does it mean that it's also true for the document transition, which is independent of elements?

Mike Bostock

unread,
Sep 26, 2012, 12:24:13 PM9/26/12
to d3...@googlegroups.com, kai.s...@gmail.com
> I saw that, does it mean that it's also true for the document transition,
> which is independent of elements?

As the documentation says, it's equivalent to
d3.select(document).transition(). So, it's not technically independent
of elements—it's a transition on the document itself. Thus it is
exclusive.

If you are creating multiple transitions at the same time and you want
them to run concurrently, you can use transition.transition() to
create a child transition that shares the same id and reference time.

If you are creating multiple transitions at different times and you
want them to overlap, then you can assign the transition.id property
manually to some shared value (e.g., 42) so that they can run
concurrently.

Mike
Reply all
Reply to author
Forward
0 new messages