Chart.js でレスポンシブ指定をするとサイズが自由に変更できなくなる

両刃の剣であるレスポンシブ指定

Chart.js はグラフをWebページ上に描画するために大変便利なツールです。そしてレスポンシブ指定ができる(options で responsive: true と指定するだけ)ので、画面の大きさに応じたサイズにグラフを自動でリサイズしてくれます。スマホ対応も簡単。

…という甘い話ではありませんでした。レスポンシブ指定をすると canvas タグのサイズ指定は無効になり、Webブラウザの横幅を基準として一定の比率を維持したままグラフが表示されます。このため、スマホで見るとちょうどよくてもPCで見ると大きすぎる、あるいはその逆ということが起こります。

棒グラフ(type: 'bar')での対応方法

棒グラフの場合は、「PCで見ると大きすぎる」ということが起こります。仕方がないので canvas タグを div タグでくくって style 指定をしてやります。style 指定の中にレスポンシブな内容を埋め込んで、グラフの表示サイズを指定してやるという感じです(何だか本末転倒な感じもしますが…)。

<div class="chart_container">
  <canvas id="myChart" width="320" height="360"></canvas>
</div>

<style>
@media screen and (min-width: 768px) {
  .chart_container {
    width: 640px;
    margin: auto;
  }
}
</style>

円グラフ(type: pie)での対応方法

円グラフの場合は、「スマホで見ると小さすぎる」ということが起こります。この原因は「ラベル」(各項目の名称と色を対応させて説明している部分)のフォントが大きすぎることが原因なので、スマホの場合にそのフォントを小さくすることを考えます。

そのためには options の指定をレスポンシブで変更します。JavaScript の分岐で対応します。JavaScript による分岐なので、厳密にはレスポンシブではありません。動的にサイズが変わるわけではなく、再読み込みをして初めてサイズが適用されます(実用上は問題ないでしょう)。

if (window.matchMedia('screen and (min-width:768px)').matches) {
  //768px以上のデスクトップでの処理
  var options = {
    // 略

    legend: {
      labels: {
        boxWidth: 20,
        fontSize: 12 // PC用
      }
    }

   // 略
  };
} else {
  //スクリーンサイズが768pxより小さい時の処理
  var options = {
    // 略

    legend: {
      labels: {
        boxWidth: 20,
        fontSize: 8 // スマホ用
      }
    }

   // 略
  };
}

どちらもやや対症療法的

レスポンシブ指定したものを style で上書きしてレスポンシブ再指定、みたいなことをやっているのであまり望ましい方法ではないと思います。Chart.js 側でもうちっといろいろ対応してくれると嬉しいですね。

Powered by はてなブログ