What is the standard way to get the active (running) D3 v3 Transition for a given element?

d3.js, javascript, transition

Solution

Another way to do it: Create your own property on each node that stores an array of the actual `d3.transition` objects. When creating a new transition, grab the last transition from the array and create a sub-transition.

The complication is that your new transition may not be based on the same selection as the active transition. Therefore, I create the new "safe" transitions on a per-element basis within an `.each()` call.

function saveTransition(t) {
    //save the transition immediately (don't wait for "start")
    //clear it on "end"
    t.each(function() {
        var tArr = this.__tObj__
        if (!tArr) tArr = this.__tObj__ = [];

        tArr.push(t);
        //console.log("saving ", t, " for ",this);
      } )
     .each("end", function() {
        var test =  this.__tObj__.shift();
        // console.log("clearing ", t, " from " ,this, 
         //            (test == t ? "correctly" : "ERROR") );
       } );
}
function newSafeTransition(node) { 
    var tArr = node.__tObj__; 
    if ( tArr && tArr.length ) {

        var t = tArr[ tArr.length - 1 ];
        return t.filter( function(){ return this === node; } )
                .transition().call(saveTransition);
    }
    else {
        return  d3.select(node).transition().call(saveTransition);
    }
}

d3.selectAll("div.foo")
    .transition().duration(3000)
    .call( saveTransition )
    .style("left", "100px");

d3.selectAll("div.bar")
    .transition().duration(3000)
    .call( saveTransition )
    .style("top", "100px");

setTimeout( function() { 
    console.log("blue");

    d3.selectAll("div.blue")
      .each( function() {
            newSafeTransition(this).style("color", "blue");
        });
}, 1000);

setTimeout( function() { 
    console.log("reposition");

    d3.selectAll("div.foo")
      .each( function() {
            newSafeTransition(this).style("left", "0px");
        });
}, 2000);

http://jsfiddle.net/7SQBe/3/

It could probably be cleaned up, you could even over-write the `selection.transition()` and `transition.transition()` methods to do this automatically. However, you'd probably want to keep a way to indicate whether you want to queue the new transition after any scheduled transitions or whether you want to interrupt.

Problem

The abstractions of D3 still make my mind bend, so hopefully I'm presenting this correctly. In D3 version 3, given an element (say a circle), and given only one transition possibly running per element what is the best way to determine what the current running transition on that element is, if there is one at all? I'm aware that I can manually inspect `__transition__` on the element (though help there is welcome too), but I'm really hoping for something a little higher-level. My larger goal here is to create a subtransition if-and-only-if there's a transition to sub. Otherwise, I'll be creating a new transition.

Original source

Related problems