by Vikrant Negi

How to build React Native charts with dynamic tooltips

Area Chart with tappable tooltip

Creating charts, be it on the web or on mobile apps, has always been an interesting and challenging task especially in React Native. It’s difficult to find a suitable library that can meet your functional and design needs at the same time. You can try to make your own charts, but that often comes with the overhead of learning and implementing things from scratch.

If you are a beginner like I am, you probably want to use an existing charts library. And given how young the React Native community is, you have very few options available to you to implement and customize charts.

Problem Statement

Before starting our journey deep into the woods, I would like to introduce you to our problem statement.

In this tutorial, we are going to draw an area chart and add a circular marker at each of the data points which can further be tapped to show a tooltip containing x and y coordinate values.

To solve this problem, I did some research on some existing React Native libraries and narrowed it down two of them, react-native-charts-wrapper, and react-native-svg-charts.

React Native Charts Wrapper

Our first contender, react-native-charts-wrapper is a React Native wrapper of popular Native charting library MPAndroidChart and Charts.

This library is highly configurable, and since it uses the native chart libraries it provides silky smooth transitions and touch support. It also has tons of examples of use cases on its Github repo.

In the beginning, it was my preferred choice given its performance and customization. It has a very long and specific installation guide, following which I was able to install and run it on both iOS and Android devices.

Everything seems to be working smoothly on Android. However, when I tried to create an iOS build, it gave me an error. After countless hours of searching through GitHub issues and Google, I decided against it.

React Native SVG Charts

After giving up on react-native-charts-wrapper this was the next best solution available that I could find.

react-native-svg-charts uses react-native-svg under the hood to render charts. It also has tons of examples featuring many use cases.

Since it doesn’t use any native linking, installation and implementation was pretty simple and straightforward.

If you just want to see the source code of the example project, find the project repo here.

Now that’s done, let’s get this party rolling.

Getting Started

Create a React native project and install all the required dependencies.

~ react-native init ReactNativeTooltip

We’ll also need to install and link the react-native-svg library.

~ npm i react-native-svg
~ react-native link react-native-svg

If you face any problem linking the library automatically using the link command, follow the manual steps mentioned in the official documentation.

Now, finally install the react-native-svg-charts .

~ npm install react-native-svg-charts

Getting the Dummy data

Before we dive any further we’ll need to have some data that we can use for rendering our AreaChart. We’ll be using a third-party service called Mockaroo to generate some mock data for our area chart.

Ideally, we’ll be getting this data from an API that we’ll store it in the component state and then feed to our area component.

Here is how my dummy JSON data looks. See here for the full JSON data file.

export const DATA = [  {    id: 1,    date: ‘2019–01–26T22:37:01Z’,    score: 3,  },  {    id: 2,    date: ‘2019–01–06T06:03:09Z’,    score: 9,  },  {    id: 3,    date: ‘2019–01–28T14:10:00Z’,    score: 10,  },  {    id: 4,    date: ‘2019–01–03T02:07:38Z’,    score: 7,  },  ...]

Using React Native SVG charts

react-native-svg-charts has lots of components that we can use to create graphs. In this tutorial, we’ll use AreaChart component but you can use any one of the available charts components. Here is how an Areachart chart component looks:

<AreaChart  style={{ height: '70%' }}  data={data}  yAccessor={({ item }) => item.score}  xAccessor={({ item }) => moment(item.date)}  contentInset={contentInset}  svg={{ fill: '#003F5A' }}  numberOfTicks={10}  yMin={0}  yMax={10}>

Let’s go through the important props that we are using in the AreaChart.

  • data : This is a required field and must be an array.
  • yAccessor: A function that takes each entry of data (named "item") as well as the index and returns the y-value of that entry.
  • xAccessor: Same as yAccessor but returns the x-value of that entry.

You can read more about the other available props in the official documentation.

Adding Decorators

React native SVG charts was built to be as extensible as possible. All charts can be extended with “decorators”, a component that somehow styles or enhances your chart. Simply pass in a react-native-svg compliant component as a child to the graph and it will be called with all the necessary information to layout your decorator.

For this tutorial, we’ll need two decorators, one for the datapoint marker and another one for the tooltip.

Make sure you place Decorators inside the AreaChart component. Otherwise they won’t render.

Adding Marker Data Points

Let’s create a decorator to be used as a marker at each data point in the chart.

const ChartPoints = ({ x, y, color }) =>  data.map((item, index) => (   <Circle     key={index}     cx={x(moment(item.date))}     cy={y(item.score)}     r={6}     stroke={color}     fill=”white”     onPress={() =>       this.setState({         tooltipX: moment(item.date),         tooltipY: item.score,         tooltipIndex: index,       })     }  />));

We need a circular marker for each item in the data array. And, for that, we are going to loop through each item in the data array and return Circle SVG component for each one of them.

Now, to position them on the chart, we’ll use the cx and cy props to position them horizontally and vertically, respectively. For cx we will use date key and for cy we will use the score key.

Apart from that, we’ll also pass onPress prop that will set three states, tooltipX, tooltipY and tooltipIndex when any of the data points are pressed. We’ll use then use these states to position the Tooltip decorator.

Area charts with the markers

Adding Tooltip

Now that we have necessary information like x-axis(tooltipX), the y-axis (tooltipY)and index(tooltipIndex) of the marker pressed, we can use them to place Tooltip on the AreaChart.

We’ll create a new file for the Tooltip Decorator.

const Tooltip = ({ x, y, tooltipX, tooltipY, color, index, dataLength,}) => {
let xAxis = 4;  if (dataLength > 4) {    if (index < 2) {      xAxis = 35;    } else if (index > dataLength — 2) {      xAxis = -20;    } else {     xAxis = 4;    }  }
return (    <;G x={x(tooltipX) — 40} y={y(tooltipY)}>      <G y={tooltipY > 9 ? 20 : -29} x={xAxis}>        <Rect x={-2} y={0} height={22} width={70} stroke={color} fill=”white” ry={10} rx={10} />        <Rect x={-2} y={0} height={22} width={18} fill={color} ry={10} rx={10} />        <Rect x={10} y={0} height={22} width={tooltipY > 9 ? 12 : 10} fill={color} /&gt;        <Text x={6} y={14} stroke=”#fff”>          {tooltipY}        </Text>        <Text x={tooltipY > 9 ? 24 : 22} y={14}>          {moment(tooltipX).format(‘MMM DD’)}        </Text>      </G>    </G>  );};

Don’t get confused or intimidated by all the React, G and Text tags here, most of them are just for the styling of the tooltip.

Just focus on tooltipX and, tooltipY that we are using to position the Tooltip horizontally and vertically on the chart. These values are the same as cx and cy that we used for the marker, except that we are adding and subtracting some values to adjust them on the chart.

Apart from that, we are using tooltipIndex to offset the first and last Tooltip so that they don’t get cut off on the sides.

Here is the full source code of a working example.
Area chart with tappable tooltips

Final Thoughts

That is all we need to do to create charts, markers, and tooltips. This is just a basic implementation of what can be achieved using the react-native-svg-charts library.

If you want to explore more, do check out their examples repo where they showcase tons of other use cases.

For the sake of brevity I’ve skipped some boilerplate code which you can find on the Github repo.

Let me know if you find anything confusing. If you have worked on react native charts, do share what libraries and use cases you came across.