Using Chart.js with Vue.js

Dave Berning

If you aren’t familiar with Chart.js, it’s worth looking into it. It’s a powerful and simple way to create clean graphs with the HTML5 <canvas> element. Don’t worry, you don’t need to know anything about the <canvas> to use Chart.js. With Vue’s data() object, it’s easy to store our data and manipulate it to change our graph when needed.

Install Chart.js

First thing that you want to do is create a Vue.js application using the webpack-simple template and install Chart.js.

$ vue init webpack-simple <project-name>
$ cd <project-name>
$ npm install
$ npm install chart.js --save

Navigate to your App.vue file and remove all of the generated code. The chart’s <canvas> will be in the root #app element. Next, import Chart.js using ES6 into your Vue component.

App.vue

import Chart from 'chart.js';

Creating the Chart

This chart is going to have two datasets: One) with the number of moons per planet in our solar system and two) with the overall mass of each planet. With these two datasets, we can have different chart types to show correlations in data.

Every Chart.js chart needs to have a <canvas> in the HTML markup. The id of the chart is used as a selector to bind the JavaScript to it.

App.vue

<template>
  <div id="app">
    <canvas id="planet-chart"></canvas>
  </div>
</template>

Structure of the Chart

In it’s simplest form, each chart has the same basic structure:

const ctx = document.getElementById('planet-chart');
const myChart = new Chart(ctx, {
  type: '',
  data: [],
  options: {},
});

You can start by adding your data to this Chart object and keep repeating that process for each new chart you want to create. However, this process can be a lot easier if we had a function to pass arguments into.

Start by creating a new function in your component’s methods object and give it two parameters, chartId and chartData.

App.vue

methods: {
  createChart(chartId, chartData) {
    const ctx = document.getElementById(chartId);
    const myChart = new Chart(ctx, {
      type: chartData.type,
      data: chartData.data,
      options: chartData.options,
    });
  }
}

Chart.js tends to have a lot of code. This simple “planets” chart for example, has at least 50+ lines of code in it. Imagine having multiple charts with complex data.

Your single file Vue component can become large and confusing quick. So let’s use ES6 to import our chart’s data, in order to keep our Vue component slim and focused.

Creating the Chart’s Data

Create a new .js file inside the root src directory. For this post, it’s called chart-data.js. However, you can name this anything you like. Create a const and name it planetChartData.

Keep in mind, you’ll want to give it a unique and descriptive name based on the data. You can have several data objects in this file for different charts

chart-data.js

export const planetChartData = {
  type: 'line',
  data: {
    labels: ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune'],
    datasets: [
      { // one line graph
        label: 'Number of Moons',
        data: [0, 0, 1, 2, 67, 62, 27, 14],
        backgroundColor: [
          'rgba(54,73,93,.5)', // Blue
          'rgba(54,73,93,.5)',
          'rgba(54,73,93,.5)',
          'rgba(54,73,93,.5)',
          'rgba(54,73,93,.5)',
          'rgba(54,73,93,.5)',
          'rgba(54,73,93,.5)',
          'rgba(54,73,93,.5)'
        ],
        borderColor: [
          '#36495d',
          '#36495d',
          '#36495d',
          '#36495d',
          '#36495d',
          '#36495d',
          '#36495d',
          '#36495d',
        ],
        borderWidth: 3
      },
      { // another line graph
        label: 'Planet Mass (x1,000 km)',
        data: [4.8, 12.1, 12.7, 6.7, 139.8, 116.4, 50.7, 49.2],
        backgroundColor: [
          'rgba(71, 183,132,.5)', // Green
        ],
        borderColor: [
          '#47b784',
        ],
        borderWidth: 3
      }
    ]
  },
  options: {
    responsive: true,
    lineTension: 1,
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true,
          padding: 25,
        }
      }]
    }
  }
}

export default planetChartData;

Note: You can reference Chart.js’ documentation for more information about line charts, as well as others like bar, polarArea, radar, pie, and doughnut.

By exporting planetChartData, you are allowing that const to be imported into another JavaScript file. More importantly, you’re separating the data from the component. This makes it much easier to manage and create a new chart with new data in the future.

Import your chart’s data into your App.vue component.

App.vue

import planetChartData from './chart-data.js';

Next, store the single chart’s data into Vue’s data() function.

App.vue

data() {
  return {
    planetChartData: planetChartData,
  }
}

Note: You can also use ES6 shorthand. Since the data property and value have the same name, you can just use planetChartData instead of planetChartData: planetChartData.

Initializing the Chart

At this point, Chart.js should be installed and the chart’s data should be imported into the App.vue component. In the methods object, you also created a function that creates the chart object with data from the chart-data.js file.

You should already have a <canvas> element created in the component’s template. At this point, it’s time to initialize the chart and write to the <canvas>.

To do so, you need to run the createChart() function in the component’s mounted() lifecycle method. This function takes two arguments; the chartId (string) and chartData (object in our data from chart-data.js).

App.vue

mounted() {
  this.createChart('planet-chart', this.planetChartData);
}

The chart should render now when the component is mounted!

line graph

As you can see, we can focus on our data and let Chart.js do the hard work.

Mixed charts

Chart.js also supports mixed charts. Continuing with the planets chart you created above, let’s show this same data with two types of graphs.

Open your chart-data.js file and let’s modify the types property of our chart and datasets. Find the type property of your chart’s data and change it to bar. At this point, both charts will be bar graphs. However, we want the graph to show a bar and a line graph.

To change this, in each dataset object, add a type property under the label property. For the first dataset object, give it a type property with a value of line and for the second, give it a type property with a value of bar.

chart-data.js

data: {
  type: 'bar', // was "line"
  labels: ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune'],
  datasets: [
    {
      label: 'Number of Moons',
      type: 'line', // Add this
      data: [...],
      backgroundColor: [...],
      borderColor: [...],
      borderWidth: 3
    },
    {
      label: 'Planet Mass (x1,000 km)',
      type: 'bar', // Add this
      data: [...],
      backgroundColor: [...],
      borderColor: [...],
      borderWidth: 3
    }
  ]
}

After your component mounts, you should see something like this:

line and bar graph

This post just scratched the surface of what you can do with Chart.js. You should have a basic understanding on how to use Chart.js with Vue by separating your data with ES6 imports.

  Tweet It
✖ Clear

🕵 Search Results

🔎 Searching...