Any equivalent of .done() .then() so i can chain events following a chart rendering?

3,083 views
Skip to first unread message

Mark Bridgett

unread,
Sep 11, 2012, 5:01:12 AM9/11/12
to d3...@googlegroups.com
I'm trying to get my D3 chart to draw, and then use some animation libraries to do an 'enter content' type transition where the chart quickly fades in from the right, and will do this upon any re-draws that the user initiates.

The problem is that the content holder (that houses the chart) completes this action after the chart loads (since it has a slight delay) which means the effect is ruined. 

Is there any way of tapping into some kind of render completed event, async event, or some kind of promise object (with .done() etc) that i can use to chain my animations to begin after the chart has
finished drawing?

Ger Hobbelt

unread,
Sep 11, 2012, 10:19:44 AM9/11/12
to d3...@googlegroups.com
I'm not sure I understand exactly what you're saying, but the usual 'd3' way is quite simple.

First, the question is when is the moment that a graph is 'rendered'.
Unless you do some very fancy stuff, the data loading + graph generating code has a structure similar to this:

d3.json("data-url.json", function(json) {
  // data has been loaded and now we generate the SVG DOM content:
  var selection = d3.selectAll("<some base node>")
    .data(json);
  selection.exit().remove();
  selection.enter().append("svg nodes").blahblah();
  selection.update_existing_svg_nodes_blahblah();
  // <pling!>
});

where d3.json is one of many ways to load data from a server and the selection.xyz... code in the callback handler is updating/generating the DOM to visualize the data.
To answer the question "when is the render completed?": when the JavaScript execution reaches the line "<pling!>" the DOM construction will be complete and the JavaScript run will terminate immediately after, so this is the point where the content gets rendered (when JS execution terminates, the browser will render the content, as usual).

The above applies to plain vanilla d3 coding; all the (basic) examples use this behavioral pattern.


Which leads us to the question about animating and 'chaining' animation.
You don't need a 'done' event for data loaded because the callback function you specify for d3.json, d3.csv, etc. _is_ the 'done' handler, at least for the 'data load complete'. Given the above structure, basic visualization will then construct the corresponding DOM at once and you're ready to 'transition' your d3.selection in order to animate it.

So what to do when you want to 'animate' the data visualization update on data load/update from the server?
That's where you go and use d3.transition to tell d3 to 'transition' to the specified target (https://github.com/mbostock/d3/wiki/Transitions -- note the first paragraph so you must enter().append("<svg node>").transition().attr_blabla() when you add DOM nodes and wish to animate these; it may be handy to append() them and immediately set their opacity or other property to zero, so the transition can 'fade them in'.

Think of transitions as 'animating settings from value a to b': that way it's immediately clear that you must create all DOM nodes you want to end up with at the end of a transition beforehand, so transitions can animate the opacity, position, or other attribute(s) to make them visible (or have them disappear; a 'fade-out' statement like .exit().transition().attr("opacity", 1e-6).remove() is used quite often, where the opacity is dialed down to 1e-6 instead of plain zero(0) to circumvent a tween bug/issue in some browsers. This also indicates that any nodes that are to be gone once the animation is complete, are simply remove()d once the transition completes.


Re transition chaining: see the aforementioned transition wiki documentation; in particular https://github.com/mbostock/d3/wiki/Transitions#wiki-each


BTW: If you seek more case specific responses from mailing list members, offering a case sample as a gist (and http://bl.ocks.org/ ) is strongly recommended.



Met vriendelijke groeten / Best regards,

Ger Hobbelt

--------------------------------------------------
web:    http://www.hobbelt.com/
        http://www.hebbut.net/
mail:   g...@hobbelt.com
mobile: +31-6-11 120 978
--------------------------------------------------

wimdows

unread,
Sep 13, 2012, 3:05:30 AM9/13/12
to d3...@googlegroups.com
Could .each(end) somehow be of use, maybe?

Regards,

wim


Reply all
Reply to author
Forward
0 new messages