chart.js でグラフの出力

## 準備
### 知識
HTML,JSの超基礎
CSSを知っているとグラフのデザイン設定がしやすいです。

### CDNの追加
※CDNはファイルをインストールしないでもURLにアクセスするだけでchart.jsが使えるようになるよ〜ってやつです。
chart.jsのファイルをローカルにインストールしてそのパスを辿っても実装可能です。

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

こちらより最新のCDNを読み込むだけでOK！
一応コピペできるように載せておきます。

``` html
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
```

## 実装
### 基本
JSでは以下の3つをを設定してあげればOK！
1. グラフの指定(type)
1. データの入力(data)
1. 詳細設定（optioons）


``` html
<!-- ここにグラフが表示 -->
<canvas id="myChart"></canvas>

<script>
  const type; //何グラフかの指定
  let data;　//データ
  let options;　//色々な設定
  const ctx = document.getElementById("myChart").getContext("2d");//表示する場所取得

//ここで今までの設定した値を出力
  const myChart = new Chart(ctx, {
    type: type,
    data: data,
    options: options
  });
<script>
```
### 基本的な折れ線グラフ
![スクリーンショット 2021-08-13 21.14.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/e6b2e8d3-b58f-49bb-e46c-01f7b1538d3a.png)

``` html
<canvas id="myChart"></canvas>
<script>
    const type = "line";
    let data = {
        labels: [2010, 2011, 2012, 2013],
        datasets: [{
            label: "@taguchi",
            data: [120, 300 , 100, 100]
        }]
    }
    let options;
    const ctx = document.getElementById("myChart").getContext("2d");

    const myChart = new Chart(ctx, {
        type: type,
        data: data,
        options: options
    });
</script>
```

### 2つ以上のデータがある折れ線グラフ
![スクリーンショット 2021-08-13 21.17.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/4c742661-f773-9fed-310b-6f17e4702147.png)

``` html
<canvas id="myChart"></canvas>
<script>
    const type = "line";
    let data = {
        labels: [2010, 2011, 2012, 2013],
        datasets: [{
            label: "@taguchi",
            data: [120, 300, 100, 100]
        }, {
            label: '@fkoji',
            data: [180, 250, 320, 180]
        }]
    }
    let options;
    const ctx = document.getElementById("myChart").getContext("2d");

    const myChart = new Chart(ctx, {
        type: type,
        data: data,
        options: options
    });
</script>
```
### optionsで縦軸をいじる
先ほどまでのoptionsに追加で値を入れます。
やりたいこと

1. 最大最小値の設定
1. 軸の刻みを100に設定
1. 軸の数値の前に単位を設定

![スクリーンショット 2021-08-13 21.30.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/a89d8988-0218-9544-c566-7d4528f1b853.png)

``` javascript 
let options = {
    scales: {
        yAxes: [{
            ticks: {
                //この範囲より大きいデータが入ったらはみ出てしまう
                // min: 0,
                // max: 400,
                suggestedMin: 0,
                suggestedMax: 400,
                stepSize: 100,
                callback: function(value, index, values) {
                    //value: index番目の値
                    //index: 何番目か
                    //value: 全ての値
                    return 'JPY' + value;
                }
            }
        }]
    }
};
```

### グラフのデザインを変更する
上の例で出しているtaguchiさんのグラフデザインを変えていきます.

1. 線の色を赤色
1. 線を5px
1. 背景を青
1. 直線に変更
1. 点を三角に変更

全てデータにまつわるもので、グラフのデータごとにデザインを変えたいものなのでoptionではなくdataにスタイルを記述します。

![スクリーンショット 2021-08-13 23.00.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/319473c7-d04d-f80c-0883-26d6c0b41490.png)

``` javascript
let data = {
    labels: [2010, 2011, 2012, 2013],
    datasets: [{
        label: "@taguchi",
        data: [120, 300, 100, 100],
        borderColor: 'red',
        borderWidth: 5,
        backgroundColor: 'rgba(0, 0, 255, 0.3)',
        // fill: false,
        //背景をなくしたい場合はfillをfalseに設定
        lineTension: 0,
        pointStyle: 'triangle'
    }, {
        label: '@fkoji',
        data: [180, 350, 320, 180]
    }]
};

```

### 棒グラフを作成
グラフのタイプを選択する際はtypeの修正ですね

```javascript
const type = "bar";

//横棒グラフ
const type = 'horizontalBar';
```

### 積み上げグラフを作成
棒グラフかつ,全てに適応させたいので変更する箇所はoptionsですね

![スクリーンショット 2021-08-13 23.14.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/6422f7cb-a8d0-c4f7-0fcc-2b6f8ee328c8.png)

``` javascript
let options = {
    scales: {
        yAxes: [{
            ticks: {
                //この範囲より大きいデータが入ったらはみ出てしまう
                // min: 0,
                // max: 400,
                suggestedMin: 0,
                suggestedMax: 400,
                stepSize: 100,
                callback: function(value, index, values) {
                    //value: index番目の値
                    //index: 何番目か
                    //value: 全ての値
                    return 'JPY' + value;
                }
            },
            stacked: true
        }],
        xAxes: [{
            stacked: true
        }],
    }
};

```

###　混合グラフの作成
棒グラフと折れ線グラフの混合グラフを作っていきます。
今回は全体を棒グラフ、個別（fkoziさん）を折れ線グラフにします。
全体のタイプはいじることなく,fkojiさんのdataをいじってあげればできそうですね。

![スクリーンショット 2021-08-13 23.22.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/c96fc7f3-178f-2793-c64d-ba184d110b1f.png)

``` javascript
const type = "bar";
let data = {
    labels: [2010, 2011, 2012, 2013],
    datasets: [{
        label: "@taguchi",
        data: [120, 300, 100, 100],
        borderColor: 'red',
        borderWidth: 5,
        backgroundColor: 'rgba(0, 0, 255, 0.3)',
        lineTension: 0,
        pointStyle: 'triangle'
    }, {
        label: '@fkoji',
        data: [1800, 3500, 3200, 1800],
        //この下2行を追加
        type: "line",
        fill: false
    }]
};
```

ただ、このままだとグラフがかなり見にくくなってしまうので、棒グラフの縦軸と、折れ線グラフの縦軸の値を変えてあげた方が良さそうですね。
それぞれのdataの縦軸にIDを指定して実装しましょう。


![スクリーンショット 2021-08-13 23.30.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/031f8a3b-f27f-c289-8fcd-36f0519ed018.png)

``` javascript
const type = "bar";
let data = {
    labels: [2010, 2011, 2012, 2013],
    datasets: [{
        label: "@taguchi",
        data: [120, 300, 100, 100],
        borderColor: 'red',
        borderWidth: 5,
        backgroundColor: 'rgba(0, 0, 255, 0.3)',
        lineTension: 0,
        pointStyle: 'triangle',
        yAxisID: 'taguchi-axes'
    }, {
        label: '@fkoji',
        data: [1800, 3500, 3200, 1800],
        type: "line",
        fill: false,
        yAxisID: 'fkoji-axes'
    }]
};

let options = {
    scales: {
        yAxes: [{
            ticks: {
                suggestedMin: 0,
                suggestedMax: 400,
                stepSize: 100,
                callback: function(value, index, values) {
                    return 'JPY' + value;
                }
            },
            id: 'taguchi-axes',
            type: 'linear',
            position: 'left'
        },{
            ticks: {
                suggestedMin: 0,
                suggestedMax: 2000
            },
            id: 'fkoji-axes',
            type: 'linear',
            position: 'right',
            gridLines: {
                display: false
            }
        }]
    }
};
```

### レーダーチャートの作成
基本は今までと同じです。
まずグラフのtypeを「radar」へ変更。
そして、縦軸と横軸という概念がなくなり1事件になるのでoptionsの書き方が楽になりますね！
表示するデータも少し変えるので今回は「type,data,options」の3セット書き換えます！

![スクリーンショット 2021-08-13 23.41.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/7b01a43d-9474-950b-c390-e8a16d16eab3.png)

``` JavaScript
const type = "radar";
let data = {
    labels: ['PHP', 'Ruby', 'Python', 'JavaScript', 'HTML'],
    datasets: [{
        label: '@taguchi',
        data: [40, 50, 70, 30, 80],
        backgroundColor: 'rgba(255, 0, 0, 0.3)'
    }, {
        label: '@fkoji',
        data: [90, 62, 34, 80, 48],
        backgroundColor: 'rgba(0, 0, 255, 0.3)'
    }]
};

let options = {
    scale: {
        ticks: {
            // suggestedMin: 0,
            beginAtZero: true,
            suggestedMax: 100
        }
    }
};
```

### 円グラフ
まずグラフのtypeを「pie」へ変更。
dataも少し変えてあげて
optionsはなにも指定しなくていいので1番楽ちん！

![スクリーンショット 2021-08-13 23.45.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/b881d59b-c9ef-d433-40cf-85b07aa397aa.png)


```JavaScript
const type = "pie";
let data = {
    labels: ['YES', 'NO', 'Maybe'],
    datasets: [{
        data: [122, 53, 33],
        backgroundColor: ['tomato', 'skyblue', 'gray']
    }]
};

let options = {};
```

ここまでで基礎は以上！
自分はドットインストールで基礎をざっと見ましたが、他にもドーナッツ型のグラフや細かい設定も講義にありました！
なのでより技術を高めたい人は見てみてもいいかもしれませんね！

今回ドキュメントにしたのは、今制作している販売管理システムでグラフの出力をしたいからです。
正解かは分かりませんが`「サービスの肝となる技術は基礎をサラッと全体的に学んでその後必要な技術を付け足す。」`とういう作業を毎回やっています。

そこで、これ以降は現在開発中のサービスで必要な要素をピックアップしていくのでかなりニッチな内容になると思います。
## 結構細かい開発
### x軸の値を任意の値の時のみ表示
たとえばx軸が1月〜12月の時軸の表示は2ヶ月に1回でいいんだよな〜って時ですね！

![スクリーンショット 2021-08-14 1.44.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/77e01b81-259a-f037-4513-9347fb25bed3.png)

maxTicksLimitがポイント。
今回はlabelsが12個あるので6で割ってあげると2個ずつ出力されますね！


``` JavaScript
let data = {
    labels: [0,1,2,3,4,5,6,7,8,9,10,11,12],
    datasets: [{
        fill: false,
        label: "店舗A",
        data: [120, 300, 100, 100, 100,100,100,100, 20, 30, 100, 20, 100],
        borderColor: 'red'
    }, {
        fill: false,
        label: '店舗B',
        data: [180, 250, 320, 180, 10, 200, 200, 200, 200, 300, 100, 20, 100]
    }]
}
let options = {
    scales: {
        yAxes: [{
            ticks: {
                suggestedMin: 0,
                suggestedMax: 400,
                stepSize: 100,
                callback: function(value, index) {
                    return 'JPY' + value;
                }
            }
        }],
        xAxes: [{
            ticks: {
                maxTicksLimit: 6,
                callback: function(value) {
                    return  value + "月";
                }
            }
        }]
    }
};
```

個人的に表示させたい数になるように割った値を計算しないといけないってのが、しっくりこないので関数をうまく使ってあげて、軸に何個表示させる値を作るかを記入するだけでいいようにする

2回に1回軸を表示させるときはsetpに「2」と指定するだけで良くなりますね！
※ここはエンジニアの好みが分かれるところですね！
※自分の前職の現場はstepのような数を指定する定数は大文字という規則だったので正確にはCUT_STEP_NUMとかが変数名としては好まれるのかな？？


``` JavaScript
//これを追加
const step = 2;
function tickCounts(data, step) {
    return Math.round(data.labels.length / step);
}

//これに書き換える
maxTicksLimit: tickCounts(data, step),
```

### コールバック関数使った方が綺麗にx軸のメモリを消せる
labelsの数が偶数このときは中央値がぴったり出てこないので、両端に値を出力すつことを考えるとうまく表示できないことを知ってしまいました。

![スクリーンショット 2021-08-14 2.24.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/a3405744-53d9-08ee-0ceb-c5d3aad3cf89.png)

そこで表示の制御をコールバック関数で管理します。

``` JavaScript
xAxes: [{
    ticks: {
        callback: function(value, index, values) {
            if (index % 2 === 1) {
                return "";
            }
            return value;
        }
    }
}]
```
そうすると綺麗に奇数の時のみ表示されていい感じになりました。
![スクリーンショット 2021-08-14 2.28.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615043/04ea3ef8-4037-cffe-d383-120da18c7271.png)



## 参考

・ドットインストール(https://dotinstall.com/lessons/basic_chartjs)