Skip to content

Instantly share code, notes, and snippets.

@WesThorburn
Last active November 1, 2024 08:11
Show Gist options
  • Save WesThorburn/7bcc930e9b48e002be67de4a00cc9420 to your computer and use it in GitHub Desktop.
Save WesThorburn/7bcc930e9b48e002be67de4a00cc9420 to your computer and use it in GitHub Desktop.
Use Chart.js with Nuxt v2.11.0

Use Chart.js with Nuxt v2.11.0

Line chart example

  • Run npm i vue-chartjs
  • Run npm i chart.js hchs-vue-charts
  • Create a file called chart.js and save it in the /plugins directory
  • Give chart.js the following contents
import Vue from 'vue'
import { Line } from 'vue-chartjs'

Vue.component('line-chart', {
	extends: Line,
	props: ['data', 'options'],
	mounted () {
		this.renderChart(this.data, this.options)
	}
})
  • Include line-chart.js in nuxt.config.js plugins like so
plugins: [
	{src: '~/plugins/chart.js', mode: 'client'}
],
  • Nuxt may have to be restarted at this point: npm run dev or nuxt
  • Use the line chart in your views like so:
  <template>
    <client-only>
        <line-chart :data="chartData"></line-chart>
    </client-only>
  </template>

  <script>
  export default {
    data() {
      return {
        chartData: {
          datasets: [{
            label: 'Title',
            data: [45, 55, 48, 35, 12]
          }]
        }
      };
    }
  }
  </script>
  • The chart will still render without client-only however the client side DOM tree will no longer match the server render and a console error will be shown.

Multi chart example

  • You can add multiple Chart.js types to your chart.js plugin file like so:
import Vue from 'vue'
import { Line } from 'vue-chartjs'
import { Pie } from 'vue-chartjs'

Vue.component('line-chart', {
	extends: Line,
	props: ['data', 'options'],
	mounted () {
		this.renderChart(this.data, this.options)
	}
})

Vue.component('pie-chart', {
	extends: Pie,
	props: ['data', 'options'],
	mounted () {
		this.renderChart(this.data, this.options)
	}
})
@NekiKulLik
Copy link

@aivaras-ciurlionis Hmm I'm using pretty much the same code and exactly the same versions of Nuxt and Chart.js but can't modify options of any chart. For instance - if I pass in to hide the legend, it ignores it and uses default. Did you experience the same issue?

@Stacker8
Copy link

@aivaras-ciurlionis Hmm I'm using pretty much the same code and exactly the same versions of Nuxt and Chart.js but can't modify options of any chart. For instance - if I pass in to hide the legend, it ignores it and uses default. Did you experience the same issue?

Yep same issue for me

@shiouming
Copy link

shiouming commented Jun 27, 2022

@WesThorburn Thanks for sharing the instruction. They are great starting point, especially for front-end newbie like me :)

I encountered few issues and below is how they got resolved. Perhaps these issues are resulted from changes / new requirement introduced in recent versions, just my guess.

My versions:

{
    "chart.js": "^3.8.0",
    "nuxt": "^2.15.8",
    "vue": "^2.6.14",
    "vue-chartjs": "^4.1.1",
}
  1. For Vue 2, import the chart component from vue-chartjs/legacy instead of from 'vue-chartjs'.
    https://vue-chartjs.org/guide/#creating-your-first-chart

  2. Regardless of Vue 2 or 3, import and register few more elements from chart.js. Refer the Line.vue code in the official example:
    https://codesandbox.io/s/github/apertureless/vue-chartjs/tree/main/legacy/sandboxes/line?file=/src/components/Line.vue

  3. During runtime I was getting error complaining that required props chartData is missing.
    My solution: rename the data props as chartData.

  4. The chart background and axis (incl. axis scale) were displayed properly, but the data line was not coming.
    My solution: within the chartData object, in addition to datasets, add a labels array, each element is the label for a data point.

Voila!

I still need to explore more especially customisation of the chart.

@shiouming
Copy link

BTW, may I know why it has to be implemented as Nuxt plugin rather than standard Vue component?

Initially I tried to implement the chart as Vue component, but the import statement (from vue-chartjs/legacy) seems to cause runtime error Cannot use import statement outside a module. When I search this error message in google, some responses in StackOverflow suggest to implement thing as Nuxt plugin instead of component. Eventually I landed on this page.

Copy link

ghost commented Aug 10, 2022

This worked well for me with everyone's tips. I had to remove <client-only>...</client-only> .. it was causing some screwy page rendering behavior. My charts were showing up only after saving my Nuxt project, but not on a page refresh. Removing that resolved the issue for me and I haven't noticed any problems or console errors without it

I'm using chartsjs in markdown files with embedded Vue components.

Thank you all for your input on this.

Below is what worked for me.


Relevant package versions:

"dependencies": {
  "vue": "^2.7.8",
  "nuxt": "^2.15.8",
  "chart.js": "^3.8.0",
  "vue-chartjs": "^4.1.1",
  "hchs-vue-charts": "^1.2.8",
},

/plugins/chart.js

import Vue from 'vue'
import { Line } from 'vue-chartjs/legacy'
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
  PointElement
} from 'chart.js'

ChartJS.register(
  Title,
  Tooltip,
  Legend,
  PointElement,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement
)

Vue.component('line-chartjs', {
  extends: Line
})

nuxt.config.js

  plugins: [
    { src: '~/plugins/chart.js', mode: 'client' }
  ],

markdown file: (I'm doing some custom work here.. so the format will look a bit off)

---
title: Chart Test
description: 
---

<line-chart :labels="['a', 'b', 'c', 'd', 'e']" :datasets="[ { label:'a', data:[2,20,50,100,10] }, { label:'b', data:[25,2,15,80,60] }, { label:'c', data:[25,32,15,810,60] }, { label:'d', data:[215,2,15,80,610] } ]"></line-chart>

Custom component:

<template>
  <div class="myclass">
    <line-chartjs :chart-data="chartData" :chart-options="options" />
  </div>
</template>

@ghonchesefidi
Copy link

Good job. Thanks for this useful gist!

@ghonchesefidi
Copy link

I was able to fix the issue by changing the following code:

/plugins/chart.js :

import Vue from "vue";
import { Line } from "vue-chartjs/legacy";
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
  PointElement,
} from "chart.js";

ChartJS.register(
  Title,
  Tooltip,
  Legend,
  PointElement,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
);

Vue.component("line-chart", {
  extends: Line,
});

nuxt.config.js:

plugins: [
	{src: '~/plugins/chart.js', mode: 'client'}
]

And then using the component as:

<template>
  <div>
    <client-only placeholder="Loading...">
      <line-chart
        :chart-options="options"
        :chart-data="data"
        :height="100"
        :width="300"
        chart-id="lineChart"
      />
    </client-only>
  </div>
</template>

Nuxt/vue/chart.js versions used:

{
   "chart.js": "^3.7.1",
   "vue-chartjs": "^4.0.6",
   "nuxt": "^2.15.7"
}

Thanks. This worked for me
"chart.js": "^3.9.1"
"vue-chartjs": "^4.1.1"
"nuxt": "^2.15.8"
"vue": "^2.6.14"

@yakserr
Copy link

yakserr commented Dec 14, 2022

I was able to fix the issue by changing the following code:
/plugins/chart.js :

import Vue from "vue";
import { Line } from "vue-chartjs/legacy";
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
  PointElement,
} from "chart.js";

ChartJS.register(
  Title,
  Tooltip,
  Legend,
  PointElement,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
);

Vue.component("line-chart", {
  extends: Line,
});

nuxt.config.js:

plugins: [
	{src: '~/plugins/chart.js', mode: 'client'}
]

And then using the component as:

<template>
  <div>
    <client-only placeholder="Loading...">
      <line-chart
        :chart-options="options"
        :chart-data="data"
        :height="100"
        :width="300"
        chart-id="lineChart"
      />
    </client-only>
  </div>
</template>

Nuxt/vue/chart.js versions used:

{
   "chart.js": "^3.7.1",
   "vue-chartjs": "^4.0.6",
   "nuxt": "^2.15.7"
}

Thanks. This worked for me "chart.js": "^3.9.1" "vue-chartjs": "^4.1.1" "nuxt": "^2.15.8" "vue": "^2.6.14"

I got an error "Cannot find module 'vue-chartjs' from" do you know how to solve?
I use same version.

@Maelstromeous
Copy link

@ghost Thank you! You've saved my bacon here!

@vince015
Copy link

I'm getting this error just from installing
Screen Shot 2023-08-21 at 09 28 38

package.json

"dependencies": {
    "nuxt": "^2.15.8",
    "nuxt-buefy": "^0.4.13",
    "vue": "^2.6.14",
},
"devDependencies": {
    "node-sass": "^9.0.0",
    "sass": "^1.64.2",
    "sass-loader": "^10.4.1",
    "webpack": "^4.46.0"
}

@Ali-SaZa
Copy link

I'm getting this error:
ERROR in ./node_modules/vue-chartjs/dist/index.js 216:37
Module parse failed: Unexpected token (216:37)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| const ref = shallowRef(null);
| const reforwardRef = (chartRef)=>{

            ref.value = chartRef?.chart;

| };
| expose({

package.json

"nuxt": "^2.15.8", "vue": "^2.7.10",

@ilyagarbuz
Copy link

I'm getting this error: ERROR in ./node_modules/vue-chartjs/dist/index.js 216:37 Module parse failed: Unexpected token (216:37) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders | const ref = shallowRef(null); | const reforwardRef = (chartRef)=>{

            ref.value = chartRef?.chart;

| }; | expose({

package.json

"nuxt": "^2.15.8", "vue": "^2.7.10",

you have to use this versions
{
...
"dependencies": {
"chart.js": "2.9.4",
"vue-chartjs": "^3.5.1"
}
...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment