JavaScript: Chart.jsでグラフ描画にトライした話

初めまして、18卒で入社したWebチームのコヤマです。
先日公開した、ベトナム開発拠点のLPのコーディングを担当しました。
その際にグラフの描画に使用したChart.jsで、「あれれ~?」「どうやるんだ?」って疑問解消してたら完成した話です。

※Chart.jsの導入と、公式ドキュメントでサクッと出来る内容は割愛してます。

Chart.jsとは

こだわらなければ、簡単に綺麗なグラフが描画できます。
大抵の事は、ドキュメントに書いてあるので↓参照


chartjs.orgより

今回バージョンは、Chart.js Ver.2.7.2を使用します。

ドーナツチャートを用意して試行錯誤

初期状態

左がデザインチームからいただいたデザインで、右は公式ドキュメントからコピペして描画したグラフです。

公式ドキュメントを読みながら近づけていく。

var labelplugin = {
  afterDatasetsDraw: function (chart) {
    // ラベルのフォントやサイズや、位置を指定する
  }
}

var ctx = document.getElementById("doughnut-canvas").getContext('2d');
var myDoughnutChart = new Chart(ctx, {
  type: 'doughnut',
  data: {
    datasets: [{
      data: [55, 30, 10, 5],
        backgroundColor: ['#FFC20F','#172343','#DCE9F5','#EDF4FA']
     }],
  },
  options: {
    cutoutPercentage: 76,  // 円の中心からどのくらい切り取るか
    animation: { animateRotate: false },
    tooltips: { enabled: false }
  },
  plugins: labelplugin,
});

色やアニメーションなどは、それっぽいプロパティ名の部分を変えて.
一先ず既存のラベルは消して、afterDatasetsDrawというプラグインを使用してラベルを用意。
公式サイトでもいくつかプラグインが紹介されています、拡張は容易ですね。

鬼門①白の枠線が消えない

デフォルトで、白で縁取りがされています。。。
こういう地味なのは、ドキュメントにわざわざ書くほどのことでもないので少し焦ります。
とりあえず、こんな感じかなと思いつきを…試すのみ。

試したこと

  • 枠線の幅の値を0にしてみた: borderWidth: 0
  • 枠線の色を透明にしてみた: borderColor: 'transparent'

結果

  • どちらも、枠線が消えた。
    (感覚的に言うと、空白を詰められた感じがします)

サクッとできてしまいました__orz

※ついでにセンターの文字は、一番簡単にCSSに#doughnut-area::beforeで挿入

鬼門②レスポンシブにしてみる

まず、公式ドキュメントに書いてある通りにオプションを指定してみます。

options: {
  responsive: true,
  maintainAspectRatio: true
}

結果

残念ながら、このままだと幅を縮めていくとグラフが大きくなりすぎました。

アスペクト比を維持したままだと都合が悪いのでmaintainAspectRatio: falseに変えます。

responsive: trueは、親要素のサイズに依存します。
が、幅は親要素に合わせてはくれなかったので、横スクロールが発生しました。

幅を指定すれば、いけそうな気もしますが今回は画面サイズに合わせた可変なグラフを描画したいので、とりあえず思いついた再描画の手順を試してみます。

画面サイズが変わったら再描画してみる

$(window).on('load resize', function () {
  draw();
});
function draw() {
  var myDoughnutChart = new Chart(ctx, {
    // グラフの描画
  }
}

結果

  • 画面サイズに合わせてグラフの描画が出来ている?
  • 前に描画したグラフが残り続ける

半分正解みたいです。となったら簡単、前に描画したグラフは削除しましょ。

既存のグラフは削除して再描画

// 画面リサイズ時に読み込む
$(window).on('load resize', function () {
  draw();
});
function draw() {
  // myDoughnutChartが残ってたら消す
  if (myDoughnutChart) {
    myDoughnutChart.destroy();
  }
  var myDoughnutChart = new Chart(ctx, {
      // グラフの描画
    }
}

完成

正直、もっと良い方法はあるので、これは随時データが変わる場合とかに使うのが好ましいかと。

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

コヤマ

2018年4月新卒入社/ものぐさタイプ。Webチームにいます。

コヤマの書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ