JavaScriptグラフ描画ライブラリ比較 - Chart.jsをやめた理由

はじめに

新卒2年目(もうすぐ3年目!)のエンジニア、宮西です。

現在、私が開発に携わっているプロダクトでは、グラフを使ってさまざまなデータを表示しています。 グラフ化の利点は、一目で要点を伝えられるところ。 開発中のプロダクトは分析系のサービスであるため、「分かりやすいグラフ」はとても大切な要素です。

今までは、Chart.jsというグラフ描画ライブラリを使って、これらの画面を作っていました。 しかし、より分かりやすくするために、高度な機能・柔軟なデザイン性が求められるようになりました。 その中で、Chart.jsでは対応しきれない部分がでてきたため、ライブラリの再選定を行うことになりました。 今回はその結果をお知らせしたいと思います。

技術選定に至った背景

やりたかったこと

今回作りたかったグラフは以下のようなものです。 f:id:miyanishi-yuki:20180319094555p:plain

具体的には、

  1. 折れ線グラフ・棒グラフ・積み上げ棒グラフおよび、これらの複合グラフを動的に描画する

  2. 複合グラフの場合、y軸が左右にあるグラフ(2軸グラフ)となる

  3. グラフの点とその周辺にマウスオーバーした際、そのグラフを強調して表示する

  4. 対象のグラフを太く、他のグラフを薄く表示する

  5. 対象の点の情報をツールチップで表示する

  6. カーソルに追従する縦線を引く

  7. グラフの中に任意の文字や絵文字を表示し、クリックした際にイベントを発火させる
  8. その他、細かなグラフのデザイン(たとえばx軸のラベルの文字間隔など)を調整する

なぜ、Chart.jsではできなかったのか

Chart.jsは、HTMLのcanvas要素にグラフを描画しています。 実際に、Chart.jsで描画されたグラフがどのようなHTMLで構成されているのかを見てみると、canvas要素しかありません。 まさに、キャンバスに描かれた絵のようなものです。 そのため、決められたオプション以外の動きやデザインの変更は不得意という欠点がありました。

上記の「やりたかったこと」の内、1,2はChart.jsでもできたのですが、3と4はChart.jsのオプションでは用意されていませんでした。 また、5についてはまさにChart.jsの不得意な分野でした。 少々強引な方法を使えば実現するものもありましたが、 別のグラフ描画ライブラリで簡単にできるのであればChart.jsに固執する必要はないと考え、 新しいグラフ描画ライブラリを探す決断に至りました。

比較した結果

結論

この技術選定の結果、Highcharts という有料のグラフ描画ライブラリを使うことに決めました。 以降で、比較したグラフ描画ライブラリについてと、比較結果を順を追って説明します。

選定候補のグラフ描画ライブラリ

今回選定を行ったグラフ描画ライブラリは以下の6種類です。

比較

最初に、比較に用いた記号の意味を説明します。

記号 説明
ドキュメントを読めば実装できる
可能だが、一工夫必要(許容できる範囲内)
可能そうだが、時間や手間がかかるので、なるべくやりたくない
× 許容できない手間がかかる

実際に比較した結果が以下の表です。

No. Chart.js Taucharts C3.js Google Charts amCharts Highcharts
1 折れ線グラフ・棒グラフ・積み上げ棒グラフおよび、これらの複合グラフを動的に描画する ×
2 グラフの点とその周辺にマウスオーバーした際に、そのグラフを強調して表示する - ×
3 カーソルに追従する縦線を引く -
4 グラフの中に任意の文字や絵文字を表示し、クリックした際にイベントを発火させる × -
5 その他、細かなグラフのデザインを調整する △ or ×

Chart.js以外のライブラリはSVGを用いています。 SVGでは、グラフの点や線、軸やラベルなどのグラフの要素が、HTMLの要素で表現されています。 つまり、ライブラリが用意したオプションで指定しなくても、グラフ描画後にCSSでデザインの調整ができます。 そのため、5のデザインの微調整については、Chart.js以外はすべて ○ という結果になりました。

Tauchartsは、2軸グラフのデザインに問題がありました。 2軸グラフにした際、y軸が左右に表示されるのではなく、左側に2つ軸が出てしまいました。 2つの軸が1か所にまとまって表示される状態は見にくく、要件を満たしていないと判断しました。 そのため、Tauchartsについてはその他の詳細な調査を行っていません。

C3.jsは無料のライブラリの中でも高機能で、ドキュメントも充実していました。 調査を始めた段階では第一候補として考えていたのですが、マウスオーバー時に発火するイベントで問題が見つかりました。 C3.jsのマウスオーバーイベント内では、「どのx軸上にカーソルがあるか」は特定できるようになっていました。 しかし、そのx軸上にあるグラフの内のどのグラフが選択されているのかは分かりませんでした。 そのため、2で挙げた「対象のグラフの強調」ができず、利用を諦めることになりました。

最終的に、要件を満たしたライブラリは3つありました。Google ChartsとamCharts、そしてHighchartsです。 その中でHighchartsを選んだ理由は、ドキュメントの充実度とオプションの充実度、そして調査時に感じた扱いやすさでした。

Google Chartsは要件を満たした唯一の無料ライブラリでした。 しかし、Google ChartsはHighchartsやamChartsに比べて、ドキュメントの充実度は劣ると感じました。 実際、サンプルコードで実装されていた機能を別のグラフで利用しようとした際に上手く動作せず、 さらにドキュメントを読んでも理由が分からずに困ったことがありました。

amChartsはHighchartsと同等の機能がありながら、Highchartsより安価でした。 ドキュメントというよりはサンプルが多く存在していました。ここで気になったのは、ドキュメントの見やすさです。 基本的にサンプルベースになっているのですが、オプションの書き方などを体系的に理解するのが難しく感じました。 オプションやイベントが体系的に説明されたページもあるのですが、今度はサンプルの数が減ってしまいます。 これは個人の好みだと思うのですが、Highchartsのように、体系的にまとまっている中にサンプルが豊富にちりばめられているドキュメントは理解しやすく、魅力的でした。

おわりに

以上の理由から、私のチームのプロダクトでは、新しくHighchartsを利用する運びとなりました。 今回の要件をすべて満たすライブラリはなかなか見つけられず苦労しました。

最後の3つにしぼられた時、Highchartsを使いたいという気持ちがありましたが、値段のこともあり少し躊躇していました。 そんな時、一緒にプロダクトを作っている事業部の担当者から、 「エンジニアの皆さんが使いやすいものを選んで欲しい。無料でも、安くても、使い勝手の悪いものを使って消耗したり、工数がかかってしまうことは望んでいない。」 と言ってもらえたことで、Highchartsに決めることができました。 先日、実際に画面作成でHighchartsを使ってみて、使いやすさや柔軟さを実感しました。 (好みなどもあると思うので、あくまで個人的な感想ですが…。) 改めて、使い勝手を重視して決定させてもらえたことに感謝しています。

この記事が、これからグラフ描画ライブラリを使いたいと思っているかたの参考になれば幸いです。