Chart.js v4でグラフの色とサイズを指定する方法【レスポンシブ対応・動くデモ付き】

結論:色はdatasetsの配列指定、サイズは親要素の高さで決まる

Chart.jsの色はbackgroundColor / borderColorに配列を渡すと、系列内のデータごとに別の色を割り当てられます。サイズはcanvas要素自体のwidth/heightではなく、親要素の大きさとmaintainAspectRatioで決まります。ここを混同すると「サイズを指定したのに効かない」というつまずきが起きます。

new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['A店', 'B店', 'C店', 'D店'],
    datasets: [{
      label: '売上',
      data: [420, 680, 310, 540],
      backgroundColor: ['#2B7FE8', '#FB923C', '#22C55E', '#A855F7'],
      borderColor: ['#1D4ED8', '#EA580C', '#15803D', '#7C3AED'],
      borderWidth: 1
    }]
  },
  options: {
    responsive: true,
    maintainAspectRatio: false // 親要素の高さを実際の描画高さにする
  }
});

実際に動くデモです。色の切り替えとサイズ変更を試せます。

デモ:色の配列指定と高さの変更

実装解説:色とサイズの各オプション

backgroundColor / borderColor(データごとの色)

単一の色(文字列)を渡すと系列全体が同じ色になりますが、配列を渡すとデータの要素数に合わせて1件ずつ色を割り当てられます。棒グラフや円グラフで項目ごとに色分けしたいときはこの配列指定を使います。配列の要素数がデータより少ない場合は先頭から繰り返し使われます。

datasets: [{
  data: [420, 680, 310, 540],
  backgroundColor: ['#2B7FE8', '#FB923C', '#22C55E', '#A855F7'], // 4件分
  borderColor: '#1D4ED8', // 単一指定なら全データ共通
  borderWidth: 1
}]

CSS変数と連携させる

サイトのテーマカラーとグラフの色を統一したい場合、JS側にハードコードせずgetComputedStyleでCSS変数の値を読み取って渡すと、CSS側の変更だけで見た目を揃えられます。

const styles = getComputedStyle(document.documentElement);
const primaryColor = styles.getPropertyValue('--color-primary').trim();

new Chart(ctx, {
  type: 'line',
  data: {
    datasets: [{
      data: [10, 20, 15, 30],
      borderColor: primaryColor || '#2B7FE8' // 取得失敗時のフォールバックも用意する
    }]
  }
});

CSS変数が未定義だったりtrim()忘れで空文字や前後の空白が残っていると、Chart.jsが色として解釈できず描画が崩れることがあります。フォールバック値を必ず用意し、取得した値はtrim()しておくと安全です。

maintainAspectRatio(アスペクト比の固定を解除する)

Chart.jsはデフォルトでmaintainAspectRatio: trueとなっており、縦横比(デフォルト2:1)を保ったまま描画します。この状態だと親要素の高さをCSSで指定しても、幅に対して比率通りの高さに強制的に調整されてしまいます。親要素の高さをそのまま使いたい場合はfalseにします。

options: {
  responsive: true,
  maintainAspectRatio: false // これがないと親のheightが無視される
}

親要素でサイズを制御する

responsive: true(デフォルト)かつmaintainAspectRatio: falseの組み合わせでは、Chart.jsはcanvasの親要素のサイズを監視して自動的にリサイズします。そのため、サイズ指定はcanvas自身ではなく親のdivにCSSで行います。

<div style="position: relative; height: 320px; max-width: 640px;">
  <canvas id="myChart"></canvas>
</div>

親要素にはposition: relativeも必須です。Chart.jsは内部でcanvasをposition: absolute相当のサイズ計算をしているため、親に位置指定の基準がないとレイアウトが崩れることがあります。

よくあるバリエーション・ハマりどころ

canvasにwidth/heightを直接指定しても効かない

<canvas width="600" height="300">のようにHTML属性で指定しても、responsive: true(デフォルト)の場合はChart.jsが描画のたびに親要素のサイズへ上書きしてしまいます。サイズを固定したいなら、responsive: falseにしてcanvas属性で指定するか、レスポンシブ対応のまま親divの高さで制御するかのどちらかに統一してください。両方を同時に使おうとすると意図と違う挙動になります。

グラフの高さがどんどん伸び続ける

親要素の高さをCSSで指定せず、親自身も中身の高さに合わせて広がる(height: auto相当)要素になっていると、canvasと親要素が互いの高さを参照し合って際限なく伸びていく現象が起きます。親要素にはheightを数値やvhで明示的に固定してください。

スマホ表示でグラフが潰れる・はみ出す

max-widthを指定していないと、画面幅いっぱいまで広がったcanvasの横幅に対して高さが極端に低く(または高く)計算されることがあります。親divにmax-widthを設定し、maintainAspectRatio: falseと固定heightの組み合わせで、画面幅に関わらず一定の高さを保つのが安定します。

症状 原因 対処
canvasにwidth/heightを書いたのにサイズが変わらない responsive: trueが親要素のサイズで上書きしている 親divのheightで制御するか、responsive: falseにする
親divにheightを指定したのに高さが反映されない maintainAspectRatio: true(デフォルト)が縦横比を優先している maintainAspectRatio: falseを追加する
ページを開くたびにグラフが縦に伸び続ける 親要素の高さが未指定でcanvasと高さを参照し合っている 親要素に固定のheightposition: relativeを指定する
色を配列で渡したのに全部同じ色になる 配列ではなく単一の文字列を渡している、または要素数が1件しかない データの件数分だけ色を配列で用意する

まとめ

Chart.jsの色はbackgroundColor / borderColorに配列を渡せばデータごとに変えられ、CSS変数と連携させればテーマカラーの変更にも追従します。サイズはcanvas自体ではなく、maintainAspectRatio: falseと親要素のheight / max-widthの組み合わせで決まります。「サイズを指定したのに効かない」ときは、まずcanvas属性ではなく親要素側を指定できているか、maintainAspectRatioがfalseになっているかを確認してください。

関連するUI事例

Chart.js v4を使ったグラフの実装例です。色とサイズの指定を実際のグラフで確認できます。

あわせて読みたい

Chart.js v4の実装Tipsをまとめています。