d3-transition
A transition is a selection-like interface for animating changes to the DOM. Instead of applying changes instantaneously, transitions smoothly interpolate the DOM from its current state to the desired target state over a given duration. To start a transition, select elements, call selection.transition, and then apply the desired changes. For example:
d3.select("body")
.transition()
.style("background-color", "red");
Transitions support most selection methods (such as transition.attr and transition.style), but not all methods are supported; for example, you must append elements or bind data before a transition starts. A transition.remove operator is provided for convenient removal of elements when the transition ends.
To animate changes, transitions leverage a variety of built-in interpolators. Colors, numbers, and transforms are automatically detected. Strings with embedded numbers are also detected, as is common with many styles (such as padding or font sizes) and paths. To specify a custom interpolator, use transition.attrTween, transition.styleTween or transition.tween.
Installing
If you use NPM, npm install d3-transition
. Otherwise, download the latest release. You can also load directly from d3js.org, either as a standalone library or as part of D3 4.0 alpha. AMD, CommonJS, and vanilla environments are supported. In vanilla, a d3_transition
global is exported:
<script src="https://d3js.org/d3-color.v0.4.min.js"></script>
<script src="https://d3js.org/d3-dispatch.v0.4.min.js"></script>
<script src="https://d3js.org/d3-ease.v0.7.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v0.7.min.js"></script>
<script src="https://d3js.org/d3-selection.v0.7.min.js"></script>
<script src="https://d3js.org/d3-timer.v0.4.min.js"></script>
<script src="https://d3js.org/d3-transition.v0.2.min.js"></script>
<script>
var transition = d3_transition.transition();
</script>
Try d3-transition in your browser.
API Reference
Selecting Elements
Transitions are derived from selections via selection.transition. You can also create a transition on the document root element using d3.transition.
# selection.transition([name])
Returns a new transition on the given selection with the specified name. If a name is not specified, the default empty name (“”) is used. The new transition is only exclusive with other transitions of the same name.
If the name is a transition instance, the new transition has the same id, name and timing as the specified transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element. This can be used to synchronize a transition across multiple selections, or to re-select a transition for specific elements and modify its configuration. For example:
var t = d3.transition()
.duration(750)
.ease(d3.easeLinear);
d3.selectAll(".apple").transition(t)
.style("fill", "red");
d3.selectAll(".orange").transition(t)
.style("fill", "orange");
# selection.interrupt([name])
Interrupts the active transition of the specified name on the selected elements, and cancels any pending transitions with the specified name, if any. If a name is not specified, the empty name (“”) is used.
# d3.transition([name])
Returns a new transition on the root element, document.documentElement
, with the specified name. If a name is not specified, the default empty name (“”) is used. The new transition is only exclusive with other transitions of the same name. The name may also be a transition instance; see selection.transition. This method is equivalent to:
d3.selection().transition(name)
This function can also be used to test for transitions (instanceof d3.transition
) or to extend the transition prototype.
# transition.select(selector)
For each selected element, selects the first descendant element that matches the specified selector string, if any, and returns a transition on the resulting selection. The selector may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum d
and index i
, with the this
context as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
This method is equivalent to deriving the selection for this transition via transition.selection, creating a subselection via selection.select, and then creating a new transition via selection.transition:
transition
.selection()
.select(selector)
.transition(transition)
# transition.selectAll(selector)
For each selected element, selects all descendant elements that match the specified selector string, if any, and returns a transition on the resulting selection. The selector may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum d
and index i
, with the this
context as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
This method is equivalent to deriving the selection for this transition via transition.selection, creating a subselection via selection.selectAll, and then creating a new transition via selection.transition:
transition
.selection()
.selectAll(selector)
.transition(transition)
# transition.filter(filter)
For each selected element, selects only the elements that match the specified filter, and returns a transition on the resulting selection. The filter may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum d
and index i
, with the this
context as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
This method is equivalent to deriving the selection for this transition via transition.selection, creating a subselection via selection.filter, and then creating a new transition via selection.transition:
transition
.selection()
.filter(filter)
.transition(transition)
# transition.merge(selection)
Returns a new transition merging this transition with the specified selection (or transition). The returned transition has the same number of groups, the same parents, the same name and the same id as this transition. Any missing (null) elements in this transition are filled with the corresponding element, if present (not null), from the specified selection.
This method is equivalent to deriving the selection for this transition via transition.selection, merging with the specified selection via selection.merge, and then creating a new transition via selection.transition:
transition
.selection()
.merge(selection)
.transition(transition)
# transition.transition()
Returns a new transition on the same selected elements as this transition, scheduled to start when this transition ends. The new transition inherits a reference time equal to this transition’s time plus its delay and duration. The new transition also inherits this transition’s name, duration, and easing. This method can be used to schedule a sequence of chained transitions. For example:
d3.selectAll(".apple")
.transition()
.style("fill", "green")
.transition()
.style("fill", "red")
.transition()
.delay(1000)
.style("fill", "brown")
.remove();
The delay for each transition is relative to its previous transition. Thus, in the above example, apples will stay red for one second before the last transition to brown starts.
# transition.selection()
Returns the selection corresponding to this transition.
# d3.active(node[, name])
Returns the active transition on the specified node with the specified name, if any. If no name is specified, the default empty name is used. Returns null if there is no such active transition on the specified node. This method is useful for creating chained transitions. For example, to initiate disco mode:
d3.selectAll("circle").transition()
.delay(function(d, i) { return i * 50; })
.on("start", function repeat() {
d3.active(this)
.style("fill", "red")
.transition()
.style("fill", "green")
.transition()
.style("fill", "blue")
.transition()
.on("start", repeat);
});
Modifying Elements
…
# transition.attr(name, value)
… Note that unlike selection.attr, value is required.
# transition.attrTween(name[, value])
…
# transition.style(name, value[, priority])
… Note that unlike selection.style, value is required.
# transition.styleTween(name[, value[, priority]]))
…
# transition.text(value)
… Note that unlike selection.text, value is required.
# transition.remove()
…
# transition.tween(name[, value])
…
Timing
Transitions may have per-element delays and durations computed by functions of data or index; this lets you stagger a transition across a set elements. For example, sorting elements and staggering the reordering improves perception. See Animated Transitions in Statistical Data Graphics for recommendations.
Transitions start automatically after the given delay. Note, however, that even a zero-delay transition starts asynchronously after one tick (~17ms); this delay gives you time to configure the transition before it starts. Transitions have a default duration of 250ms.
Transitions are partially exclusive: only one transition of a given name may be active on a given element at a given time. Multiple transitions with different names may be simultaneously active on the element, and multiple transitions with the same name may be scheduled on the element, provided they do not overlap in time. See transition.transition, for example. When a transition starts on a given element, it automatically interrupts any active transition and cancels any pending transitions that were scheduled before the starting transition. This allows new transitions to supersede old transitions (such as in response to a user event), even if the old transitions were delayed. To manually interrupt transitions, use selection.interrupt. To run transitions concurrently on a given element, give each transition a unique name.
If another transition is active on a given element, a new zero-delay transition will not immediately (synchronously) interrupt the active transition: the old transition does not get pre-empted until the new transition starts, so the old transition is given a final tick. (Within a tick, active transitions are invoked in the order they were scheduled.) Thus, the old transition may overwrite attribute or style values that were set synchronously when the new transition was created. Use selection.interrupt to interrupt any active transition and prevent it from receiving its final tick.
For more on transitions, see Working with Transitions.
# transition.delay([value])
…
# transition.duration([value])
…
# transition.ease([value])
…
Control Flow
…
# transition.on(typenames[, listener])
…
# transition.each(function)
Invokes the specified function for each selected element, passing in the current datum d
and index i
, with the this
context of the current DOM element. This method can be used to invoke arbitrary code for each selected element, and is useful for creating a context to access parent and child data simultaneously. Equivalent to selection.each.
# transition.call(function[, arguments…])
Invokes the specified function exactly once, passing in this transition along with any optional arguments. Returns this transition. This is equivalent to invoking the function by hand but facilitates method chaining. For example, to set several attributes in a reusable function:
function color(transition, fill, stroke) {
transition
.style("fill", fill)
.style("stroke", stroke);
}
Now say:
d3.selectAll("div").transition().call(color, "red", "blue");
This is equivalent to:
color(d3.selectAll("div").transition(), "red", "blue");
Equivalent to selection.call.
# transition.empty()
Returns true if this transition contains no (non-null) elements. Equivalent to selection.empty.
# transition.nodes()
Returns an array of all (non-null) elements in this transition. Equivalent to selection.nodes.
# transition.node()
Returns the first (non-null) element in this transition. If the transition is empty, returns null. Equivalent to selection.node.
# transition.size()
Returns the total number of elements in this transition. Equivalent to selection.size.