
Chart.js 入門 - 美しいグラフを簡単に実装する方法
Webサイトでデータを可視化したいとき、Chart.js は非常に強力な選択肢です。軽量でありながら美しいグラフを簡単に作成でき、レスポンシブ対応も標準で備えています。
この記事では、Chart.jsの基本的な使い方から、様々なチャートタイプの実装例まで、実践的なコードとともに解説します。
Chart.jsとは?
Chart.jsは、HTML5 Canvasを使用してグラフを描画するオープンソースのJavaScriptライブラリです。
特徴
- 軽量: 圧縮版で約60KB程度
- 8種類のチャートタイプ: 棒、折れ線、円、ドーナツ、レーダー、極座標、バブル、散布図
- レスポンシブ対応: 画面サイズに合わせて自動リサイズ
- アニメーション: デフォルトで滑らかなアニメーション
- カスタマイズ性: 色、フォント、凡例、ツールチップなど細かく設定可能
- プラグインエコシステム: データラベル、ズーム機能などの拡張
インストール方法
CDNから読み込む(最も簡単)
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>npmでインストール
npm install chart.jsimport Chart from 'chart.js/auto';基本構造
Chart.jsでグラフを作成する基本的な流れは以下の通りです:
- HTMLに
<canvas>要素を配置 - JavaScriptで
new Chart()を呼び出し - チャートタイプ、データ、オプションを設定
<canvas id="myChart"></canvas>
<script>
const ctx = document.getElementById('myChart');
new Chart(ctx, {
type: 'チャートタイプ',
data: {
labels: ['ラベル1', 'ラベル2', '...'],
datasets: [{
label: 'データセット名',
data: [値1, 値2, ...],
// スタイリング設定
}]
},
options: {
// 表示オプション
}
});
</script>チャートタイプ別 実装例
1. 棒グラフ(Bar Chart)
最も基本的で使用頻度の高いチャートです。カテゴリ別のデータ比較に適しています。
<canvas id="barChart" width="400" height="200"></canvas>
<script>
const barCtx = document.getElementById('barChart');
new Chart(barCtx, {
type: 'bar',
data: {
labels: ['1月', '2月', '3月', '4月', '5月', '6月'],
datasets: [{
label: '売上(万円)',
data: [120, 190, 150, 180, 200, 220],
backgroundColor: [
'rgba(255, 99, 132, 0.7)',
'rgba(54, 162, 235, 0.7)',
'rgba(255, 206, 86, 0.7)',
'rgba(75, 192, 192, 0.7)',
'rgba(153, 102, 255, 0.7)',
'rgba(255, 159, 64, 0.7)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: '売上(万円)'
}
}
},
plugins: {
title: {
display: true,
text: '月別売上推移'
}
}
}
});
</script>横棒グラフ
type: 'bar' を使い、indexAxis: 'y' を設定します。
new Chart(ctx, {
type: 'bar',
data: data,
options: {
indexAxis: 'y', // これで横棒グラフに
responsive: true
}
});2. 折れ線グラフ(Line Chart)
時系列データや連続したデータの推移を表現するのに最適です。
<canvas id="lineChart" width="400" height="200"></canvas>
<script>
const lineCtx = document.getElementById('lineChart');
new Chart(lineCtx, {
type: 'line',
data: {
labels: ['1月', '2月', '3月', '4月', '5月', '6月'],
datasets: [{
label: '訪問者数',
data: [1200, 1900, 3000, 2500, 4200, 5300],
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderWidth: 2,
fill: true,
tension: 0.4 // 曲線の滑らかさ(0で直線)
}, {
label: 'コンバージョン',
data: [100, 150, 280, 220, 380, 450],
borderColor: 'rgba(255, 99, 132, 1)',
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderWidth: 2,
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'サイトアクセス推移'
}
},
scales: {
y: {
beginAtZero: true
}
}
}
});
</script>ポイントスタイルのカスタマイズ
datasets: [{
// ...
pointStyle: 'circle', // 'circle', 'cross', 'rect', 'star', 'triangle'
pointRadius: 6, // ポイントサイズ
pointHoverRadius: 10, // ホバー時のサイズ
pointBackgroundColor: '#fff',
pointBorderWidth: 2
}]3. 円グラフ(Pie Chart)
全体に対する各要素の割合を表現します。
<canvas id="pieChart" width="300" height="300"></canvas>
<script>
const pieCtx = document.getElementById('pieChart');
new Chart(pieCtx, {
type: 'pie',
data: {
labels: ['デスクトップ', 'モバイル', 'タブレット'],
datasets: [{
data: [55, 35, 10],
backgroundColor: [
'rgba(54, 162, 235, 0.8)',
'rgba(255, 99, 132, 0.8)',
'rgba(255, 206, 86, 0.8)'
],
borderColor: [
'rgba(54, 162, 235, 1)',
'rgba(255, 99, 132, 1)',
'rgba(255, 206, 86, 1)'
],
borderWidth: 2,
hoverOffset: 10 // ホバー時に飛び出す
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom',
},
title: {
display: true,
text: 'デバイス別アクセス比率'
},
tooltip: {
callbacks: {
label: function(context) {
return context.label + ': ' + context.raw + '%';
}
}
}
}
}
});
</script>4. ドーナツグラフ(Doughnut Chart)
円グラフの中央を切り抜いたスタイル。中央に合計値や追加情報を表示できます。
<canvas id="doughnutChart" width="300" height="300"></canvas>
<script>
const doughnutCtx = document.getElementById('doughnutChart');
new Chart(doughnutCtx, {
type: 'doughnut',
data: {
labels: ['完了', '進行中', '未着手', '保留'],
datasets: [{
data: [45, 30, 15, 10],
backgroundColor: [
'rgba(75, 192, 192, 0.8)',
'rgba(54, 162, 235, 0.8)',
'rgba(255, 206, 86, 0.8)',
'rgba(201, 203, 207, 0.8)'
],
borderWidth: 0
}]
},
options: {
responsive: true,
cutout: '60%', // 中央の穴のサイズ(デフォルト50%)
plugins: {
legend: {
position: 'right',
},
title: {
display: true,
text: 'タスク進捗状況'
}
}
}
});
</script>半円(ハーフドーナツ)を作る
options: {
circumference: 180, // 表示角度
rotation: -90, // 開始角度(-90で上から開始)
cutout: '60%'
}5. レーダーチャート(Radar Chart)
複数の指標を同時に比較するのに適しています。スキル評価やプロダクト比較によく使われます。
<canvas id="radarChart" width="400" height="400"></canvas>
<script>
const radarCtx = document.getElementById('radarChart');
new Chart(radarCtx, {
type: 'radar',
data: {
labels: ['JavaScript', 'TypeScript', 'React', 'Vue', 'Node.js', 'Python'],
datasets: [{
label: 'エンジニアA',
data: [90, 85, 95, 70, 80, 60],
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 2,
pointBackgroundColor: 'rgba(255, 99, 132, 1)'
}, {
label: 'エンジニアB',
data: [75, 90, 70, 95, 85, 80],
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 2,
pointBackgroundColor: 'rgba(54, 162, 235, 1)'
}]
},
options: {
responsive: true,
scales: {
r: {
beginAtZero: true,
max: 100,
ticks: {
stepSize: 20
},
pointLabels: {
font: {
size: 14
}
}
}
},
plugins: {
title: {
display: true,
text: 'スキル比較'
}
}
}
});
</script>6. 極座標グラフ(Polar Area Chart)
円グラフと似ていますが、各セグメントの半径がデータ値を表します。
<canvas id="polarChart" width="300" height="300"></canvas>
<script>
const polarCtx = document.getElementById('polarChart');
new Chart(polarCtx, {
type: 'polarArea',
data: {
labels: ['HTML/CSS', 'JavaScript', 'React', 'Node.js', 'Database'],
datasets: [{
data: [85, 90, 80, 70, 65],
backgroundColor: [
'rgba(255, 99, 132, 0.7)',
'rgba(255, 206, 86, 0.7)',
'rgba(54, 162, 235, 0.7)',
'rgba(75, 192, 192, 0.7)',
'rgba(153, 102, 255, 0.7)'
]
}]
},
options: {
responsive: true,
scales: {
r: {
beginAtZero: true
}
},
plugins: {
legend: {
position: 'bottom'
},
title: {
display: true,
text: '技術スキル分布'
}
}
}
});
</script>7. 散布図(Scatter Chart)
2つの変数間の関係を視覚化します。相関関係の確認に便利です。
<canvas id="scatterChart" width="400" height="400"></canvas>
<script>
const scatterCtx = document.getElementById('scatterChart');
new Chart(scatterCtx, {
type: 'scatter',
data: {
datasets: [{
label: 'サンプルデータ',
data: [
{ x: 10, y: 20 },
{ x: 15, y: 25 },
{ x: 20, y: 30 },
{ x: 25, y: 22 },
{ x: 30, y: 45 },
{ x: 35, y: 40 },
{ x: 40, y: 55 },
{ x: 45, y: 52 },
{ x: 50, y: 65 }
],
backgroundColor: 'rgba(75, 192, 192, 0.8)',
pointRadius: 8,
pointHoverRadius: 12
}]
},
options: {
responsive: true,
scales: {
x: {
title: {
display: true,
text: '広告費(万円)'
}
},
y: {
title: {
display: true,
text: '売上(万円)'
}
}
},
plugins: {
title: {
display: true,
text: '広告費と売上の相関'
}
}
}
});
</script>8. バブルチャート(Bubble Chart)
散布図の各ポイントに「大きさ」という第3の次元を追加したチャートです。
<canvas id="bubbleChart" width="400" height="400"></canvas>
<script>
const bubbleCtx = document.getElementById('bubbleChart');
new Chart(bubbleCtx, {
type: 'bubble',
data: {
datasets: [{
label: '商品カテゴリ',
data: [
{ x: 20, y: 30, r: 15 }, // r = バブルの半径
{ x: 40, y: 10, r: 10 },
{ x: 30, y: 22, r: 25 },
{ x: 50, y: 40, r: 20 },
{ x: 10, y: 50, r: 12 }
],
backgroundColor: [
'rgba(255, 99, 132, 0.7)',
'rgba(54, 162, 235, 0.7)',
'rgba(255, 206, 86, 0.7)',
'rgba(75, 192, 192, 0.7)',
'rgba(153, 102, 255, 0.7)'
]
}]
},
options: {
responsive: true,
scales: {
x: {
title: {
display: true,
text: '価格帯'
}
},
y: {
title: {
display: true,
text: '販売数'
}
}
},
plugins: {
title: {
display: true,
text: '商品分析(バブルサイズ = 利益率)'
}
}
}
});
</script>9. 複合チャート(Mixed Chart)
棒グラフと折れ線グラフなど、異なるタイプを組み合わせて表示できます。
私が実際に開発で使用したのもこのパターンで、エリアデータを棒グラフ、全国平均を折れ線グラフで表示しました。
<canvas id="mixedChart" width="400" height="200"></canvas>
<script>
const mixedCtx = document.getElementById('mixedChart');
new Chart(mixedCtx, {
type: 'bar', // ベースタイプ
data: {
labels: ['2018年', '2020年', '2022年', '2024年'],
datasets: [
{
label: '東京都のエンジニア数',
data: [280, 290, 300, 310],
backgroundColor: 'rgba(0, 166, 81, 0.8)', // ブランドカラー
borderColor: 'rgba(0, 166, 81, 1)',
borderWidth: 1,
order: 2 // 描画順(大きいほど後ろ)
},
{
type: 'line', // このデータセットのみ折れ線
label: '全国平均',
data: [265.8, 265.8, 265.8, 265.8],
borderColor: 'rgba(255, 152, 0, 1)',
backgroundColor: 'transparent',
borderWidth: 2,
borderDash: [5, 5], // 破線
pointRadius: 0,
fill: false,
order: 1 // 前面に表示
}
]
},
options: {
responsive: true,
maintainAspectRatio: true,
scales: {
y: {
beginAtZero: false,
min: 200,
title: {
display: true,
text: '人口10万人あたり(人)'
}
}
},
plugins: {
legend: {
position: 'top'
},
title: {
display: true,
text: 'エンジニア数の推移と全国平均'
},
tooltip: {
callbacks: {
label: function(context) {
return context.dataset.label + ': ' + context.raw + '人';
}
}
}
}
}
});
</script>共通オプション
レスポンシブ設定
options: {
responsive: true, // 画面サイズに合わせてリサイズ
maintainAspectRatio: true, // アスペクト比を維持
aspectRatio: 2 // 幅:高さ = 2:1
}アニメーション
options: {
animation: {
duration: 1000, // アニメーション時間(ms)
easing: 'easeOutQuart' // イージング関数
}
}
// アニメーション無効化
options: {
animation: false
}ツールチップ
options: {
plugins: {
tooltip: {
enabled: true,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
titleFont: { size: 14 },
bodyFont: { size: 12 },
padding: 12,
callbacks: {
label: function(context) {
return context.dataset.label + ': ' + context.raw + '円';
}
}
}
}
}凡例(レジェンド)
options: {
plugins: {
legend: {
display: true,
position: 'top', // 'top', 'bottom', 'left', 'right'
align: 'center',
labels: {
boxWidth: 20,
padding: 15,
font: { size: 12 }
}
}
}
}実践Tips
1. データ属性から値を取得
HTMLのdata属性を使ってサーバーサイドからデータを渡すパターン。
<canvas id="chart"
data-values="[120, 190, 150, 180]"
data-labels='["1月", "2月", "3月", "4月"]'>
</canvas>
<script>
const canvas = document.getElementById('chart');
const values = JSON.parse(canvas.dataset.values);
const labels = JSON.parse(canvas.dataset.labels);
new Chart(canvas, {
type: 'bar',
data: {
labels: labels,
datasets: [{
data: values
}]
}
});
</script>2. 動的なデータ更新
const chart = new Chart(ctx, config);
// データ更新
chart.data.datasets[0].data = [新しいデータ];
chart.update(); // 再描画3. グラフの破棄
SPAなどでコンポーネントをアンマウントする際は、メモリリークを防ぐためにグラフを破棄します。
chart.destroy();まとめ
Chart.jsは、以下の点で優れたライブラリです:
- 学習コストが低い: シンプルなAPIで素早く実装できる
- 美しいデフォルトスタイル: そのままでも見栄えが良い
- 柔軟なカスタマイズ: 細かい部分まで調整可能
- レスポンシブ対応: モバイルでも適切に表示
データ可視化が必要なプロジェクトでは、まずChart.jsを検討してみてください。シンプルなグラフからやや複雑な複合チャートまで、幅広いニーズに対応できます。