Vue3でchart.jsを使用してみる。

### まえがき
Vueでchart.jsを使用する際にはvue-chartjsのパッケージを使用するのが一般的なようです。しかし今現在(2020/11/19)、vue-chartjsはVue3に対応していないようなので、chart.jsをそのまま使ってみました。
この記事はその時のメモ的な感じになりますので方法としては間違っているかもしれません。

### 方法
まずはchart.jsのパッケージをインストールします。npmで行いました。

```
npm install chart.js --save
```

次に書いたソースコードを載せます。

```Vue
<template lang="pug">
canvas#pentagonChart
</template>

<script>
import { mapState } from "vuex";
import { Chart } from "chart.js";

export default {
  methods: {
    createChart() {
      const seasonal_sense = this.evaluatedClothes.seasonal_sense;
      const formality = this.evaluatedClothes.formality;
      const trend = this.evaluatedClothes.trend;
      const value = this.evaluatedClothes.value;
      const colorfulness = this.evaluatedClothes.colorfulness;
      new Chart(this.ctx, {
        type: "radar",
        data: {
          labels: [
            "季節感",
            "トレンド感",
            "カラフルさ",
            "フォーマルさ",
            "価格帯"
          ],
          datasets: [
            {
              label: "あなたの結果",
              data: [seasonal_sense, trend, colorfulness, formality, value],
              backgroundColor: "RGBA(33,33,33, 0.5)",
              borderColor: "RGBA(33,33,33, 1)",
              borderWidth: 1,
              pointBackgroundColor: "RGB(11,11,11)"
            }
          ]
        },
        options: {
          title: {
            display: true
          },
          scale: {
            ticks: {
              suggestedMin: 0,
              suggestedMax: 10,
              stepSize: 1,
              callback: function(value) {
                return value + "pt";
              }
            }
          }
        }
      });
    }
  },
  computed: mapState("evaluation", {
    evaluatedClothes: "evaluatedClothes"
  }),
  watch: {
    evaluatedClothes: function() {
      this.createChart();
    }
  },
  mounted() {
    this.ctx = document.getElementById("pentagonChart");
    this.createChart();
  }
};
</script>

```
### テンプレート

このテンプレートはpugで書かれています。htmlでもどちらでも良いですが、canvasを置いて任意のidを設定しておきましょう。

```Vue
<template lang="pug">
canvas#pentagonChart
</template>
```

### スクリプト

1. chart.jsから任意のグラフをインポートします。今回はレーダーチャート(多角形のグラフ)を使用するので、Chartをインポートします。

2. methodsにチャートを生成するような関数をchart.jsの記法を参考にして書いていきます。ラベルや値の代入などは任意です。datasets → dataに出力したい値が入るようにします。今回はstoreからmapStateで読み取った値がそのまま入るようにしています。

3. mounted()でcanvasを取得するためにdocument.getElementByIdした後、methodsに設定した描写関数を呼び出します。このときに取得したcanvasを共有できるように書きます。たぶんなのですが、mounted()で描写関数を呼び出さないとライフサイクル的にcanvasを取得することができません。created()に書いてしまうとcanvasが取得できないためか、真っ白になります。ライフサイクルを参考にして書いていきましょう。

4. storeの値が変わった時に変更を反映させたいため、watchに処理を書いておきます。storeに置いてあるであろうevaluatedClothesが変更されたときに、グラフを再描写させることで更新しています。

5. これで完成です。

```Vue
<script>
import { mapState } from "vuex";
import { Chart } from "chart.js";

export default {
  methods: {
    createChart() {
      const seasonal_sense = this.evaluatedClothes.seasonal_sense;
      const formality = this.evaluatedClothes.formality;
      const trend = this.evaluatedClothes.trend;
      const value = this.evaluatedClothes.value;
      const colorfulness = this.evaluatedClothes.colorfulness;
      new Chart(this.ctx, {
        type: "radar",
        data: {
          labels: [
            "季節感",
            "トレンド感",
            "カラフルさ",
            "フォーマルさ",
            "価格帯"
          ],
          datasets: [
            {
              label: "あなたの結果",
              data: [seasonal_sense, trend, colorfulness, formality, value],
              backgroundColor: "RGBA(33,33,33, 0.5)",
              borderColor: "RGBA(33,33,33, 1)",
              borderWidth: 1,
              pointBackgroundColor: "RGB(11,11,11)"
            }
          ]
        },
        options: {
          title: {
            display: true
          },
          scale: {
            ticks: {
              suggestedMin: 0,
              suggestedMax: 10,
              stepSize: 1,
              callback: function(value) {
                return value + "pt";
              }
            }
          }
        }
      });
    }
  },
  computed: mapState("evaluation", {
    evaluatedClothes: "evaluatedClothes"
  }),
  watch: {
    evaluatedClothes: function() {
      this.createChart();
    }
  },
  mounted() {
    this.ctx = document.getElementById("pentagonChart");
    this.createChart();
  }
};
</script>

```

### さいごに
今回はchart.jsをそのままVue3で使用してみました。フロントエンドのフレームワークは、何かのjsをラッパーしたパッケージがたくさんあってとても便利ですが、使いたいjsパッケージがラッパーされてないこともあると思います。ラッパーされているものも、されていないものも、臨機応変に使っていきたいです。