【Vue】グラフを簡単に描けるライブラリvue-chartjsを触ってみた

# はじめに
Vue.jsのライブラリを好きに触ってみる機会があったので、Chart.jsのラッパーであるvue-chartjsを既存のRails+Vueのアプリにインストールして、少しいじってみました。

環境：Rails7、Vue3

# 導入
今回はRails7のimportmapの仕組みを使い、npmパッケージとして導入したので、下記コマンドを流しました。
```bash
/bin/importmap pin vue-chartjs chart.js
```
[公式ドキュメント](https://vue-chartjs.org/guide/#introduction)によると、他に`yarn`や`pnpm`でもインストールできるそうです。

# サンプル（棒グラフ）
まずは公式のサンプルコードをぺたんと貼り付けてみます。
```javascript:chart_comp.js
import { Bar } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js';

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

const ChartComp = {
  template: `
    <Bar
    id="my-chart-id"
    :options="chartOptions"
    :data="chartData"
  />
  `,
  components: { Bar },
  data() {
    return {
      chartData: {
        labels: [ 'January', 'February', 'March'],
        backgroundColor: '#f87979',
        datasets: [ { data: [40, 20, 12] } ]
      },
      chartOptions: {
        responsive: true
      }
    }
  }
}

export default ChartComp;
```
```html:app.html
<template>
  <BarChart />
</template>

<script>
import BarChart from 'path/to/component/BarChart'

export default {
  name: 'App',
  components: { BarChart }
}
</script>
```
いわゆる棒グラフというやつが出てきました。
ぬるっと出てくるのが素晴らしいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605286/f500bba8-5e22-a427-50f0-f031c25eef79.png)
# 他の種類
他にもこんなグラフを描けます。
## 散布図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605286/7784c28b-f489-873b-56f1-92ba22c54d8d.png)
```javascript
import { Scatter } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, PointElement, LinearScale } from 'chart.js';

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

const ChartComp = {
  template: `
    <Scatter
    id="my-chart-id"
    :options="chartOptions"
    :data="chartData"
  />
  `,
  components: { Scatter },
  data() {
    return {
      chartData: {
        datasets: [{
          label: 'Scatter Dataset',
          data: [{x: -10, y: 0},
            {x: 0, y: 10},
            {x: 10, y: 5},
            {x: 0.5, y: 5.5}],
          backgroundColor: '#0072bf'
        }]
      }
    }
  }
}
```
## レーダーチャート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605286/44197d59-0b87-1f21-0037-dbf669739521.png)
```javascript
import { Radar } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, PointElement, LineElement, RadialLinearScale } from 'chart.js';

ChartJS.register(Title, Tooltip, Legend, PointElement, LineElement, RadialLinearScale);

const ChartComp = {
  template: `
    <Radar
    id="my-chart-id"
    :options="chartOptions"
    :data="chartData"
  />
  `,
  components: { Radar },
  data() {
    return {
      chartData: {
        labels: ['食事', '水分', '睡眠', 'デザイン', 'コーディング', 'サイクリング', 'ランニング'],
        datasets: [{
          label: '1日目',
          data: [65, 59, 90, 81, 56, 55, 40],
          fill: true,
          backgroundColor: 'rgba(255, 99, 132, 0.2)',
          borderColor: 'rgb(255, 99, 132)',
          pointBackgroundColor: 'rgb(255, 99, 132)',
          pointBorderColor: '#fff',
          pointHoverBackgroundColor: '#fff',
          pointHoverBorderColor: 'rgb(255, 99, 132)'
        }, {
          label: '2日目',
          data: [28, 48, 40, 19, 96, 27, 100],
          fill: true,
          backgroundColor: 'rgba(54, 162, 235, 0.2)',
          borderColor: 'rgb(54, 162, 235)',
          pointBackgroundColor: 'rgb(54, 162, 235)',
          pointBorderColor: '#fff',
          pointHoverBackgroundColor: '#fff',
          pointHoverBorderColor: 'rgb(54, 162, 235)'
        }]
      }
    }
  }

```
## 折れ線グラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605286/d516acf9-53ab-1010-4b0d-67eac48e0362.png)
```javascript
import { Line } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, PointElement, LineElement, CategoryScale, LinearScale } from 'chart.js';

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

const ChartComp = {
  template: `
    <Line
    id="my-chart-id"
    :options="chartOptions"
    :data="chartData"
  />
  `,
  components: { Line },
  data() {
    return {
      chartData: {
        labels: ['1月', '2月', '３月', '４月', '5月', '6月', '７月'],
        datasets: [{
          label: 'データ',
          data: [65, 59, 80, 81, 56, 55, 40],
          fill: false,
          borderColor: 'rgb(75, 192, 192)',
          tension: 0.1
        }]
      }
    }
  }
}
```
## ドーナツチャート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605286/7983127f-3ae9-fcf1-23de-22e6f9db2b98.png)
```javascript
import { Doughnut } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, ArcElement } from 'chart.js';

ChartJS.register(Title, Tooltip, Legend, ArcElement);

const ChartComp = {
  template: `
    <Doughnut
    id="my-chart-id"
    :options="chartOptions"
    :data="chartData"
  />
  `,
  components: { Doughnut },
  data() {
    return {
      chartData: {
        labels: [
          'Red',
          'Blue',
          'Yellow'
        ],
        datasets: [{
          label: 'データ',
          data: [300, 50, 100],
          backgroundColor: [
            '#ff6384',
            '#0072bf',
            '#ffcd56'
          ],
          hoverOffset: 4
        }]
      }
    }
  }
}
```
# おわりに
導入から描画までほとんど時間をかけずにできてしまいました。
今回は特にいじりませんでしたが、既存のコードをカスタムして色々できるみたいです。
あまりにもホイホイ描画できてしまうので、特にトラッキングが好きなタイプだとかなり夢が広がりそうです。

# 参考
https://vue-chartjs.org/guide/#introduction

https://www.chartjs.org/docs/latest/getting-started/integration.html