Skip to content

D3.js Transitions — Animated Property Changes

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about D3.js Transitions. We cover key concepts, practical examples, and best practices to help you master this topic.

D3.js transitions animate DOM element properties smoothly over time, interpolating between start and end values with configurable duration and easing functions.

What You'll Learn

By the end of this guide, you will create transitions on attributes and styles, control timing with duration and delay, use easing functions for natural motion, chain transitions sequentially, and interrupt or cancel running transitions.

Why Transitions Matter

Sudden data changes are jarring. In Durga Antivirus Pro, threat levels transition smoothly from green to yellow to red as severity increases, giving operators intuitive visual feedback.

flowchart LR
    A[Start State] --> B[Transition]
    B --> C[Interpolation]
    C --> D[Easing]
    D --> E[End State]
    E --> F[Next Transition]

Basic Transition

d3.select('circle')
    .transition()
    .duration(1000)
    .attr('r', 50)
    .style('fill', 'steelblue');

Expected output: A circle that smoothly expands its radius to 50 and changes color to steelblue over 1 second.

Duration and Delay

d3.selectAll('rect')
    .transition()
    .delay(function(d, i) { return i * 100; })
    .duration(500)
    .attr('height', function(d) { return d; });

Expected output: Each rectangle animates to its target height sequentially, starting 100ms after the previous one.

Easing Functions

d3.select('.box')
    .transition()
    .duration(1000)
    .ease(d3.easeBounceOut)
    .attr('transform', 'translate(300, 0)');

// Common easing types:
d3.easeLinear       // Constant speed
d3.easeQuadInOut    // Slow start and end
d3.easeCircleOut    // Natural deceleration
d3.easeElasticOut   // Overshoot with bounce
d3.easeBounceOut    // Bounce at end

Chaining Transitions

d3.select('.box')
    .transition()
    .duration(500)
    .attr('transform', 'translate(100, 0)')
    .transition()
    .duration(500)
    .attr('transform', 'translate(100, 100)')
    .transition()
    .duration(500)
    .attr('transform', 'translate(0, 0)');

Expected output: The box moves right, then down, then back to origin in a square path.

Transition Events

d3.select('.box')
    .transition()
    .duration(1000)
    .attr('opacity', 0)
    .on('start', function() { console.log('Fade started'); })
    .on('end', function() { console.log('Fade complete'); d3.select(this).remove(); })
    .on('interrupt', function() { console.log('Transition interrupted'); });

Common Mistakes

1. Applying Transitions to Initial State

Transitions animate from current state to target state. For initial entry, set the starting state before the transition.

2. Forgetting That Transitions Are Non-blocking

Transitions return immediately. Code after transition() runs before the animation completes.

3. Interrupting Transitions Without Handling

A new transition on an element interrupts the previous one. Use .interrupt() before starting a new transition.

4. Using Incompatible Property Types

Not all properties can be interpolated. D3 handles numbers, colors, and transforms. Custom data requires custom tween functions.

5. Transitions on Removed Elements

Calling transition on a selection that has been removed causes errors.

Practice Questions

Q1: What is the default duration of a D3 transition? A: 250 milliseconds.

Q2: How do you delay each element's transition by an increasing amount? A: Use a delay function: .delay(function(d, i) { return i * 100; }).

Q3: What does d3.easeBounceOut do? A: It creates a bouncing effect at the end of the transition, like a ball settling after dropping.

Q4: How do you run transitions sequentially on the same element? A: Chain .transition() calls. Each starts after the previous one completes.

Q5: How do you remove an element after its transition ends? A: Use .on('end', function() { d3.select(this).remove(); }).

Challenge: Build a race animation with 5 bars of different lengths. When a button is clicked, all bars grow to random lengths with different durations. The first bar to reach full length wins and turns gold.

FAQ

Can I transition the 'd' attribute of a path?

Yes, but you need a custom tween or a library like d3-interpolate-path for complex path morphing.

How do I cancel a running transition?

Call .interrupt() on the selection. This stops the current transition immediately.

What happens if I apply two transitions to the same element?

The second transition interrupts the first by default. Use .transition().delay() for sequential transitions.

Can I transition CSS transforms?

Yes. Use .style('transform', 'translateX(200px)'). D3 interpolates numeric transform values.

How do I know when a transition completes?

Use .on('end', callback) on the transition selection.

Try It Yourself

Build a page with an animated SVG scene where shapes move, fade, and transform with different easing functions.

<!DOCTYPE html>
<html>
<head>
    <title>D3 Transitions Playground</title>
    <style>
        body { font-family: sans-serif; padding: 20px; background: #1a1a2e; display: flex; gap: 20px; }
        .controls { width: 200px; }
        .controls button { display: block; width: 100%; padding: 10px; margin: 5px 0; cursor: pointer; background: #4ecdc4; border: none; color: white; font-weight: bold; border-radius: 6px; }
        .controls button:nth-child(2) { background: #ff6b35; }
        .controls button:nth-child(3) { background: #45b7d1; }
    </style>
</head>
<body>
<div class="controls">
    <button onclick="animateAll()">Animate All</button>
    <button onclick="resetAll()">Reset</button>
    <button onclick="chainDemo()">Chain Sequence</button>
</div>
<svg width="500" height="400" id="canvas">
    <circle id="c1" cx="80" cy="200" r="30" fill="#ff6b35"></circle>
    <circle id="c2" cx="200" cy="200" r="30" fill="#4ecdc4"></circle>
    <circle id="c3" cx="320" cy="200" r="30" fill="#45b7d1"></circle>
    <rect id="box" x="400" y="170" width="60" height="60" fill="#f9ca24" rx="8"></rect>
</svg>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
function animateAll() {
    d3.select('#c1').transition().duration(800).ease(d3.easeBounceOut)
        .attr('cy', 50).attr('r', 45);
    d3.select('#c2').transition().duration(1000).ease(d3.easeElasticOut)
        .attr('cy', 50).attr('r', 45);
    d3.select('#c3').transition().duration(1200).ease(d3.easeCircleOut)
        .attr('cy', 50).attr('r', 45);
    d3.select('#box').transition().duration(800).ease(d3.easeQuadInOut)
        .attr('x', 100).attr('width', 100).attr('fill', '#a29bfe');
}
function resetAll() {
    d3.select('#c1').interrupt().attr('cy', 200).attr('r', 30);
    d3.select('#c2').interrupt().attr('cy', 200).attr('r', 30);
    d3.select('#c3').interrupt().attr('cy', 200).attr('r', 30);
    d3.select('#box').interrupt().attr('x', 400).attr('width', 60).attr('fill', '#f9ca24');
}
function chainDemo() {
    d3.select('#box')
        .transition().duration(400).attr('x', 300).attr('fill', '#ff6b35')
        .transition().duration(400).attr('y', 100).attr('fill', '#4ecdc4')
        .transition().duration(400).attr('x', 400).attr('fill', '#45b7d1')
        .transition().duration(400).attr('y', 170).attr('fill', '#f9ca24');
}
</script>
</body>
</html>

What's Next

Create axes for your D3.js charts.

Axis — D3.js axis component. Force Layout — Network visualization with force layout.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro