react-chart-js2で時刻同期グラフを作る

react-chart-jsはJS用のグラフ描画ライブラリChart.jsのreact用ラッパーライブラリです。
Chart.jsについては公式のドキュメントや技術記事が豊富に存在しますが、意外とreact-chsrt-jsでは記法が変わっていたりとややこしく、ひょんなことでハマってしまう事がありました。

例えば以下のようなデータをグラフ描画したい時
|時刻|14:30|14:31|14:35|14:36|14:38|14:39|14:40|
|---|---|---|---|---|---|---|---|
|温度|10℃|12℃|17℃|12℃|12℃|10℃|14℃|

単純にX軸Y軸に値を渡しただけだと以下のようなグラフになってしまいます
![スクリーンショット 2023-01-25 19.59.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729200/7d8f2fa4-48d4-1a03-2615-9ca4be60c69e.png)
横軸を時間にしているので時間が空いた所のデータはその分間隔をとって表示したいはずです。
そんな時には横軸にTimeScaleを導入して内部で時刻として認識させる必要があります。

Chart.jsの公式ドキュメントにもTimeScaleについての記述があります

https://www.chartjs.org/docs/latest/samples/scales/time-line.html
>
>~~~js
>const config = {
>  type: 'line',
>  data: data,
>  options: {
>    plugins: {
>      title: {
>        text: 'Chart.js Time Scale',
>        display: true
>      }
>    },
>    scales: {
>      x: {
>        type: 'time',
>        time: {
>          // Luxon format string
>          tooltipFormat: 'DD T'
>        },
>        title: {
>          display: true,
>          text: 'Date'
>        }
>      },
>      y: {
>        title: {
>          display: true,
>          text: 'value'
>        }
>      }
>    },
>  },
>};
>~~~


しかし単純にこれを設定しただけでは動作しません。
いくつか必要な工程があったので以下にまとめました。

# TimeScale適用方法
必要な工程は以下の三つです。
* 時刻アダプターライブラリの追加
* Chart.jsへTimeScaleを登録
* (config変数に設定を記述)

### 環境
react: 17.0.2
react-chartjs-2: 3.0.4
chart.js: 3.5.1
chartjs-adapter-date-fns: 2.0.0
date-fns: 2.29.3

:::note alert
少しでもバージョンが異なるとうまく動作しない可能性が高いのでご注意ください
:::
### 時刻アダプターライブラリの追加
以前まではmoment.jsが標準の時刻ライブラリとして備わっていたので必要なかったようですが、現在は「対応している時刻ライブラリから好きなの選んで自分で導入してねって感じみたいです。

一応公式にもちっちゃく載っています

https://www.chartjs.org/docs/latest/axes/cartesian/time.html

大体一般的なのはmomentかdatefnsなのでどちらか使うのがいいと思います。
・時刻ライブラリ
・Chart用時刻アダプターライブラリ
の二つを追加するのを忘れずに。

datefns使うなら以下の二つです。
https://date-fns.org/
https://github.com/chartjs/chartjs-adapter-date-fns

チャート描画するファイルでimportします。
~~~js
import 'chartjs-adapter-date-fns';
~~~以下略~~~
~~~

### Chart.jsへTimeScaleを登録
どういうこっちゃという感じですが、何やら時刻スケールは追加機能なのでモジュールに追加する必要があるようです。
そんなの公式に書いてないじゃん！と思いましたが、Chart.js的には常識なんでしょうか、なんとかstackOverFlowで見つけましたが、1時間くらい時間を無駄にしました...
詳しい解説は以下が参考になります。

https://zenn.dev/rinda_1994/articles/7e04702247f3e2

追記：今検索したら最近ドンピシャの記事が投稿されていたようです。

https://zenn.dev/decline/articles/cdcdb47145e0cc
~~~react
import {
  Chart as ChartJS,
  TimeScale,
// 省略、その他追加したいモジュール
} from "chart.js";

ChartJS.register(
  TimeScale,
// 省略、以下その他登録したいモジュール
);
~~~
こんな感じで使いたいモジュールをimportして、ChartJS.register()で登録します。

### config変数に設定を記述
ここまでやって初めて上で書いた設定の記述が動作するようになります。
scaleのtypeをtimeにして時刻の刻み方、時刻表記の指定を行います。
~~~js
const options = {
    scales: {
      x: {
        distribution: 'liner',
        type: 'time' as const,
        time: {
          unit: 'minute' as const,
          displayFormats: {
            minute: 'HH:mm'
          } as const,
        } as const,
      }
    }
  }
~~~
:::note warn
typescriptを使用する場合は設定値にas constと記述して定数であることを明示しないと自分の場合エラーになりました。
:::
timescaleの設定値についてのドキュメントリンクを貼っておきます。慣れるまで見辛い．．．

https://www.chartjs.org/docs/latest/axes/cartesian/time.html

### Tips: react-chart-js2でハマった際の抜け出すコツ
Chart.jsは非常に便利なライブラリでReact開発のグラフ描画アプリにおいてファーストチョイスにする人が多いと思いますが、以下の理由により初心者はとてもハマりやすいと思います。
* __Chart.jsとreact-chart-jsで"微妙"に書き方が違う部分がある"事がある"。__
この"微妙に"と"事がある"というのが厄介で、全く違う書き方であれば逆にやりやすいですが、同じ事もあればほんのちょっと違う事もあるので慣れていない人には罠になりやすいと思います。ラッパーライブラリなので仕方ないですが。

* __react-chart-js2の公式ドキュメントがあっさりしている__
これもラッパーライブラリなので仕方のないことかも知れませんが、Chart.jsに比べて圧倒的に情報量が少ないです。簡単なサンプルと設定値の羅列くらいしかありません。せめて素のChart.jsとの差異だったり注意点はもうちょっと詳しく書いてくれてもいいと思います...

* __バージョン違いで全く動作しない事がある。__
グラフ描画(と時刻の取り扱い)は内部的に複雑な処理になるのと頻繁に修正が行われているのでちょっとした差異で全く動かなくなるという事が頻繁に起こります。

* __設定ファイルにエラーが出ない__
これが自分的は一番辛かったです。グラフのラベルやスケール、プラグインの設定などconfig変数には大量の記述をしますが、動かしてみて分かるのは思った通りに表示されたか表示されていないか、のみです。どこの記述が悪いだったり、入力補完もありません。これが上記二つの要因と合わさってフロントエンド初心者、ひいてはグラフライブラリ初心者には地獄のような難易度になっていると思いました。

理解が浅い自分なりの所感ですが
これらになるべく立ち向かうためのコツは、何かカスタマイズを行いたくなったら
* __Chart.js公式ドキュメント→react-chart-js2公式ドキュメントの順で読む__
react-chart-js2の公式ドキュメントは貧弱なのでちょっとしたカスタマイズをしたい際に求めている情報はほとんど落ちていません。前述の通り設定値のエラーも出ないため心が折れて何も手が動かなくなってしまう可能性があります。
ちょっと遠回りですが、素のChart.jsではどのような実装になっているかを確認して根本的な仕様を理解しておく事ができると試せることが増えるのでまだ戦いやすくなります。

* __StackOverFlowを漁る__
前述の通り公式の情報量が少ないためピンポイントでの質問がたくさん投稿されています。全部英語ですが大体のことはこれで解決するので英語で検索をかけて翻訳に頼りましょう。
一見関係ないスレッドでも有用な情報が見つかることがあるので、上でも書きましたが根本の仕様を少しでも理解しておくと原因を抽象化してほしい情報を発掘しやすくなります。

* __CodeSandBoxを漁る__
これも意外と役に立ちました。エラーから原因を探ることができないため、CodeSandBoxにあるすでに動くことが保証されているもの中から自分の理想に近いコードを引っ張ってきて、そこからカスタマイズをしていくとうまくいったりします。その際バージョンにはくれぐれも注意してください

* __なるべく最小構成で__
色々とモジュールやプラグインを追加していくと相性が悪いのかうまく動作しないことがあります。原因の解明はかなり骨が折れるのでまずは最小構成で正常動作するか確認することをお勧めします。

以上です、参考になれば幸いです。