As of 2.0.0, it's possible to have multiple transitions running concurrently
with the same id. Thus, it is no longer sufficient to check the transition id
to decide whether to delete the transition lock. We now use reference counting
to determine the number of transitions that are scheduled on a given element;
when that number drops to zero, we can delete the transition lock.
They weren't being invoked with the correct syntax (being passed the data and
index, with the current node as the context). This commit also removes the
d3_array wrapper, which does not appear to be necessary; I've forgotten why it
was there in the first place.
This means that you can now extend D3's selections and transitions with custom
functionality! Also, you can use now instanceof to see whether something is an
instanceof d3.selection or d3.transition.
Also fix a bug where it would be possible for an earlier to transition to become
the lock owner. We now guarantee that the lock owner can only increase while
transitions are scheduled on an element.
This caught a couple bugs in the previous commit. First, I wasn't sending the
correct index (i) to the "end" event listeners, because it was being masked by
a local variable. Second, the transition lock was being incorrectly deleted when
a transition is inherited on the same node and there is zero delay and
d3.timer.flush is called. There was potentially a related bug where the active
field was not being cleared on the transition lock. Yay tests!
This changes the core implementation of selections and transitions to use
prototype injection rather than direct extension. This offers better performance
by eliminating per-instance overhead from closures and assignment. On browsers
that don't support prototype injection, we fall back to direct extension.
This commit isn't just about performance, though; the code ends up being a lot
cleaner and more separable if we force methods to rely solely on `this`, rather
than capturing surrounding variables with closures.
Most importantly, transitions are now "transparent", like selections. Rather
than opaque objects, transitions are now arrays of nodes, similar to selections.
The nodes are wrapped in an object that stores the delay and duration, which
means you can now inspect the computed delay and duration. (This was the
original motivation for this commit, and will allow chart components to be
call'd on transitions as well as selections.)
Transitions now support the `each` operator with one argument, which has the
same behavior as on selections. The `each` operator now passes a third argument
containing the group index (`j`). Transitions now also support a `tween`
operator, which is a generic mechanism for doing things during a transition; use
this in place of a "tick" event.
This commit also fixes a few bugs. The enter selection now supports the empty
operator; we can add other operators in the future more easily, if we so choose.
Transition's attr operator now supports namespaced attributes. Selection's
property operator no longer parses property namespaces.