In my last post I talked about animating SVG objects and how to combine that with React. As I talked about the catalyst for it was looking into how we could do charts.
Well of course after my initial experiments I wanted to actually look at how to do a chart.
Creating a basic chart
For this I started with the great walk through on SVG Charts at CSS Tricks, and I'm going to use the Line Chart example for this (but with randomly generated data).
Now we know what the basic React component would look like:
But that's not what we've come here to look at, rendering elements to the DOM is pretty basic, let's start thinking about animation.
Animating a line chart
The kind of animation I want to go with the for this is having the lines grow from a
0 x-axis to their final resting point on the y-axis.
Also, rather than just having an array for our input data, I'm going to try and represent something a bit more realistic by having an object. My data will look like this:
Like my last post I'm going to use a Higher Order Component for wrapping up the logic around handling the animation. Let's start with the
Now, we're expecting 3
props on the component:
- An array of data
- A function for getting the
xvalue from a data item
- A function for getting the
yvalue from a data item
We then create a new array that is flattening the data, so it'd look like:
So now we need to prepare for our animation, to achieve this we need to flatten the line we first draw and then we'll walk back up to it. To do this we need to find the largest
y value, this I'm putting into a variable called
Finally I need to create that flattened data set, doing is done by taking the array of points and turn all the
y points to the
max value (because it's the bottom of the graph we start at, which is the approximately height of the SVG). Now the data that we're rendering to the UI looks like this:
Great, we've got a hidden line graph that doesn't actually represent our data… not really useful.
Time to start building the animation. Like the last post we use
componentDidMount to start the animation and the
componentWillUnmount to stop it if needed. Here's the
Let's break it down, or more accurately, break down the
animator function, which is really what does the animation for us.
First step, the reason we have the
max on the component is so that we know when to stop trying to animate a point. That's what this logic is for:
Second step, start taking our temporary data a bit closer to the real data:
We're going to map over the data and:
- If the current index is even, an x-axis value, just return it, we're not moving that
- If the current index is odd
- Is it less than the target value, add 1 to it
- Otherwise just return the current value
Third step is to put that new array into state (and cause a re-render) as well as increase the loop count, then kick off
And that's all, we have a lovely animated line cart.
Again we've seen that a small bit of code and React components can make a very easy to read animated SVG without any external dependencies.
I've created another example that you can see here in action, and the data is randomly generated so reloading the page will get you a new chart each time 😄.