How to import and use a custom Chart.js plugin in Nuxt? (Chartjs-vuejs v2.9.4)

Viewed 839

I am trying to import a custom plugin into my chart.
Got this plugin from my previous question: Question
Its a plugin so that I can use Grace in my version of Chart.js.
The version of Chart.js I am using is V2.9.4. I am using vue-chartjs in Nuxt!.
Couldn't really find an answer anywhere else.


This is how it looks now

This is how I want it to look

Thanks in advance. :)

  1. I made a Component called 'BarChart' in my Components folder.
  2. I made a normal .vue file in my pages directory. In the <template> tag I added my <Barchart/> component.
  3. In that same .vue file I added a script in the <script> tag.
  4. The plugin code is included in the codes below, I didn't include it anywhere yet.

  1. Barchart.vue (Component)

    <script>
    import {Bar} from "vue-chartjs";
    
    export default {
      extends: Bar,
      props: {
        data: {
          type: String,
          default: () => {},
        },
        options: {
          type: Object,
          default: () => {},
        },
      },
      computed: {
        Chart() {
          return['data', 'options'];
        },
      },
      mounted() {
        this.renderChart(this.data, this.options);
      },
    };
    </script>

  1. .vue file (Include component)

    <div class="chart">
      <BarChart :data="barChartData" :options="barChartOptions" :height="200"/>
    </div>

  1. .vue file (script tags)

    <script>
    import BarChart from "~/components/plugins/BarChart";
    
    export default {
      components: {
        BarChart,
      },
      data() {
        return {
          barChartData: {
            labels: ["Verzonden", "Ontvangen", "Geopend", "Kliks"],
            datasets: [
              {
                data: [25, 20, 20, 18],
                backgroundColor: [
                  '#7782FF',
                  '#403DD3',
                  '#FFB930',
                  '#00E437',
                ],
                barThickness : 50,
              },
            ],
          },
          barChartOptions: {
            responsive: true,
            legend: {
              display: false,
            },
            scales: {
              xAxes: [
                {
                  gridLines: {
                    display: false,
                  },
                  ticks: {
                    fontColor: "black",
                    fontSize: 14,
                  },
                },
              ],
              yAxes: [
                {
                  ticks: {
                    beginAtZero: true,
                    min: 0,
                    stepSize: 5,
                    fontColor: '#ABACB3',
                  },
                  gridLines: {
                    display: true,
                    borderDash: [4, 4],
                    color: '#EEEDFB',
                    drawBorder: false,
                  },
                },
              ],
            },
          },
        };
      },
    };
    </script>

  1. Plugin code (where do I put this and how do I make it work?)

    const plugin = {
      id: "customScale",
      beforeLayout: (chart, options, c) => {
        let max = Number.MIN_VALUE;
        let min = Number.MAX_VALUE
        let grace = options.grace || 0
    
        chart.data.datasets.forEach((dataset) => {
          max = Math.max(max, Math.max(...dataset.data));
          min = Math.min(min, Math.min(...dataset.data))
        })
    
        if (typeof grace === 'string' && grace.includes('%')) {
          grace = Number(grace.replace('%', '')) / 100
    
          chart.options.scales.yAxes[0].ticks.suggestedMax = max + (max * grace)
          chart.options.scales.yAxes[0].ticks.suggestedMin = min - (min * grace)
    
        } else if (typeof grace === 'number') {
    
          chart.options.scales.yAxes[0].ticks.suggestedMax = max + grace
          chart.options.scales.yAxes[0].ticks.suggestedMin = min - grace
    
        }
    
      }
    }

1 Answers

According to the vue-chartjs documentation you can do this in 2 ways.

If you want the plugin to be available for all your charts you can use the global registration like so:

import Chart from 'chart.js'

Chart.pluginService.register({
    id: "customScale",
    beforeLayout: (chart, options, c) => {
      let max = Number.MIN_VALUE;
      let min = Number.MAX_VALUE
      let grace = options.grace || 0

      chart.data.datasets.forEach((dataset) => {
        max = Math.max(max, Math.max(...dataset.data));
        min = Math.min(min, Math.min(...dataset.data))
      })

      if (typeof grace === 'string' && grace.includes('%')) {
        grace = Number(grace.replace('%', '')) / 100

        chart.options.scales.yAxes[0].ticks.suggestedMax = max + (max * grace)
        chart.options.scales.yAxes[0].ticks.suggestedMin = min - (min * grace)

      } else if (typeof grace === 'number') {

        chart.options.scales.yAxes[0].ticks.suggestedMax = max + grace
        chart.options.scales.yAxes[0].ticks.suggestedMin = min - grace

      }

    }
  });

This way of importing and registering should work from anywhere in your app.

The second way is an inline plugin. This needs to be done in your BarChart.vue and goes like this:

mounted() {
  this.addPlugin(
    Chart.pluginService.register({
      id: "customScale",
      beforeLayout: (chart, options, c) => {
        let max = Number.MIN_VALUE;
        let min = Number.MAX_VALUE
        let grace = options.grace || 0

        chart.data.datasets.forEach((dataset) => {
          max = Math.max(max, Math.max(...dataset.data));
          min = Math.min(min, Math.min(...dataset.data))
        })

        if (typeof grace === 'string' && grace.includes('%')) {
          grace = Number(grace.replace('%', '')) / 100

          chart.options.scales.yAxes[0].ticks.suggestedMax = max + (max * grace)
          chart.options.scales.yAxes[0].ticks.suggestedMin = min - (min * grace)

        } else if (typeof grace === 'number') {

          chart.options.scales.yAxes[0].ticks.suggestedMax = max + grace
          chart.options.scales.yAxes[0].ticks.suggestedMin = min - grace

        }

      }
    });
  )
}
Related