React charts using Recharts and React ChartJS 2
In this post you will learn how to implement React charts. And actually we will use 2 different packages - one with D3 and one with chart.js so you can see the difference between implementation.
So here I have 2 different libraries. First of all Recharts which uses D3 under the hood. If you don't know what is D3 it's a super popular library to create graphs inside plain Javascript. But not inside React.
The next one is React-chartjs-2 and this is a React wrapper around Chart.js. And Chart.JS is another super popular library inside Javascript world to create graphs.
This is why in this video we will focus on creating the same graph by using these 2 libraries so you can see the differences between them.
Installation
I already generated create-react-app project. Now we need to install these libraries.
yarn add recharts
This is just a single package. We don't need to install any additional dependencies.
For React-chartjs-2 we must install 2 different packages.
yarn add chart.js react-chartjs-2
And actually it is an important difference. It means that this library React-chartjs-2 is just a wrapper and it uses chart.js. And we will have a direct access to chart.js if we need to.
Here is how our App component looks like.
import RechartsExample from "./RechartsExample";
import ChartJsExample from "./ChartJsExample";
const App = () => {
return (
<div>
<h1>Monsterlessons Academy</h1>
<RechartsExample />
<ChartJsExample />
</div>
);
};
export default App;
There is nothing here but I added 2 empty components so we can start implementation.
Recharts
First of all lets try to implement a graph by using Recharts library. Let's say that we want to compare popularity by years of 3 different frameworks: Angular, Vue and React.
This is why here I prepared data from Google Trends in the format how Recharts needs it.
const data = [
{ name: "2017", react: 32, angular: 37, vue: 60 },
{ name: "2018", react: 42, angular: 42, vue: 54 },
{ name: "2019", react: 51, angular: 41, vue: 54 },
{ name: "2020", react: 60, angular: 37, vue: 28 },
{ name: "2021", react: 51, angular: 31, vue: 27 },
{ name: "2022", react: 95, angular: 44, vue: 49 },
];
const RechartsExample = () => {
return (
<h1>Recharts</h1>
);
};
export default RechartsExample;
As you can see it's an array of objects where name
is our year and we have 3 additional properties as values between 0 and 100 for every framework.
From my perspective this is a nice readable format because all properties are packed in a single object.
Now let's try to use it here. First of all we need to use LineChart
which defines which type of graph we want to do and what size should be rendered.
const RechartsExample = () => {
return (
<LineChart width={600} height={300} data={data}>
</LineChart>
);
};
We also provided our prepared data inside LineChart
.
What is really awesome in Recharts is that they separated different parts of graph to different component. Let's try to provide a Lin inside
.
const RechartsExample = () => {
return (
<LineChart width={600} height={300} data={data}>
<Line type="monotone" dataKey="react" stroke="#2196F3" strokeWidth={3} />
</LineChart>
);
};
Inside Line
we provide the dataKey
which defines what property we must take from the data. As we want to render 3 lines for every framework we define react
in the first line. With stoke
we provide a color and the width of the line.
Now let's add other lines.
const RechartsExample = () => {
return (
<LineChart width={600} height={300} data={data}>
<Line type="monotone" dataKey="react" stroke="#2196F3" strokeWidth={3} />
<Line
type="monotone"
dataKey="angular"
stroke="#F44236"
strokeWidth={3}
/>
<Line type="monotone" dataKey="vue" stroke="#FFCA29" strokeWidth={3} />
</LineChart>
);
};
We successfully rendered 3 different lines for Angular, React and Vue.
But it is not all, we also want to see our grid. And we have a specific component for this.
const RechartsExample = () => {
return (
<LineChart width={600} height={300} data={data}>
...
<CartesianGrid stroke="#ccc" />
</LineChart>
);
};
As you can see now we have a nice grid where all our lines are located.
After this we want to render years. And as you can understand we have years on the bottom of the graph and values from 0 to 100 on the left side.
const RechartsExample = () => {
return (
<LineChart width={600} height={300} data={data}>
...
<XAxis dataKey="name" />
<YAxis />
</LineChart>
);
};
We used XAxis
with dataKey
name to define which property should be rendered on the bottom. In YAxis
we don't define anything as it will just render all values from 0 to 100.
The last thing that we want is to add a tooltip and a legend.
const RechartsExample = () => {
return (
<LineChart width={600} height={300} data={data}>
...
<Tooltip />
<Legend />
</LineChart>
);
};
As you can see now we have tooltip and a legend with all frameworks that we render.
With that we successfully implemented our graph by using Recharts library. And actually I really like this library.
- We don't see anything from plain Javascript library (D3). We just use React components
- Recharts components are separated and not dependent on each other
Also I want to say that documentation on Recharts website is amazing. You have an example for each component with the list of props and child components.
I really like this library and use it when I need to build graphs.
React chartsjs 2
Now let's implement exactly the same graph but with ChartJS. Here on the top I want to put data in another format.
const labels = ["2017", "2018", "2019", "2020", "2021", "2022"];
export const data = {
labels,
datasets: [
{
label: "React",
data: [32, 42, 51, 60, 51, 95],
backgroundColor: "#2196F3",
borderColor: "#2196F3",
},
{
label: "Angular",
data: [37, 42, 41, 37, 31, 44],
backgroundColor: "#F44236",
borderColor: "#F44236",
},
{
label: "Vue",
data: [60, 54, 54, 28, 27, 49],
backgroundColor: "#FFCA29",
borderColor: "#FFCA29",
},
],
};
As you can see it is completely different format. First of all we defined labels
which are our values on the bottom. After this we defined data
with labels
and datasets
where every dataset has a label
and data
. data
is the value of each framework in every year as the labels
array.
We also provided backgroundColor
and borderColor
to apply colors to every line. I don't really like this approach as we mix data of the graph with configuration of components. From my perspective it was done much better in Recharts.
To render a graph we must define a container with width and height. Inside Recharts we provided sizes to Lines
component but here we must define container by ourselves.
const ChartJsExample = () => {
return (
<div style={{ width: 600, height: 300 }}>
<Line options={options} data={data} />
</div>
);
};
Inside the container we put Line
component with options and data. But we didn't define options yet. Let's add them now.
const options = {
plugins: {
legend: {
position: "bottom",
},
},
};
In browser we get an error "Category is not a registered scale".
From the perspective of the developer this is a bad design of the library. This error doesn't say anything to me. To fix it I must just in documentation and find the differences with my code and the example.
Inline Line chart example we can see that we miss the call to native Chart.JS library.
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
} from "chart.js";
import { Line } from "react-chartjs-2";
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend
);
This is bad as they did not isolate it inside the React wrapper and we had no clue that we need to write such code in our implementation. So we must know how Chart.JS works and it may not be that comfortable for beginners.
So we provided just Line
with options and data. We defined what to show inside our graph by using register
function on the top. If we add Tooltip
to register function then this component will be rendered. From my perspective this is not very obvious and for sure in Rechart we are getting better architecture.
If you check the documentation pages for React Chart JS is not that great and clear as you must often look in Chart.JS library itself.
Want to conquer your next JavaScript interview? Download my FREE PDF - Pass Your JS Interview with Confidence and start preparing for success today!
📚 Source code of what we've done