Vue.js+Chart.js(vue-chartjs)+Laravelでグラフを作成しました。 【#np2020】

このブログではこれまでFlashを使ったグラフを採用してきたのですが、ブラウザ側のFlashへの対応が厳しくなっている今、Flashじゃないよなあということでリニューアル後はJavaScriptによるグラフを採用することにしました。


で、その作業が一段落したので現行ブログの方も置き換え。


サンプル



こんな感じです。データは普段「内閣支持率」のグラフで使用しているもの。

インタラクティブに動きますが、これ、JavaScriptなんですよねえ。すごい。しかも自分ではほとんどコードを書くことなく実現出来てしまいます(データ取得部分を除く)。


以下、導入のポイントと参考になったサイトを。



ポイント:Vue.jsを導入している環境では「vue-chartjs」を入れると幸せになれます

Chart.js単体でも十分に便利なライブラリなんですが、「vue-chartjs」を使うとデータやオプションの受渡部分を全部任せてしまって、自分はデータとオプションの内容のことだけを考えれば良くなるのでとても楽です。

オプションの渡し方には若干癖があるのでそこだけ注意。

最初に | vue-chartjs



ポイント:グラフカラーを指定するのが面倒な人は「chartjs-plugin-colorschemes」を使いましょう

デフォルトではグラフごとに色を指定していく必要がありますが、このChart.js用プラグイン「chartjs-plugin-colorschemes」を使えば自動的に良い感じに配色してくれます。超素敵。

Chart.js のチャートを格段に綺麗に見せるカラーパレットプラグイン – nagix

ガイドでは「自分の好みのカラーパレットをschemeとして設定しましょう」とありますが、デフォルトの「brewer.Paired12」で良ければ何も設定しなくても綺麗に動きます(サンプルは指定無しです)。きちんとカラーチャートを見て設定すれば、「寒色系で」「暖色系で」「ビビッドに」といった印象にも出来ます。最高。

ちなみに、CDNで読み込んで使えると書いてありますが、それだと結構遅いです。npmでインストール出来るので、CDNで試して気に入ったらインストールして使うのがおすすめです。

chartjs-plugin-colorschemes – npm



ポイント:ラベルの範囲指定には対応していません

「内閣支持率」のグラフの場合毎月更新で、その月までのデータを表示しているので(2015年9月の記事には2,015年9月までのデータしかない)、ラベルの範囲指定が必要ですが、Chart.jsは基本的には「与えられたデータをグラフとして表示する」ことだけを機能としているので、ラベルの範囲設定はデータ側が行う必要があります。

このサイトの場合は、データを用意するAPIにラベル範囲を渡すことで対応しています。



ポイント:複数グラフを表示する場合でも全ラベルに対応した値の設定が必要

「内閣支持率」のグラフの場合、データがそれぞれの総理大臣の在任期間分しかありません。しかしラベルは全グラフ共通なので、そのままデータを渡すと全てが最初に偏ってしまうことになります。一方でデータが無い部分に「0」を入れるわけにも行きません。データが無くて「0」なのか、実際の値が「0」なのか見分けが付かないからです(「内閣支持率」のグラフの場合は問題なくても)。


正解は「値がない場合はnullを入れる」。


定義からするとNaNを入れるべきかも知れませんが、NaNはJSONに入れられないのでエラーが出るんですよね(直接データを指定する使い方ならNaNでOK)。なのでnullを入れています。

オプションの「spanGaps」がtrueになっている時は、nullは飛ばして間を自動的に補完してくれますが(例えば第1期安倍内閣と第2期安倍内閣のグラフが繋がる)、そうでなければnulの部分はグラフが表示されません。もしグラフを補完しながら表示させたい場合(例えば「ダイエットサボって計測していない期間がある体重グラフ」)は、計測していない期間の値をnullにした上で「spanGaps」をtrueにしましょう。



ポイント:グラフの縦幅はレスポンシブにしない

グラフの横幅はウィンドウサイズに合わせて伸縮する方が便利ですが、デフォルトだと縦横比が固定されているので、それに合わせて縦サイズも伸縮してしまいます。縦も横も小さくなるとグラフは全然見えないし、逆に全画面に拡大するとグラフが異常にデカくなってしまう。縦だけを固定することでこの問題を回避することが出来ます。

設定が必要なオプションは以下の通り:

responsive: true,
maintainAspectRatio: false,

レスポンシブを有効にしつつ、縦横の比率を固定にしない。これで横幅はレスポンシブ、縦幅は400pxで固定されます。もし他のサイズが欲しければCSSで指定してやることが出来ます。



まとめ

こんなところかな……テキストに書くと長いけど、実際にはほとんどやることはありません。開発時間のほとんどは、データを取得するAPIの開発と関連するLaravelのドキュメントを読むのに費やしました。

以下、参考にさせて頂いたサイトです。
(紹介済みのものを除く)


Line · Chart.js documentation
Laravel上でVue.jsとChart.jsを利用してグラフを描いてみる – Qiita
vue-chartjsでいろんなグラフを書いてみる – minminの備忘録
ChartJS:横幅だけをレスポンシブにして縦幅は指定したサイズで表示する | ハックノート
非数をJSONに入れようとするとどうなるか – Qiita