Vue.jsのchart.jsについてざっくりと解説

### はじめに

Chart.jsは便利ですね。凝ったグラフをサクッと作ってくれるので、
重宝すべきライブラリです。


### 最も簡単なサンプルを

QIitaの記事らしく、概要を総なめしてもいいのですが、まずは最小限のコード量でサンプルを描画しつつ、コードについて解析し、一般的な書き方に帰属していくことにしましょう。


```Chart.vue
<script setup>
import { ref, onMounted } from 'vue';
import { Chart, Title, Tooltip, Legend, BarElement, LineElement, PointElement, LineController, CategoryScale, LinearScale, PieController, ArcElement } from 'chart.js';
Chart.register(Title, Tooltip, Legend, LineElement, PointElement, LineController, CategoryScale, LinearScale, PieController, ArcElement);

const sample = ref(null);
onMounted(() => {
    if (sample.value) {
        const ctx = sample.value.getContext('2d');
        new Chart(ctx, {
            type: 'doughnut', // 円グラフを使用
            data: {
                labels: ["a","b","c","d","e"],
                datasets: [{
                    backgroundColor: ["red","orange","yellow","green","blue"],
                    data: ["30","20","30","40","50"],
                    borderWidth: 1
                }],
            },
            options: {
                cutout: '70%',
                plugins: {
                    legend: {
                        display: false
                    },
                    borderWidth: 0
                }
            }
        });
    }
});

</script>

<template>
    <div class="h-[100px] w-[100px] p-10">
        <div class="h-[100px] w-[100px]">
            <canvas ref="sample" style="width: 100%; height: 100%;" />
        </div>
    </div>
</template>

```

高々十数行のコードで下記の画像になります。
↓↓↓

![snip.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/75a958f1-41da-66bb-a2d2-fa9faa2dd568.png)

上記に紹介したものはdonuts chartというものですが、
もちろん、棒グラフや散布図、海抜グラフなどはデフォルトで入っていますし
マニアックなグラフもプラグインを入れれば描画できます。


### テンプレート部分

テンプレート部分は以下になります。

```javascript
<template>
    <div class="h-[100px] w-[100px] p-10">
        <div class="h-[100px] w-[100px]">
            <canvas ref="sample" style="width: 100%; height: 100%;" />
        </div>
    </div>
</template>
```

<div>要素は外側の大きさを決めるものであり、chartそのものには関係しないので無視します。

注目すべきはcanvasというHTML要素です。まさにチャートを描画するためのキャンバスであり、それ自体に高度な描画機能はありませんが、以下のような機能を有するそうです。
canvasには以下のような基本的な描画機能があります。
##### 図形の描画
矩形、円弧、線分などの基本的な図形を描画できます。
##### パス
複雑な形状をパスで記述し、そのパスに沿って描画することができます。
##### テキストの描画
任意の座標にテキストを描画できます。
##### 画像の描画
画像ファイルやビデオフレームをcanvas上に描画できます。
##### グラデーション
直線グラデーションや放射グラデーションなどを描画できます。
##### 合成設定
新しく描画する内容と既存の内容をどのように合成するかを指定できます。
##### 変形
canvas全体や一部を回転、拡大縮小、移動といった変形を加えることができます。

機能を組み合わせることで、canvasでインタラクティブな可視化やゲーム、画像編集アプリなどを作れるということです。当然、chartも例外ではありません。

### Script部分

javasctipt部分です。ここからが本題の機能の解説になります。

```javascript
import { Chart, Title, Tooltip, Legend, BarElement, LineElement, PointElement, LineController, CategoryScale, LinearScale, PieController, ArcElement } from 'chart.js';
Chart.register(Title, Tooltip, Legend, LineElement, PointElement, LineController, CategoryScale, LinearScale, PieController, ArcElement);
```

ここでは、chart.jsライブラリから様々なモジュールをインポートしていますが、どれも機能
各モジュールの役割は以下の通りです。

Chart: チャートを作成するための基本クラス。
Title: チャートのタイトルを設定するためのモジュール。
Tooltip: ツールチップ（データポイントにカーソルを合わせた際に表示される情報）を表示するためのモジュール。
Legend: チャートの凡例を表示するためのモジュール。
BarElement: 棒グラフの要素を表すモジュール。
LineElement: 線グラフの要素を表すモジュール。
PointElement: 線グラフや散布図のデータポイントを表すモジュール。
LineController: 線グラフを管理するためのコントローラ。
CategoryScale: カテゴリスケール（軸のラベルがカテゴリデータである場合に使用）を提供するモジュール。
LinearScale: 線形スケール（軸のラベルが数値データである場合に使用）を提供するモジュール。
PieController: 円グラフを管理するためのコントローラ。
ArcElement: 円グラフの要素を表すモジュール。

##### なぜこのような冗長な登録をしなければいけないか？

答えは、バンドルサイズを小さくし、パフォーマンスを最適化するためだそうです。
必要な機能のみを登録しないと、chart-jsの機能すべてを読み込んでしまい、応答速度の低下につながるとのこと。（ちなみにこのアップデートあChart.js3以降だそうで、それまではすべてをインポートしていたそうです。）

この調子で描いていきましょう。
```javascript
const ctx = sample.value.getContext('2d');
```

得られるのはcanvasに接触するコンテキストのインスタンスですが、canvasに2dのチャートグラフを描画するためのインターフェースを提供します。そして、のちに生成するchartインスタンスを生成する際に、第一引数としてコンテキストが渡されます。

ちなみに以下のようなものもあるそうです。
↓↓
##### WebGL コンテキスト ('webgl' または 'experimental-webgl'):
3次元のグラフィックスを描画するためのコンテキスト。
WebGL（Web Graphics Library）はOpenGL ES 2.0を基にしたAPIで、ハードウェアアクセラレーションを利用して高度な3D描画が可能。
ゲーム開発や科学技術計算、データ可視化などに使用される。

##### WebGL2 コンテキスト ('webgl2'):
WebGLの進化版で、より高度な3D描画と機能拡張が可能。
WebGL2はOpenGL ES 3.0をベースにしており、より多くのGPU機能にアクセスできる。
特に大規模な3Dアプリケーションやシミュレーション、ビジュアルエフェクトに適している。

### Config構成

configの中身が少しややこしい配列になっていますが、大まかには３つに分かれていてそれぞれの説明に対してはざっくりでいいなら完結に説明できます。

#### type
どのようなグラフのタイプかを指定できます。
pie/ doughnut / barなど

#### data
表示させるデータの値や凡例などの設定を行うことができます。
vueのコンポーネントとして使用したとき、だいたいここがpropsの内容になります。

#### options
透明度やボーダー、グリッドなどオプショナルな設定を担います。


### ファイルの外だし
configファイルがあまりにも長くなるようなら、また複数のチャートを描画する際にコードが冗長になりたくないなら、以下のような書き方で外だしすることも可能です。

```ChartJs.vue
<script setup>
import { ref, onMounted } from 'vue';
import { donutsConfig, barConfig,pieConfig } from '@/chart.config.js';
import { Chart, Title, Tooltip, Legend, BarElement, BarController, LineElement, PointElement, LineController, CategoryScale, LinearScale, PieController, ArcElement } from 'chart.js';

Chart.register(Title, Tooltip, Legend, LineElement, BarElement, BarController, PointElement, LineController, CategoryScale, LinearScale, PieController, ArcElement);

const charts = ref(null);
const charts2 = ref(null);
const charts3 = ref(null);

onMounted(() => {
        const ctx = charts.value.getContext('2d');
        const ctx2 = charts2.value.getContext('2d');
        const ctx3 = charts3.value.getContext('2d');
        new Chart(ctx, pieConfig());
        new Chart(ctx2, donutsConfig());
        new Chart(ctx3, barConfig());
});

</script>

<template>
    <span>　円グラフ</span>
    <div class="h-[300px] w-[300px] p-10">
        <div class="h-[200px] w-[200px]">
            <canvas ref="charts" style="width: 100%; height: 100%;" />
        </div>
    </div>
    <span>　ドーナツグラフ</span>
    <div class="h-[300px] w-[300px] p-10">
        <div class="h-[200px] w-[200px]">
            <canvas ref="charts2" style="width: 100%; height: 100%;" />
        </div>
    </div>
    <span>　棒グラフ</span>
    <div class="h-[300px] w-[300px] p-10">
        <div class="h-[200px] w-[200px]">
            <canvas ref="charts3" style="width: 100%; height: 100%;" />
        </div>
    </div>
</template>
```


```chart.config.js

//ドーナツグラフに関する設定
export const donutsConfig = () => {
    return {
        type: 'doughnut', // 円グラフを使用
        data: {
            labels: ["a", "b", "c", "d", "e"],
            datasets: [{
                backgroundColor: ["red", "orange", "yellow", "green", "blue"],
                data: [30, 20, 30, 40, 50], // 文字列から数値に変更
                borderWidth: 1
            }],
        },
        options: {
            cutout: '70%',
            plugins: {
                legend: {
                    display: false
                }
            },
            borderWidth: 0 // plugins の外に移動
        }
    };
};

//棒グラフに関する設定。
export const barConfig = () => {
    return {
        type: 'bar', 
        data: {
            labels: ["a", "b", "c", "d", "e"],
            datasets: [{
                backgroundColor: ["red", "orange", "yellow", "green", "blue"],
                data: [30, 20, 30, 40, 50], // 文字列から数値に変更
                borderWidth: 5
            }],
        },
        options: {
            cutout: '70%',
            plugins: {
                legend: {
                    display: false
                }
            },
            borderWidth: 0 // plugins の外に移動
        }   
    };
};

//円グラフに関する設定
export const pieConfig = () => {
    return {
        type: 'pie', 
        data: {
            labels: ["a", "b", "c", "d", "e"],
            datasets: [{
                backgroundColor: ["red", "orange", "yellow", "green", "blue"],
                data: [30, 20, 30, 40, 50], // 文字列から数値に変更
                borderWidth: 1
            }],
        },
        options: {
            plugins: {
                legend: {
                    display: false
                }
            },
            borderWidth: 0 // plugins の外に移動
        }   
    };

}
```

実際の描画
![charts.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/be07dd20-d445-49f8-1b58-e6e009c784d7.png)


### おわりに

型さえ定義してしまえば、あとはカスタマイズでいくらでも思い通りの仕様にできる（はず？）です。
また、拡張機能を入れることでデフォルトにない種類のチャートを描画することも可能です。