【React】チャートライブラリ比較してみた

## はじめに
下記のチャートライブラリを色々と触ったので、僕の調べたことをまとめとして置いておきます。
他に確認したい事があれば、末尾に比較用・確認用のコードも置いているので、良ければご利用ください。
(2021/03/09時点に確認したものです。情報が変わっているかもしれませんので参考までに。)

#### 確認したチャートライブラリ
- [Recharts](http://recharts.org/en-US)
- [react-chartjs-2](https://github.com/reactchartjs/react-chartjs-2)
- [ApexCharts](https://apexcharts.com/docs/react-charts/#)

作成できるグラフの種類や基本的な使い方は公式で確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171582/032d8e67-84c8-f024-0e5b-bc41ac9ca404.png)

## 調査まとめ

### 前提条件
- 比較のため、棒×2、線×1という少し複雑なグラフで固定しています。
- 数値計算というよりかは、業務利用想定なので各グラフにdataLabel(数値ラベル)出してます。

### npm trends
Download数やstars, issuesの数が出てきます。

https://www.npmtrends.com/recharts-vs-apexcharts-vs-react-chartjs-2

### 調査内容
| 調査項目 | Recharts | react-chartjs | Apex Charts |
| :--- | :---: | :---: | :---: |
| 【Biaxial Chart】データの記述 | 簡単 | 簡単 | 少し面倒 |
| 【Biaxial Chart】複数y軸の罫線 | 揃う | ごちゃつく | 揃う |
| 【DataLabel】表示 | できる | できる([要plugin](https://chartjs-plugin-datalabels.netlify.app)) | できる |
| 【DataLabel】重なり時 | そのまま重なる | 片方のdatalabelを自動で消せる | そのまま重なる |
| 【Legend】系列データの表示・非表示 | 少し実装が必要 | できる | できる |
| 【Legend】大量の系列を画面崩れなく表示できるか | style指定でできる | 要実装 | できる |
| 【Legend】初期表示時に系列を非表示状態にする | できる | できる | 静的にやるのは難しそう |
| 【Legend】系列の順番で重ねて描画 | される | されない(逆順になる) | される |
| 【Others】グラフ領域の拡大・縮小 | 多分できない | 多分できない | できる |
| 【Others】チャート画像のExport | [plugin](https://www.npmjs.com/package/recharts-to-png)あるが要実装 | 少し実装が必要 |できる |

※ここでの『できる』は、特別実装なくできることを指します。また、公式のDOCにやり方が載ってます。
※『多分』とか書いてるやつはちゃんと見てないので、見てから更新します。

### 褒めポイント
- Rechartsが細かいところの融通が効く。(軽く実装して細かいことを実現できる余地が結構ある)
- 単純でよいならdataとoption渡すだけで描画できる、chartjsが楽そう。
- 高機能で描画キレイにやりたいならApexChartsがよさそう。

## 調査詳細
調査まとめにて、「できない」or「条件付きできる」ものについて、
詳細を記載します。

### 【Biaxial Chart】(複数y軸)
##### データの記述
Apex Charts ... データとy軸を1対1になるように記述しなければならないので、
jsonの記述が面倒。

##### 複数y軸の罫線
react-chartjs ... y軸が右と左にあるとき、横のGridLineがそれぞれで描画される。
揃えたいとなると、スケールや区切り幅を色々調整する必要がありそう。

### 【DataLabel】(グラフ上の数値ラベル)
##### 重なり時
react-chartjs ... 数値ラベルが重なったら、片方消すという処理をしてくれるオプションがある。

### 【Legend】(系列まわり)
##### 表示・非表示の切り替え
Recharts ... 下記のような追加実装が必要。

https://codesandbox.io/s/recharts-with-legend-toggle-dqlts

僕のコードでは上記を参考にReduxっぽく実装してます。

##### 大量の系列を画面崩れなく表示できるか
Recharts ... Legendのstyleにoverflow:autoを追加するとスクロールできる
react-chartjs ... legendを実装し直さないと無理そう
Apex Charts ... 実装なしでいい感じにスクロールできる

##### 初期表示時に系列を非表示状態にする
Recharts ... 該当のComponentにhide=true指定することで可能
react-chartjs ... datasetsにhidden=trueを指定することで可能
Apex Charts ... [hideSeriesのメソッド](https://apexcharts.com/docs/methods/#hideSeries)をどこかで呼ぶ必要がある

##### 系列の順番での描画
react-chartjs ... 「orderの順番 = 系列の順番かつ、orderの順番が若いほど手前(z-indexが大きいほう)に描画される仕様」なので、
気になる人は気になるかもしれない。

### 【Others】(その他)
##### チャート画像のExport
Recharts ... [recharts-to-pngのplugin](https://www.npmjs.com/package/recharts-to-png)の推奨されているやり方だと空のPNGがでてくる。
下記曰く、どうやらRechartsのVer2だと問題が起こるそう。

https://github.com/brammitch/recharts-to-png/issues/64

ちなみにdeprecatedのやり方で出力できるかは試してない。

react-chartjs ... [それ用のメソッド](https://www.chartjs.org/docs/latest/developers/api.html#tobase64image)があるので、利用すればできそう。

Apex Charts ... 何もしなくても右上にPNGでExportするボタンが付いてきます。高機能。

## テストコード
https://codesandbox.io/s/reactchartlibrarytest-civtt

※動作確認程度に作ってるのでリファクタしてないです。ご了承ください。