NuxtでChart.jsを利用する

# はじめに
[Chart.js](https://www.chartjs.org/ "Chart.js | Open source HTML5 Charts for your website")はjavascriptで簡単に綺麗なグラフを描くことができるチャートライブラリです。

そのChart.jsをVue.jsから利用できるようにした[vue-chart.js](https://vue-chartjs.org/ "📈 vue-chartjs")というライブラリがあり、今回はそちらを利用して`Nuxt` + `vue-chart.js`にてチャートの作成を行ってみました！

# vue-chart.jsをインストール
[公式ドキュメント](https://vue-chartjs.org/guide/#introduction "Getting Started | 📈 vue-chartjs")を参考にNuxtプロジェクトにvue-chart.jsをインストールします。

```bash
npm install vue-chartjs chart.js --save
```
# chartの実装方法
インストールが完了したら早速vue-chart.jsを利用してチャートの作成に取り掛かります。
[公式ドキュメント](https://vue-chartjs.org/guide/#creating-your-first-chart "Getting Started | 📈 vue-chartjs")によると以下の実装でチャートを作成できます。

```javascript

import { Bar } from 'vue-chartjs'

export default {
  extends: Bar,
  mounted () {
    this.renderChart(data, options)
  }
}
```

基本的には`vue-chartjs`から利用したいChartをインポートし、extendした上でmountedのタイミングでパラメータ（データセット、オプション）渡しChartを描画します。

各pageファイルで上記実装を行ってあげればChartを描画できますが、棒グラフや線グラフ、円グラフなど各Chart毎Componentに切って実装してあげた方が良さそうです。

そこでPluginを実装し、利用したいChartをGlobalなコンポーネントとして登録することにしました。

# Pluginを実装
Pluginの実装にあたり、pluginsディレクトリ配下に`vue-chartjs.js`ファイルを作成します。
その中にプロジェクト内で利用するchartコンポーネントを作成し、`Vue.component`メソッドにてGlobalなコンポーネントとして登録をします。

今回はサンプルとしてDoughnut Chartのコンポーネント（`doughnut-chart`）を作成しました。

```javascript:plugins/vue-chartjs.js

import Vue from 'vue';
import { Doughnut, mixins } from 'vue-chartjs';
const { reactiveProp } = mixins;

Vue.component('doughnut-chart', {
  extends: Doughnut,
  mixins: [reactiveProp],
  props: {
    options: {
      type: Object,
      default: () => {},
    },
  },
  mounted() {
    this.renderChart(this.chartData, this.options);
  },
});
```
ここで注意点ですが、Chart.js自身ではデータセット（this.chartDataの値）が変更された際、ライプアップデートの機能を提供していません。
ライブアップデートを実現するためには、vue-chart.jsが提供しているmixinを利用します。
https://vue-chartjs.org/guide/#updating-charts

`doughnut-chart`コンポーネントでは`reactiveProp`を利用し、propsとして渡されたデータセットが変更された際にチャートもライブアップデートされるように実装しました。

Pluginの実装が完了したら`nuxt.config.js`の`plugins`に追記をします。

```javascript:nuxt.config.js

module.exports = {
  // ・・・省略
  plugins: [
    {
      src: '@/plugins/vue-chartjs',
      ssr: false,
    },
  ],
  // ・・・省略
};
```

# chartを実装する
Pluginを作成し、Globalなコンポーネントとして`doughnut-chart`コンポーネントを登録したら、あとは各Pageからそのコンポーネントを呼び出しチャートを描画するだけです。

今回は、チャートの描画に加えランダムにデータを更新するボタンの実装も行いました。

※以下のサンプルはコンポーネントフレームワークに[Vuetify](https://vuetifyjs.com/en/ "Vue.js Material Component Framework — Vuetify.js")を利用しています。

```vuejs:pages/index.vue

<template>
  <v-container fluid>
    <doughnut-chart :chart-data="chartData" :options="chartOptions"/>

    <div class="text-xs-center mt-2">
      <v-btn dark color="indigo" @click="randomizeData()">Randomize data</v-btn>
    </div>
  </v-container>
</template>

<script>
import colors from 'vuetify/es5/util/colors';

export default {
  data() {
    return {
      chartDataValues: [],
      chartColors: [
        colors.red.lighten1,
        colors.blue.lighten1,
        colors.yellow.lighten1,
        colors.green.lighten1,
      ],
      chartLabels: ['red', 'blue', 'yellow', 'green'],
      chartOptions: {
        maintainAspectRatio: false,
        animation: {
          duration: 1500,
          easing: 'easeInOutCubic',
        },
      },
    };
  },
  computed: {
    chartData() {
      return {
        datasets: [
          {
            data: this.chartDataValues,
            backgroundColor: this.chartColors,
          },
        ],
        labels: this.chartLabels,
      };
    },
  },
  mounted: function() {
    this.randomizeData();
  },
  methods: {
    randomizeData: function() {
      var data = [];
      for (var i = 0; i < this.chartLabels.length; i++) {
        data.push(Math.floor(Math.random() * 100));
      }
      this.chartDataValues = data;
    },
  },
};
</script>
```

実行結果は以下のようになり、ボタン押下でチャートが更新されることも確認できました。

![スクリーンショット 2019-03-31 21.26.18.png](https://qiita-image-store.s3.amazonaws.com/0/165249/616af9b1-b576-79ea-0c82-5509d614f5f9.png)