Responsive charts using Chart.js and react-chartjs-2

5 min read

I have been testing and comparing a few charting libraries lately to use for a new page featuring charts on this website.

In the end, I have decided to use Chart.js because the charts are better looking, the animations are smooth, the documentation is really good and my overall experience was pleasant. The react-chart-js-2 wrapper even made it easier to build charts.

So I decided to make this quick tutorial where we will build a simple responsive linear chart using chart.js and react-chartjs-2.

Installation

First, let’s generate a CRA project.

npx create-react-app react-chartjs-tutorial
cd react-chartjs-tutorial

And then add Chart.js and react-chartjs-2.

yarn add react-chartjs-2 chart.js

Building a line chart

Cleaning first, let’s remove the CSS in the App.css file, clear the header HTML content inside the App.js file. Then, add a title inside the header tag and an article tag with a canvas-container class after the header.

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <h1>Responsive Linear chart using Chart.js</h1>
        </header>
        <article className="canvas-container">
          
        </article>
      </div>
    );
  }
}

export default App;

Now, import the Line component from react-chartjs-2 and add it inside our article tag.

import React, { Component } from 'react';
import './App.css';
import { Line } from 'react-chartjs-2';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <h1>Responsive Linear chart using Chart.js</h1>
        </header>
        <article className="canvas-container">
          <Line />
        </article>
      </div>
    );
  }
}

export default App;

An empty chart should be rendered since we did not specify the data props to our Line component yet.

The data props contains two arrays:

  • labels, which is the array containing our labels, X axis values.
  • datasets, which is an array of Dataset objects containing the properties of a line such as the Y axis data, line color, etc. You can find all the Dataset properties here.

Let’s create fake sample data and give it to our component.

import React, { Component } from 'react';
import './App.css';
import { Line } from 'react-chartjs-2';

class App extends Component {
  render() {
    const data = {
      labels: [
        '10/04/2018', '10/05/2018', 
        '10/06/2018', '10/07/2018', 
        '10/08/2018', '10/09/2018', 
        '10/10/2018', '10/11/2018', 
        '10/12/2018', '10/13/2018', 
        '10/14/2018', '10/15/2018'
      ],
      datasets: [
        {
          label: 'Temperature',
          data: [22,19,27,23,22,24,17,25,23,24,20,19],
          fill: false,          // Don't fill area under the line
          borderColor: 'green'  // Line color
        }
      ]
    }

    return (
      <div className="App">
        <header className="App-header">
          <h1>Responsive Linear chart using Chart.js</h1>
        </header>
        <article className="canvas-container">
          <Line data={data}/>
        </article>
      </div>
    );
  }
}

export default App;

You should now be able to see a green line.

Making it responsive

If you switch your browser to mobile mode, you will notice that our chart is already responsive. This is because Chart.js will adapt the height of the chart depending on the width since the maintainAspectRatio option is set to true by default. The problem is that the smaller the width gets, the harder it is to read our graph because of the small height.

  • So the first step is to set the maintainAspectRatio option to false. We will then have a chart with an even smaller height because it will be rendered using the minimum height needed.

  • The second step is to set a height to the canvas’ container. The chart will then be rendered using all the space given to him by his container.

Let’s specify a fixed height for our container inside our App.css file.

.canvas-container {
  height: 60vh;
}

And then, let’s specify new options to our Line component.

import React, { Component } from 'react';
import './App.css';
import { Line } from 'react-chartjs-2';

class App extends Component {
  render() {
    const data = {
      labels: [
        '10/04/2018', '10/05/2018', 
        '10/06/2018', '10/07/2018', 
        '10/08/2018', '10/09/2018', 
        '10/10/2018', '10/11/2018', 
        '10/12/2018', '10/13/2018', 
        '10/14/2018', '10/15/2018'
      ],
      datasets: [
        {
          label: 'Temperature',
          data: [22,19,27,23,22,24,17,25,23,24,20,19],
          fill: false,          // Don't fill area under the line
          borderColor: 'green'  // Line color
        }
      ]
    }

    const options = {
      maintainAspectRatio: false	// Don't maintain w/h ratio
    }

    return (
      <div className="App">
        <header className="App-header">
          <h1>Responsive Linear chart using Chart.js</h1>
        </header>
        <article className="canvas-container">
          <Line data={data} options={options}/>
        </article>
      </div>
    );
  }
}

export default App;

We now have a good looking and easy to read responsive chart.

It is worth noting that the maintainAspectRatio option can be specified globally and be applied to every chart by importing the defaults object from react-chartjs-2 and changing the global values.

import React, { Component } from 'react';
import './App.css';
import { Line, defaults } from 'react-chartjs-2';

defaults.global.maintainAspectRatio = false

class App extends Component {
  render() {
    const data = {
      labels: [
        '10/04/2018', '10/05/2018', 
        '10/06/2018', '10/07/2018', 
        '10/08/2018', '10/09/2018', 
        '10/10/2018', '10/11/2018', 
        '10/12/2018', '10/13/2018', 
        '10/14/2018', '10/15/2018'
      ],
      datasets: [
        {
          label: 'Temperature',
          data: [22,19,27,23,22,24,17,25,23,24,20,19],
          fill: false,          // Don't fill area under the line
          borderColor: 'green'  // Line color
        }
      ]
    }

    return (
      <div className="App">
        <header className="App-header">
          <h1>Responsive Linear chart using Chart.js</h1>
        </header>
        <article className="canvas-container">
          <Line data={data} />
        </article>
      </div>
    );
  }
}

export default App;

Conclusion

That’s it, thanks for reading. If you have any question or if something seems off, please leave a comment below.

You can check the code of this tutorial on my Github.