Chart.jsとは

Chart.jsは、HTMLの <canvas> 要素を使ってグラフを描画するJavaScriptライブラリです。

Canvasベースなので軽量かつ高パフォーマンスで、棒グラフ・折れ線・円グラフなど8種類のグラフを手軽に実装できます。MITライセンスで商用利用も無料です。

この記事では積み上げ棒グラフ(+折れ線の混合グラフ)に絞って、すぐ使えるコードを解説します。

    CDNで読み込む

    インストール不要で、HTMLに1行追加するだけで使えます。

    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    

    chart.js を読み込むと window.Chart としてグローバルに使えるようになります。フッターで読み込む場合は foot.php などに追記するだけでOKです。

    バージョンを固定したい場合https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.js のようにバージョン番号を指定します。本番サイトでは予期しないアップデートを避けるためバージョン固定が安心です。

    基本の構造

    グラフを表示するには <canvas> 要素と new Chart() の2つだけ必要です。

    <div style="position:relative; width:100%; height:340px;">
      <canvas id="myChart"></canvas>
    </div>
    
    <script>
    new Chart(document.getElementById('myChart'), {
      type: 'bar',       // グラフの種類
      data: { ... },     // データ
      options: { ... }   // オプション
    });
    </script>
    

    <canvas><div> で囲んで高さを指定するのがポイントです。<canvas> 自体にCSSで高さを指定すると崩れることがあるため、ラッパー側で高さを管理します。

    積み上げ棒グラフのコード

    以下は「自社商品売上」と「マーケットプレイス売上」を積み上げ、「営業利益」を折れ線(右軸)で重ねたサンプルです。

    <figure class="chart-wrapper">
      <!-- 凡例(HTMLで自作) -->
      <figcaption class="chart-caption fz-xs c-text-500">
        <span><i style="color:#005B92;">■</i>&nbsp;自社商品売上</span>
        <span><i style="color:#80A5C2;">■</i>&nbsp;マーケットプレイス売上</span>
        <span><i style="color:#D4963A;">●</i>&nbsp;営業利益(折れ線・右軸)</span>
      </figcaption>
    
      <!-- グラフ本体 -->
      <div class="chart-content mt-1r" style="position:relative; width:100%; height:340px;">
        <canvas id="ecChart"></canvas>
      </div>
    </figure><!-- ///.chart -->
    
    <script>
    new Chart(document.getElementById('ecChart'), {
      data: {
        labels: ['2020年', '2021年', '2022年', '2023年', '2024年'],
        datasets: [
          {
            type: 'bar',
            label: '自社商品売上',
            data: [1820, 1950, 2100, 2280, 2410],
            backgroundColor: '#005B92',
            stack: 'sales',          // ← 同じ名前で積み上がる
            yAxisID: 'y',
            order: 2,
            barPercentage: 0.5,
            categoryPercentage: 0.6
          },
          {
            type: 'bar',
            label: 'マーケットプレイス売上',
            data: [2050, 2340, 2980, 3640, 4820],
            backgroundColor: '#80A5C2',
            stack: 'sales',          // ← 同じ名前で積み上がる
            yAxisID: 'y',
            order: 2,
            barPercentage: 0.5,
            categoryPercentage: 0.6
          },
          {
            type: 'line',
            label: '営業利益',
            data: [350, 390, 510, 580, 650],
            borderColor: '#D4963A',
            backgroundColor: '#D4963A',
            pointRadius: 5,
            borderDash: [5, 3],      // 破線
            yAxisID: 'y2',           // 右軸に紐付ける
            order: 1
          }
        ]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        interaction: {
          mode: 'index',             // ← 同じX位置の全系列をまとめて表示
          intersect: false
        },
        plugins: {
          legend: { display: false } // ← デフォルト凡例を非表示
        },
        scales: {
          y: {
            stacked: true,           // ← これがないと積み上がらない
            position: 'left',
            min: 0,
            max: 8000,
            ticks: {
              callback: v => v.toLocaleString() + '万'
            }
          },
          y2: {
            position: 'right',
            min: 0,
            max: 1000,
            ticks: {
              callback: v => v.toLocaleString() + '万'
            },
            grid: {
              drawOnChartArea: false // ← 左軸グリッドと重複させない
            }
          }
        }
      }
    });
    </script>
    

    よく使うカスタマイズ

    積み上げに必要な2つのセット

    積み上げ棒グラフで忘れがちなのが、stackstacked両方の指定です。片方だけでは正しく積み上がりません。

    // datasetsの各barに指定
    stack: 'sales'
    
    // optionsのscales.yに指定
    y: { stacked: true }
    

    棒の幅を調整する

    barPercentagecategoryPercentage の2つを全barデータセットに同じ値で指定します。

    barPercentage: 0.5,      // カテゴリ内の棒の幅(0〜1)
    categoryPercentage: 0.6  // カテゴリ全体に対する占有率(0〜1)
    
    barPercentage categoryPercentage 見た目
    0.8 0.8 デフォルト(太め)
    0.5 0.6 中細
    0.3 0.5 細め

    どちらか一方だけ変えても効果が薄いので、2つセットで調整します。

    軸に単位を付ける

    ticks.callback で軸ラベルに単位を追加できます。

    ticks: {
      callback: value => value.toLocaleString() + '万'
    }
    

    toLocaleString() を使うと、20002,000万 のようにカンマ区切りにもなって見やすくなります。

    右軸のグリッド線を非表示にする

    右軸を追加すると左軸と二重にグリッド線が表示されます。drawOnChartArea: false で右軸側のグリッドを非表示にします。

    y2: {
      position: 'right',
      grid: {
        drawOnChartArea: false
      }
    }
    

    ツールチップをカスタマイズする

    interaction.mode: 'index' にすると、ホバー時に同じX位置の全系列をまとめて表示できます。

    interaction: {
      mode: 'index',
      intersect: false
    },
    plugins: {
      tooltip: {
        callbacks: {
          label: ctx => `${ctx.dataset.label}: ${ctx.parsed.y.toLocaleString()}万円`
        }
      }
    }
    

    デフォルト凡例を非表示にする

    Chart.jsのデフォルト凡例は丸アイコンで見た目がいまいちです。legend.display: false で非表示にして、HTMLで独自の凡例を作る方が柔軟に見た目を整えられます。

    plugins: {
      legend: { display: false }
    }
    

    まとめ

    Chart.jsで積み上げ棒グラフを作るときのポイントをまとめます。

    • stack の名前を揃える + scales.y.stacked: true両方が必要
    • 折れ線との混合は dataset単位で type を指定するだけ
    • 右軸は yAxisID で紐付けて scales に追加する
    • 棒の太さは barPercentagecategoryPercentage で調整(全bar系列に同じ値を)
    • 凡例はデフォルトを非表示にしてHTMLで作る方が柔軟
    • 軸ラベルは ticks.callback で単位付きにできる