Exploring Recharts: Pulsating circle using ReferenceDot

An animated circle, or another animated shape, is generally used in charts to attract user attention, to entice user to click or hover on something. Some shapes and animations are much easier to achieve in css, and other complex animations and shapes can be easier to achieve in svg. But when working with a charting library, it is much more important to understand which of these css or svg animations can be integrated well with the library api, or whether the library provides another in-built way to achieve the required functionality.

Let’s try to create a pulsating circle with Recharts using css, svg and Recharts provided components to figure out which of these provides us the most flexibility and convenience of usage.

As we already know, we cannot render HTML elements directly inside the top level Recharts container. (Note, you can bypass this restriction using foreignObject) . But, we can render svg elements directly inside the top level container and we can use css keyframes to create a pulse animation and apply it on an svg circle.

We can also use the animate element to animate specific properties for a svg element. This gives us more control to animate element specific properties and create complex animations, which might be difficult to achieve in just CSS. Like, in the previous example, we created a pulse animation in css which does not specifically target the radius of the circle, instead we needed to figure out the correct scale and the correct transform-origin to make our animation work. This can easily and more semantically be achieved using animate inside svg circle

Both the above approaches with css or svg have some problems. Although we are allowed to use svg elements directly in Recharts top level container, Recharts would not pass any context to these svg elements, which means that we cannot assign an x-value directly from the data and expect it to work, we have to explicitly calculate the x coordinate value using the x value of the data and pass it as cx to the circle. It makes a lot more sense to use Recharts provided components to achieve this. That said, how do we animate Recharts provided components? At the time of writing, it seems that there are some default animations in Recharts and they can be controlled using props, but these animations and props are only allowed on some components like Line, Bar etc. And there is no suggested way in the documentation to use animations in Recharts. For our specific use case though, we can use a ReferenceDot component, which renders an svg circle by default, and try to animate it.

Since it renders a circle, we might expect that it would be able to render a animate child if we pass it. Sadly, that’s not the case here. But, fortunately Recharts provides us a way to customize the rendering of ReferenceDot using the shape prop. We can use the shape prop to render an svg circle and animate it. This is much better than rendering an svg circle directly, because the function passed to shape prop gets the required context from Recharts, which can be used to render the svg circle with the correct cartesian coordinates without us having to explicitly calculate those.

As a side note, since these are React components, it might be possible to animate these React components using React animation libraries and by directly targeting the rendered element through css and using css animations (in this case, we wouldn’t need to calculate the cartesian coordinates explicitly, as the rendering would be done by Recharts and we can apply animation separately using css). In this case, the rendered element would have the class name “recharts-layer recharts-reference-dot”, and you can target it using nested css rules to apply animation.

References:

A list of all other posts in this series:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store