- Angular
Angular グラフ表示|ng2-chartsの使い方と更新されない原因
Angular でグラフを出すなら、Chart.js を Angular から使えるようにする ng2-charts が手早い方法です。 手順は3つです。
npm install ng2-charts chart.js
// app.config.ts:Chart.js の部品を登録する
providers: [provideCharts(withDefaultRegisterables())]
<!-- コンポーネント:imports に BaseChartDirective を入れて canvas に付ける -->
<canvas baseChart type="bar" [data]="data" [options]="options"></canvas>
データを変えてもグラフが変わらないときは、配列に push しただけになっていないかを確かめます。 ng2-charts は [data] に「新しいオブジェクト」が渡ったときに描き直す作りで、同じ配列の中身を変えただけでは描き直されませんでした(後述)。
| ng2-charts | 対応する Angular(peerDependencies) | Chart.js |
|---|---|---|
| 11.0.0(2026年9月) | 22 以上 | 3.4 以上 または 4 |
| 10.x | 21 以上 | 3.4 以上 または 4 |
| 9.x | 20 以上 | 3.4 以上 または 4 |
| 8.x | 19 以上 | 3.4 以上 または 4 |
確認環境:Angular 22.2.2・ng2-charts 11.0.0・Chart.js 4.5.1・TypeScript 6.0.3・Node.js 24.21.0 で ng build した本番ビルドを、Chromium 141(playwright-core 1.64.0)で表示しました。描画はスクリーンショットで、更新の結果は Chart.js が描いた棒の数(getDatasetMeta(0).data.length)で確かめました。表の対応は npm に公開されている各版の peerDependencies です(確認日 2026年10月13日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Angular グラフ表示|ng2-chartsの使い方と更新されない原因」
手順1:インストールと provideCharts
ng add ng2-charts を使うと、インストールと app.config.ts の書き換えを一度に行います。 実行すると、app.config.ts に次の行が足されました。
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideCharts, withDefaultRegisterables } from 'ng2-charts';
export const appConfig: ApplicationConfig = {
providers: [provideBrowserGlobalErrorListeners(), provideRouter(routes), provideCharts(withDefaultRegisterables())],
};
npm で入れる場合は npm install ng2-charts chart.js のあと、上の provideCharts(...) を自分で書きます。ng2-charts 11 は @angular/cdk(22 以上)も peerDependencies に持っています。
withDefaultRegisterables() は、Chart.js の全種類のグラフ・目盛り・プラグインをまとめて登録します。使うグラフを絞って小さくする方法は後半で扱います。
手順2:棒・折れ線・円グラフのコンポーネント全文
3つとも、そのままコピーして使える形です。 グラフの外側の div に position: relative と高さを付けているのがポイントです(理由は後述)。
棒グラフ(sales-bar-chart.ts)
import { Component } from '@angular/core';
import { BaseChartDirective } from 'ng2-charts';
import { ChartConfiguration } from 'chart.js';
@Component({
selector: 'app-sales-bar-chart',
imports: [BaseChartDirective],
template: `
<div class="chart-box">
<canvas baseChart type="bar" [data]="data" [options]="options"></canvas>
</div>
`,
styles: `.chart-box { position: relative; height: 320px; }`,
})
export class SalesBarChart {
data: ChartConfiguration<'bar'>['data'] = {
labels: ['4月', '5月', '6月', '7月', '8月', '9月'],
datasets: [
{ label: '2025年度', data: [120, 135, 150, 142, 160, 171] },
{ label: '2026年度', data: [130, 148, 165, 170, 182, 195] },
],
};
options: ChartConfiguration<'bar'>['options'] = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { position: 'bottom' },
title: { display: true, text: '月別売上(百万円)' },
},
scales: { y: { beginAtZero: true } },
};
}
折れ線グラフ(access-line-chart.ts)
import { Component } from '@angular/core';
import { BaseChartDirective } from 'ng2-charts';
import { ChartConfiguration } from 'chart.js';
@Component({
selector: 'app-access-line-chart',
imports: [BaseChartDirective],
template: `
<div class="chart-box">
<canvas baseChart type="line" [data]="data" [options]="options"></canvas>
</div>
`,
styles: `.chart-box { position: relative; height: 320px; }`,
})
export class AccessLineChart {
data: ChartConfiguration<'line'>['data'] = {
labels: ['月', '火', '水', '木', '金', '土', '日'],
datasets: [
{ label: 'PV', data: [3200, 2900, 3500, 3700, 3300, 2100, 1900], tension: 0.3, fill: true },
{ label: 'UU', data: [1800, 1700, 2000, 2100, 1900, 1200, 1100], tension: 0.3, borderDash: [6, 4] },
],
};
options: ChartConfiguration<'line'>['options'] = {
responsive: true,
maintainAspectRatio: false,
interaction: { mode: 'index', intersect: false },
plugins: { legend: { position: 'bottom' } },
};
}
tension は線のなめらかさ(0 で直線)、fill: true は線の下を塗る設定、borderDash は点線です。interaction: { mode: 'index', intersect: false } にすると、同じ曜日の PV と UU が1つのツールチップに並びます。
円グラフ(share-pie-chart.ts)
import { Component } from '@angular/core';
import { BaseChartDirective } from 'ng2-charts';
import { ChartConfiguration } from 'chart.js';
@Component({
selector: 'app-share-pie-chart',
imports: [BaseChartDirective],
template: `
<div class="chart-box">
<canvas baseChart type="pie" [data]="data" [options]="options"></canvas>
</div>
`,
styles: `.chart-box { position: relative; height: 320px; }`,
})
export class SharePieChart {
data: ChartConfiguration<'pie'>['data'] = {
labels: ['Java', 'TypeScript', 'Python', 'その他'],
datasets: [{ data: [42, 28, 18, 12] }],
};
options: ChartConfiguration<'pie'>['options'] = {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { position: 'right' } },
};
}
ドーナツグラフにするなら type="doughnut" と ChartConfiguration<'doughnut'> に変えます。
3つを並べる(dashboard.ts)
import { Component } from '@angular/core';
import { SalesBarChart } from './sales-bar-chart';
import { AccessLineChart } from './access-line-chart';
import { SharePieChart } from './share-pie-chart';
@Component({
selector: 'app-dashboard',
imports: [SalesBarChart, AccessLineChart, SharePieChart],
template: `
<div class="grid">
<app-sales-bar-chart />
<app-access-line-chart />
<app-share-pie-chart />
</div>
`,
styles: `.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }`,
})
export class Dashboard {}
幅 1280px の画面で表示すると、3つの canvas はどれも幅約 410px・高さ 320px で描かれました。色は指定していませんが、棒・線・円のどれも自動で色分けされました。 withDefaultRegisterables() に Chart.js の Colors プラグインが含まれ、既定の色を順に当てるためです。凡例(legend)も position の指定どおり、棒と折れ線は下、円は右に出ました。
baseChart の入力・イベント一覧
ng2-charts 11.0.0 の型定義(BaseChartDirective)と README から抜き出した一覧です。
| 入力・出力 | 型 | 内容 |
|---|---|---|
type |
ChartType |
bar・line・pie・doughnut・radar・polarArea・bubble・scatter |
data |
ChartData |
labels と datasets をまとめたもの |
labels / datasets |
配列 | data の代わりに分けて渡す書き方 |
options |
ChartOptions |
Chart.js のオプションそのまま |
legend |
boolean |
false で凡例を消す(指定しなければ Chart.js の既定で表示) |
plugins |
Plugin[] |
そのグラフだけのプラグイン |
(chartClick) / (chartHover) |
イベント | クリック・ホバーした点(active)を受け取る |
ディレクティブには update()・render()・hideDataset(index, hidden)・toBase64Image() のメソッドもあります。toBase64Image() はグラフを PNG の data URL にするので、画像として保存するときに使えます。
[legend] を書かなかったとき、凡例は表示されました(Chart.js の legend.options.display が true)。[legend]="false" を付けると false になり、凡例が消えました。
データを変えてもグラフが更新されない原因と4つの直し方
ボタンを押してデータを足す画面を作り、4つの書き方で、Chart.js が実際に描いた棒の数を記録しました。
import { Component, signal, viewChild } from '@angular/core';
import { BaseChartDirective } from 'ng2-charts';
import { ChartConfiguration, ChartData } from 'chart.js';
@Component({
selector: 'app-live-chart',
imports: [BaseChartDirective],
template: `
<button (click)="pushOnly()">① push だけ</button>
<button (click)="pushAndUpdate()">② push + update()</button>
<button (click)="replace()">③ 新しいオブジェクトに置き換え</button>
<button (click)="addBySignal()">④ signal を update</button>
<div class="chart-box"><canvas baseChart type="bar" [data]="data" [options]="options"></canvas></div>
<div class="chart-box"><canvas baseChart type="bar" [data]="sigData()" [options]="options"></canvas></div>
`,
styles: `.chart-box { position: relative; height: 240px; }`,
})
export class LiveChart {
chart = viewChild.required(BaseChartDirective); // 1つ目の canvas
options: ChartConfiguration<'bar'>['options'] = { responsive: true, maintainAspectRatio: false, animation: false };
data: ChartData<'bar'> = { labels: ['A', 'B'], datasets: [{ label: '件数', data: [3, 5] }] };
/** ① 配列に push するだけ */
pushOnly(): void {
this.data.labels!.push('C');
this.data.datasets[0].data.push(7);
}
/** ② push したあと update() を呼ぶ */
pushAndUpdate(): void {
this.data.labels!.push('D');
this.data.datasets[0].data.push(4);
this.chart().update();
}
/** ③ data を新しいオブジェクトにする */
replace(): void {
this.data = {
labels: [...this.data.labels!, 'E'],
datasets: [{ ...this.data.datasets[0], data: [...this.data.datasets[0].data, 6] }],
};
}
/** ④ signal で持ち、update で新しいオブジェクトを作る */
sigData = signal<ChartData<'bar'>>({ labels: ['A', 'B'], datasets: [{ label: '件数', data: [3, 5] }] });
addBySignal(): void {
this.sigData.update((d) => ({
labels: [...d.labels!, `X${d.labels!.length}`],
datasets: [{ ...d.datasets[0], data: [...d.datasets[0].data, 8] }],
}));
}
}
| 押したボタン | data.labels の中身 | 描かれた棒の数 | 結果 |
|---|---|---|---|
| 最初 | A,B | 2 | — |
| ① push だけ | A,B,C | 2 | 描き直されない |
② push + update() |
A,B,C,D | 4 | 描き直された(①の C も出た) |
| ③ 新しいオブジェクトに置き換え | A,B,C,D,E | 5 | 描き直された |
| ④ signal を update(2回) | A,B,X2,X3(2つ目のグラフ) | 4 | 描き直された |
①では、配列の中身は増えているのに、グラフは2本のままでした。 ng2-charts 11 のソースを見ると、ngOnChanges(入力が変わったときに呼ばれる処理)で data・options を Chart.js に渡して update() しています。Angular は「[data] に渡したオブジェクトが別のものになったか」で入力の変化を判断するため、同じ配列に push しただけでは ngOnChanges が呼ばれません。
| 直し方 | 書き方 | 向いている場面 |
|---|---|---|
② update() を呼ぶ |
viewChild(BaseChartDirective) で取り、update() |
大きな配列を毎回作り直したくない、リアルタイム更新 |
| ③ 新しいオブジェクトにする | スプレッド構文(...)で作り直して代入 |
普通の画面。書き忘れが起きにくい |
| ④ signal で持つ | signal.update() で新しいオブジェクトを返す |
signal で状態を持つ画面 |
なお、ソースでは type を変えたときだけ、グラフを一度破棄して作り直す(render())作りでした。棒グラフと折れ線を切り替えるボタンなら、[type] を変えるだけで作り直されます。signal の使い方は、関連記事「Angular Signals使い方|v22対応の全API早見表と実行結果つきコード」で扱っています。
グラフの高さが思いどおりにならないとき
Chart.js は親要素の大きさに合わせて canvas の大きさを決めます。 Chart.js のドキュメントには「親要素は position: relative で、その canvas 専用であること」とあります。
| 設定 | 動き(Chart.js のドキュメント) |
|---|---|
maintainAspectRatio: true(既定) |
幅に合わせ、縦横比を保って高さが決まる |
aspectRatio の既定 |
円・ドーナツ・レーダー・鶏頭図は 1、それ以外は 2 |
maintainAspectRatio: false |
親要素の高さに合わせる。親に高さを付ける |
この記事のコードは maintainAspectRatio: false と、親の div の height: 320px の組み合わせで、canvas の高さが 320px になりました。
使うグラフだけ登録して小さくする
withDefaultRegisterables() の代わりに、使う部品だけを provideCharts({ registerables: [...] }) に並べられます。 棒グラフだけなら次のとおりです。
import { provideCharts } from 'ng2-charts';
import { BarController, BarElement, CategoryScale, LinearScale, Legend, Title, Tooltip, Colors } from 'chart.js';
provideCharts({
registerables: [BarController, BarElement, CategoryScale, LinearScale, Legend, Title, Tooltip, Colors],
});
この記事の確認用のアプリ(ガード・テンプレートの確認用の画面も入ったもの)では、本番ビルドの main の大きさが次のように変わりました。
| 登録 | main の大きさ | 転送量の目安(圧縮後) |
|---|---|---|
withDefaultRegisterables() |
498.40 kB | 137.63 kB |
| 棒グラフに使う8つだけ | 464.72 kB | 128.12 kB |
Chart.js のドキュメントにある、グラフの種類ごとに要る部品です。
| グラフ | コントローラー | 要素 | 既定の目盛り |
|---|---|---|---|
| 棒(bar) | BarController |
BarElement |
CategoryScale・LinearScale |
| 折れ線(line) | LineController |
LineElement・PointElement |
CategoryScale・LinearScale |
| 円(pie) | PieController |
ArcElement |
なし |
| ドーナツ(doughnut) | DoughnutController |
ArcElement |
なし |
| レーダー(radar) | RadarController |
LineElement・PointElement |
RadialLinearScale |
折れ線の fill: true には Filler、タイトルには Title、ツールチップには Tooltip、凡例には Legend のプラグインを足します。
登録が足りないときのエラー
| 状況 | ブラウザのコンソールに出たエラー |
|---|---|
provideCharts を書いていない(棒グラフを表示) |
ERROR Error: "linear" is not a registered scale. |
| 棒グラフ用だけ登録して折れ線を表示 | ERROR Error: "line" is not a registered controller. |
is not a registered controller / scale が出たら、provideCharts の書き忘れか、そのグラフの部品の登録漏れです。
よくある質問
Q. グラフをクリックした項目を知りたいです。
A. (chartClick)="onClick($event)" で、クリックの情報と active(当たった点の配列)を受け取れます。ng2-charts 11 のソースでは、イベントを受け取る側があるときだけ Angular の処理に戻して通知する作りです。
Q. SSR(サーバー側の描画)でエラーになりませんか。
A. ng2-charts 11 のソースでは、ブラウザでないとき(isPlatformBrowser が false)は canvas の取得もグラフの作成も行わない作りになっています。グラフはブラウザで表示されたときに描かれます。
Q. ダークモードで文字の色を変えたいです。
A. ng2-charts の ThemeService の setColorschemesOptions() に、上書きしたいオプションを渡すと、表示中のグラフにまとめて反映されます(README の Dynamic Theming)。
Q. Angular Material と一緒に使えますか。
A. ng2-charts 11 は @angular/cdk を peerDependencies に持っています。Angular Material の導入は、関連記事「Angular Materialの使い方|導入からテーブル・ダイアログまで」で扱っています。
まとめ
provideCharts(withDefaultRegisterables())を app.config に書き、BaseChartDirectiveを imports に入れて<canvas baseChart>- ng2-charts 11 は Angular 22 以上、10 は 21、9 は 20 に対応
- 配列に push しただけではグラフは変わらなかった。
update()・新しいオブジェクトの代入・signal のどれかで更新する - 高さは 親を
position: relativeにして高さを付け、maintainAspectRatio: false is not a registered controllerは部品の登録漏れ。使う部品だけ登録すると main が約 34 kB 小さくなった
参考・出典
確認日はいずれも 2026年10月13日です。
- ng2-charts(GitHub・README):https://github.com/valor-software/ng2-charts
- ng2-charts(npm):https://www.npmjs.com/package/ng2-charts
- Chart.js「Integration」(Bundlers・tree-shaking):https://www.chartjs.org/docs/latest/getting-started/integration.html
- Chart.js「Responsive Charts」:https://www.chartjs.org/docs/latest/configuration/responsive.html
- Chart.js「Updating Charts」:https://www.chartjs.org/docs/latest/developers/updates.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Angular グラフ表示|ng2-chartsの使い方と更新されない原因」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。