I wanted a nice way of animating in a D3 donut chart with a "corkscrew" effect, where segments animate in at constant speed regardless of segment size in a clockwise sweep, simultaneously animating out from the centre. Here's what I came up with:
I found some nice examples of pie/donut chart entry animations, where segments animate in one by one, but none of them were quite what I was looking for.
In this example, each segment is animated in turn, meaning that it takes the same amount of time to animate in regardless of its size. This produces a slightly odd effect when a small segment is immediately followed by a large segment.
I also wanted the "corkscrew" effect shown above, where the chart expands from the center point at the same time as it's drawn, and I couldn't find any examples of that.
The solution to both problems is that each segment has to be animated for the entire duration of the entry animation so that they can be animated out from the center point. We can then add some basic logic to work out when to start and finish drawing each segment, which means segments appear to be drawn at a constant speed regardless of their size.
The first step is to create the path elements in the usual way. A group is added to the SVG to move the chart to the center of the available space, and bound to data created from
With the initial setup done, we need three interpolations:
- Between the start and end angles of the pie chart:
let angleInterpolation = d3.interpolate(generator.startAngle()(), generator.endAngle()());
This will allow us to calculate when to start drawing each segment, and how much of the segment to draw.
- From the center to the outer radius of our chart:
let outerRadiusInterpolation = d3.interpolate(0, sizes.outerRadius);
This is used to give the effect of animating out from the center point of the chart.
- From the center to the inner radius of our chart:
let innerRadiusInterpolation = d3.interpolate(0, sizes.innerRadius);
If you're building a pie chart this isn't needed - a pie chart is effectively a donut chart with an
innerRadius of 0, and the resulting effect would be the pie chart segments "growing" out from the center as they are drawn.
With that done, we start two transitions. The first is responsible for drawing the arcs.
We use the angle interpolation to determine whether we are at the point where we should have started drawing the current arc or not. If the current angle is prior to the start of the arc, we leave it undrawn. Otherwise we use the current angle to determine how much of the arc to draw using the arc generator.
The second transition is responsible for modifying the arc generator by updating its
outerRadius over the duration of the entry animation. As it's effectively a transition for the entire chart, we run it against the root element.
The effect of this is that as the arcs are redrawn over the course of the first transition they appear to move outward from the center point of the chart.
To see the full code, take a look at the CodePen here.