棒グラフ(Bar Chart)— 縦棒・横棒 2パターン

グラフ・チャート 初級

このコンポーネントについて

棒グラフは月次売上・部門別比較・アンケート集計など、カテゴリーごとの数値を比較するのに最も適したグラフです。 このページでは Chart.js v4(CDN)を使い、外部の JSON ファイルからデータを fetch して描画する実装を紹介します。 データをグラフコードから分離することで、デザインを変えずにデータだけを差し替えられる保守性の高い構成になります。

  • Pattern 1 — 縦棒グラフ(単一系列) — 月別サイト訪問者数を縦棒で可視化。1系列のシンプルな構成で、売上・アクセス数・件数などの推移把握に使いやすい
  • Pattern 2 — 横棒グラフ(複数系列) — 部門別の予算と実績を横棒で比較。indexAxis: 'y' を指定するだけで縦棒から切り替え可能。ラベルが長い場合は横棒の方が読みやすい

実装のポイント・注意点

Chart.js v4 は UMD ビルドchart.umd.min.js)を CDN から読み込むと、グローバルに Chart クラスが使えるようになります。以前の v2/v3 からバージョンが上がっているため、古いサンプルをそのまま流用するとオプション構造の違いでエラーになることがあります。特に 横棒グラフの指定方法 が変わっており、v3 以前の type: 'horizontalBar' は廃止され、v4 では type: 'bar'options.indexAxis: 'y' を加える書き方が正しい形です。

JSON fetch でデータを取得する際、fetch同一オリジン または CORS を許可したサーバーからしか読み込めません。ローカルで index.html をダブルクリックして開くと file:// プロトコルになり fetch が失敗します。サンプルを手元で試す場合は VS Code の Live Server や Python の http.server など、ローカルサーバーを使って http:// で開いてください。

グラフの描画は <canvas> 要素を使います。レスポンシブ対応は Chart.js が自動で行いますが、親要素のサイズに追従させるために options.responsive: true(デフォルト)と options.maintainAspectRatio: false を組み合わせると、コンテナの高さを CSS で自由に指定できます。縦棒グラフは max-width で横幅を制限するとバランスよく見えます。

複数系列のカラー設定は datasets 配列の各エントリに backgroundColorborderColor を指定します。色を CSS 変数で管理すれば、ダークモード切り替えにも対応しやすくなります。

HTML・CSS・JavaScriptで実装しており、Chart.jsライブラリ(CDN)を1本追加するだけで動きます。フレームワーク不要でコピペすぐに使えます。

デモ

Pattern 1 — 縦棒グラフ(単一系列)

データを読み込んでいます...

Pattern 2 — 横棒グラフ(複数系列)

データを読み込んでいます...

サンプルソース

4つのファイルを同じフォルダに保存し、ローカルサーバー(VS Code Live Server 等)で index.html を開くと動作確認できます。
ファイル名:index.html / style.css / script.js / data/data.json — 保存時の文字コードは UTF-8 を指定してください。
⚠️ fetchfile:// では動作しません。ローカルサーバー経由(http://)で開いてください。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>棒グラフ サンプル</title>
  <link rel="stylesheet" href="./style.css">
  <!-- Chart.js v4(UMD ビルド) -->
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script>
</head>
<body>

<!-- ===== Pattern 1: 縦棒グラフ(単一系列) ===== -->
<section class="chart-section">
  <h2 class="chart-title">Pattern 1 — 縦棒グラフ(単一系列)</h2>
  <div class="chart-wrap chart-wrap--vertical">
    <canvas id="bar-v-chart" aria-label="月別サイト訪問者数の棒グラフ" role="img"></canvas>
  </div>
</section>

<!-- ===== Pattern 2: 横棒グラフ(複数系列) ===== -->
<section class="chart-section">
  <h2 class="chart-title">Pattern 2 — 横棒グラフ(複数系列)</h2>
  <div class="chart-wrap chart-wrap--horizontal">
    <canvas id="bar-h-chart" aria-label="部門別予算と実績の横棒グラフ" role="img"></canvas>
  </div>
</section>

<script src="./script.js"></script>
</body>
</html>
:root {
  --chart-blue:   #2B7FE8;
  --chart-orange: #FB923C;
  --chart-bg:     #F8FAFC;
  --chart-border: #E2E8F0;
  --chart-text:   #1E293B;
}

body {
  font-family: sans-serif;
  padding: 24px;
  background: var(--chart-bg);
  color: var(--chart-text);
}

.chart-section {
  margin-bottom: 48px;
}

.chart-title {
  font-size: 16px;
  font-weight: 700;
  margin: 0 0 16px;
  color: var(--chart-text);
}

/* 縦棒グラフ: 最大幅を指定して縦長にならないようにする */
.chart-wrap--vertical {
  max-width: 680px;
  height: 320px;
  background: #fff;
  border: 1px solid var(--chart-border);
  border-radius: 8px;
  padding: 16px;
  box-sizing: border-box;
}

/* 横棒グラフ: 高さを行数に合わせて余裕を持たせる */
.chart-wrap--horizontal {
  max-width: 680px;
  height: 280px;
  background: #fff;
  border: 1px solid var(--chart-border);
  border-radius: 8px;
  padding: 16px;
  box-sizing: border-box;
}
// data.json を fetch してグラフを描画する
document.addEventListener('DOMContentLoaded', function () {
  fetch('./data/data.json')
    .then(function (r) { return r.json(); })
    .then(function (data) {
      renderVertical(data.vertical);
      renderHorizontal(data.horizontal);
    })
    .catch(function (err) {
      console.error('データの取得に失敗しました:', err);
    });
});

// Pattern 1: 縦棒グラフ(単一系列)
function renderVertical(data) {
  var ctx = document.getElementById('bar-v-chart');
  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: data.labels,
      datasets: [{
        label: data.datasets[0].label,
        data: data.datasets[0].data,
        backgroundColor: 'rgba(43, 127, 232, 0.8)',
        borderColor: '#2B7FE8',
        borderWidth: 1,
        borderRadius: 4
      }]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        title: {
          display: true,
          text: data.label,
          font: { size: 13 }
        },
        legend: { display: false }
      },
      scales: {
        y: {
          beginAtZero: true,
          ticks: {
            // 数値を「1,000人」形式で表示
            callback: function (value) {
              return value.toLocaleString() + '人';
            }
          }
        }
      }
    }
  });
}

// Pattern 2: 横棒グラフ(複数系列)
// indexAxis: 'y' を指定するだけで縦棒から横棒に切り替わる
function renderHorizontal(data) {
  var ctx = document.getElementById('bar-h-chart');
  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: data.labels,
      datasets: [
        {
          label: data.datasets[0].label,
          data: data.datasets[0].data,
          backgroundColor: 'rgba(43, 127, 232, 0.8)',
          borderColor: '#2B7FE8',
          borderWidth: 1,
          borderRadius: 4
        },
        {
          label: data.datasets[1].label,
          data: data.datasets[1].data,
          backgroundColor: 'rgba(251, 146, 60, 0.8)',
          borderColor: '#FB923C',
          borderWidth: 1,
          borderRadius: 4
        }
      ]
    },
    options: {
      indexAxis: 'y',
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        title: {
          display: true,
          text: data.label,
          font: { size: 13 }
        }
      },
      scales: {
        x: {
          beginAtZero: true,
          ticks: {
            callback: function (value) {
              return value.toLocaleString() + '万円';
            }
          }
        }
      }
    }
  });
}
{
  "vertical": {
    "label": "月別サイト訪問者数(2025年)",
    "labels": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
    "datasets": [
      {
        "label": "訪問者数(人)",
        "data": [8200, 7600, 9100, 10400, 11200, 9800, 8700, 7300, 10100, 12500, 11800, 13200]
      }
    ]
  },
  "horizontal": {
    "label": "部門別予算と実績(2025年度)",
    "labels": ["営業部", "開発部", "マーケ部", "人事部", "総務部"],
    "datasets": [
      {
        "label": "予算(万円)",
        "data": [1200, 2400, 800, 600, 400]
      },
      {
        "label": "実績(万円)",
        "data": [1050, 2580, 720, 630, 380]
      }
    ]
  }
}

AI用プロンプト

各パターンのプロンプトをコピーしてAIに渡すと、同様のコンポーネントを生成できます。

ChatGPTやClaudeにこのプロンプトを渡すと、同様のコンポーネントをゼロから生成・カスタマイズできます。ライブラリ指定や系列数・データ変更など、要件を追記して使うのがおすすめです。

※ このプロンプトを使ってもデモとまったく同じ動作にならない場合があります。AIの解釈や生成タイミングによって差が出ることをご了承ください。

💡 jQuery・Vue・React など特定のライブラリで実装したい場合は、プロンプトの末尾に「〇〇を使って実装してください」と追記してください。

Pattern 1 — 縦棒グラフ(単一系列)

# 縦棒グラフ(Chart.js v4)作成依頼

## 概要
Chart.js v4(CDN)と JSON fetch を使った縦棒グラフを実装してください。
外部の data.json からデータを読み込んでグラフを描画します。

## 要件
- Chart.js v4 の UMD ビルドを CDN から読み込む
- data.json を fetch で取得してグラフを描画する
- グラフの種類は縦棒(type: 'bar')、単一系列
- グラフタイトルをグラフ内に表示する
- Y軸の数値を「1,000人」のようにカンマ区切り+単位付きで表示する
- 棒の角丸(borderRadius)を設定してモダンな見た目にする
- レスポンシブ対応(responsive: true)
- canvas の親要素の高さを CSS で指定し maintainAspectRatio: false で制御する

## 技術仕様
- HTML / CSS / バニラJavaScript で実装
- 外部ライブラリ:Chart.js v4(https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js)
- レスポンシブ対応:必要

## データ形式(data.json)
{
  "label": "グラフタイトル",
  "labels": ["1月", "2月", ...],
  "datasets": [
    { "label": "系列名", "data": [数値, 数値, ...] }
  ]
}

## 出力形式
HTML・CSS・JavaScriptを分けて出力してください。
各ファイルは単独でコピー&ペーストして使えるよう記述してください。

Pattern 2 — 横棒グラフ(複数系列)

# 横棒グラフ・複数系列(Chart.js v4)作成依頼

## 概要
Chart.js v4(CDN)と JSON fetch を使った横棒グラフ(複数系列)を実装してください。
外部の data.json からデータを読み込んでグラフを描画します。

## 要件
- Chart.js v4 の UMD ビルドを CDN から読み込む
- data.json を fetch で取得してグラフを描画する
- グラフの種類は横棒(type: 'bar' + options.indexAxis: 'y')
- 2系列以上の比較グラフにする(例:予算 vs 実績)
- 系列ごとに異なる色を設定する
- グラフタイトルをグラフ内に表示する
- 凡例(legend)を表示する
- X軸の数値を「1,000万円」のようにカンマ区切り+単位付きで表示する
- 棒の角丸(borderRadius)を設定してモダンな見た目にする
- レスポンシブ対応(responsive: true)
- canvas の親要素の高さを CSS で指定し maintainAspectRatio: false で制御する

## 技術仕様
- HTML / CSS / バニラJavaScript で実装
- 外部ライブラリ:Chart.js v4(https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js)
- レスポンシブ対応:必要

## データ形式(data.json)
{
  "label": "グラフタイトル",
  "labels": ["カテゴリ1", "カテゴリ2", ...],
  "datasets": [
    { "label": "系列A", "data": [数値, 数値, ...] },
    { "label": "系列B", "data": [数値, 数値, ...] }
  ]
}

## 出力形式
HTML・CSS・JavaScriptを分けて出力してください。
各ファイルは単独でコピー&ペーストして使えるよう記述してください。