You can make some awesome charts in D3. Animate your charts, and they’re made even awesomerer. To animate lines, such as those found in line charts, try out the following methods.
In order to animate in D3, you call the
transition function on a
d3.selection. The transition essentially creates a tween from the starting point of the animation to the specified ending point. So, to specify an animation:
- Set the starting state
- Specify that you are transitioning
- Set the ending state
Then D3 will handle the animation on the diff between the starting and ending state.
SVG Line Animation
An SVG line element has 4 required attributes,
y2. These required attributes specify where the line begins and ends in a 2D space. When choosing your coordinates, remember that the SVG coordinate plane starts at (0,0) in the top-left of the SVG element.
For our line animation, we want the line to look like it’s being drawing from the beginning to the ending point. We will follow the general formula for defining a D3 transition as stated above. Assuming we have an
svg element from the DOM selected, the remaining code might look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13
In the code above, the line’s starting state shows the line beginning and end at the same point, (25, 15). This is so that the line appears to be
15px long when first seen in the UI. Then, over time it will grow. Note that the
attrs set after the
transition call specify the end of the line as being
400px to the right. Thus, over the duration of the transition (set to 1500ms in order to observe it), the line will appear to grow to its final length of 400px in the horizontal direction.
D3 Line Function
D3 line functions are specified differently than SVG lines. An SVG line is guaranteed to be a straight edge from the beginning to the ending point. On the other hand, a D3 line function can describe a line through many different points, and can thus be anything but straight. Think of a zig-zaggy line chart, and this is what a D3 line function is meant to accomplish. Thus, a D3 line function is often used to generate the data needed for an SVG
path, not a
line element. There will still be an SVG
stroke on a path, but we will use a different technique to animate it.
Strokes with Dashes
There are two attributes to of a
stroke in SVG that we will use:
stroke-dasharray- a set of 2 numbers. The first number is the length of the dash. The second number is the length between the dashes.
stroke-dashoffset- a dash pattern is repeated, according to the
stroke-dasharrayattribute. But this attribute specifies where to start in that repeating pattern. In other words, how many pixels offset into that pattern should the first iteration of the pattern begin. The default is 0px.
To see these numbers change and how they affect a line, check out the following SVG lines:
In each of the above cases, the
stroke-dasharray is set so the dash line length and the dash space length are equal to the total length of the total line. Note that the
stroke-dashoffset is the only attribute that changes between the 3 lines.
- In the first, the
stroke-dashoffsetis set to the length of the total line. This means that the
stroke-dasharraypattern begins at the point where the space between the dashes begins. Thus, the line appears invisible – it’s just the line-length space between the dashes.
- In the second, the
stroke-dashoffsetis set to the mid-length of the total line. Thus, the 2nd half of the first dash is visible, making the line seem half as long as its total intended length.
- Finally, the
stroke-dashoffsetis set to 0, meaning that the total line-length dash is now fully visible.
One could imagine that were the
stroke-dashoffset to tween from the full line length to 0, the line would appear to grow from the left to the right. At first, the space between the dash would be fully visible, slowly, backing off the
stroke-dashoffset until the pattern, which begins with a dash be fully visible. Let’s try it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
The above is the simplest possible example of how to make this happen. In real life, you’re going to have:
- No foreknowledge of the data domain or maybe even the visual space range and will need a d3 scale (eg,
- A more complicated set of data which is going to lead to a more complicated line and the actual need for the line function used above
- A more complicated line where the length is not immediately obvious and where
path.node().getTotalLength()will be useful as a way to use the browser’s distance-along-a-path algorithm
In the example above, note that the total length of the line is
385px. We make the line dashed. We set the dash length and the space between the dash length to both be
stroke-dasharray. We define the animation by making the starting state have a
385px, showing nothing but the invisible space between the dash to start. Then we tween to a
0, causing the offset window to shrink until we see the dash, which is the length of the total line, grow into view.
Frankly, this dash-based solution feels like a hack. It doesn’t seem like someone sat back and thought much about how to animate a non-linear path. But this solution works well all the times I’ve used it.
What are some other solutions that you’ve found for animating lines or creating other interesting line animations?