Animated Graph in React Native
Recently I was looking for a React Native graph library for my Savee.io app. During the research, I realized it’s not easy to deal with graphs in React Native. And if you want to animate them? It looks almost impossible. The following gif is what I have done and will talk about in this tutorial!
Without ART library
When I was doing my research about charts in React Native, I found out that almost everyone uses the ART library. Which is really cool and powerful drawing library. Look at this pie chart that has been done by ART library for the Savee.io app.
But when you want to animate it? Well, you can. It is possible. But the animation is done by JS thread. I am always trying to find a way how to move everything to a native part, so our JS thread is not blocked by animation and can work on something else.
The column chart I am going to talk about (and you can see in the gif below) has been done by pure React Native. No ART library!
Let’s make it a bit complicated
I realized that I also need a negative value in the graph. Users of Savee.io usually create a group for a trip and track their spendings. Obviously, there are only negative values — only spendings. The following gif shows how the animation looks like for both negative and positive values.
Layout
I decided to make every single column separately as a component. So I could add a “delay” effect. You can see that the animation starts randomly for every single column when the graph is changing a position of baseline. Let’s work with the 200 height. Value’s height could be 25 and label’s height 25 as well. That makes 150 for column.
If the graph’s height is 150 then the column’s height is 300. Every column has a positive part (A) and a negative part (B). Opposite side of these parts is always hidden. The A is hidden for the negative part and the B is hidden for the positive part. It means that if we move the positive part (A) underneath of baseline to the B space, the positive column will be completely hidden. That’s what we want when the value is negative.
You can see the negative value for the last column on the picture. The value is -5. Positive column is completely moved underneath of baseline (it’s hidden) and negative column is moved to proper Y position to represent -5 value. A maximum value for this graph is 10 (first column). It means that the -5 will be in the middle of a negative part (75 / 2).
We need to do a bit of math here because we need to interpolate actual value to Y position. But I am not going to talk about this here. I believe that you can figure everything out pretty easily.
Animated Column
I used my open source library called react-native-motion and component TranslateY. Which makes animations really easy to implement. Look at the code. Easy to understand. We use TranslateY component in the same way as we would use View component. The only thing we need to do is compute Y positions for positive column, negative column, baseline, and a value label.
Check out the result in a real application. Savee.io already implemented the column chart. As I said before, everything is done by UI thread (it’s pretty fast). There is an onPress event so you can change the months. When you select the category it will change the values of a graph and recomputes Y positions. Then the react-native-motion takes care of animation.
Animated Number
The number animation is a bit problem. Because we can’t move it to UI thread. It has to be done by JS thread. I’ve seen that developers usually have the effect done by setInterval. Of course, you can use it, but I wanted to do it safer.
So I use React Native’s Animated API even for the number animation. We can add a listener to animated value and when the value is changed we just re-render the number. It’s easy and you can take advantage of the Animated API. By using an Easing for example. And what’s the best? I put the component to the react-native-motion library which is open-sourced for you guys 😉
You just have to write a couple of lines like this. Once the value is changed in your code it will take care of the rest.
Did you like it? Clap, Comment, Share and Follow me! 👏
Actually you don’t have to do anything of that. But it will help me a lot. It’s a big motivation to the next work. Next articles like this for you guys.
About me 👦
I am an author of Savee.io (which I also use as a playground for my animations 🤷). I open-sourced react-native-material-ui and react-native-motion libraries. Writing about them in this blog.
If you need a help with your React Native app (animations, performance, etc.), let me know, please ;) I will be happy to discuss it.