Skip to content

D3.js - Transitions API

D3.js transitions allow for smooth, animated changes to selected elements over time. The d3-transition module provides the core functionality. When you apply a transition, D3 interpolates attributes and styles from their current values to target values, creating an animation.

The d3-transition module is part of the main D3.js library. Ensure D3.js is included in your HTML:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D3.js Transitions API Example</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
.shape { width: 50px; height: 50px; background-color: steelblue; margin: 10px; }
</style>
</head>
<body>
<div class="shape"></div>
<script>
// Your D3.js transition code will go here
</script>
</body>
</html>

Key methods for initiating and managing transitions:

  • selection.transition([name]): Initiates a transition on the selected elements. The optional name argument allows for multiple named transitions on the same elements, preventing them from interfering. If no name is specified, it’s an unnamed transition.
  • selection.interrupt([name]): Immediately stops the active transition(s) of the specified name (or all unnamed transitions if no name is given) on the selected elements. This is useful for user interactions that should override an ongoing animation.
  • d3.interrupt(node[, name]): Interrupts the transition of the specified name on a single DOM node.
  • d3.transition([name]): Creates a new transition configuration with the specified name. This can be used to define shared transition parameters, though direct chaining on selection.transition() is more common for simpler cases.

Once a transition is initiated, you can use familiar D3 selection methods. These methods, when called on a transition, will apply to the elements as they are being transitioned or define the end state of the transition.

  • transition.select(selector): For each selected element, selects the first descendant element that matches the selector. The returned transition applies to these descendant elements.
  • Example: d3.selectAll("g").transition().select("rect").attr("fill", "red"); would transition the fill of rects within transitioning groups.
  • transition.selectAll(selector): Similar to select, but selects all matching descendant elements.
  • transition.filter(filter): Filters the transitioning selection, returning a new transition containing only elements for which the filter (function or selector string) is true.
  • transition.merge(otherTransition): Merges this transition with another otherTransition. Useful when dealing with enter/update selections where new elements also need to transition.
  • transition.transition(): Schedules a new transition to start after the current transition on the same elements ends. This is a powerful way to chain sequential animations. The new transition inherits properties like duration and easing from the parent transition unless overridden.

Example of chaining transitions:

d3.select(".shape")
.transition() // First transition
.duration(1000)
.style("background-color", "orange")
.transition() // Second transition, starts after the first one ends
.duration(1000)
.style("transform", "translateX(100px)")
.transition() // Third transition
.delay(500) // Starts 500ms after the second one ends
.duration(1000)
.style("background-color", "steelblue")
.style("transform", "translateX(0px)");

This animates a shape’s color, then its position, then its color and position back, in sequence.

  • d3.active(node[, name]): Returns the active transition of the specified name on the given node, if any. Useful for checking if an element is currently transitioning.

Control the timing and feel of your animations:

  • transition.delay([value]): Sets the transition delay in milliseconds. If value is a function, it’s evaluated for each selected element (passed datum, index, nodes) and should return the delay. If no value is specified, returns the current delay of the first non-null element.
  • Example: transition.delay((d, i) => i * 100); // Staggered start
  • transition.duration([value]): Sets the transition duration in milliseconds. Similar to delay, value can be a constant or a function. Default is 250ms.
  • transition.ease([easingFunction]): Sets the easing function, which controls the rate of change over time (e.g., slow start, fast end). D3 provides many built-in easing functions in d3-ease (e.g., d3.easeLinear, d3.easeCubicInOut, d3.easeBounce). If no function is given, returns the current easing function.

Transitions emit events and return promises, allowing for more complex orchestration:

  • transition.on(typenames, listener): Adds an event listener for start, end, or interrupt events. The listener function is called when the event occurs for an element. Its this context is the DOM element.
  • transition.end(): Returns a Promise that resolves when all transitions in the selection have ended. This is very useful for running code after an animation completes without complex event tracking. Example: myTransition.end().then(() => console.log("Transition finished!"));

This API provides a robust way to create sophisticated animations. In the next chapter, we will discuss the drag and drop concept in D3.js.