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 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!
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:
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.