Chart.js v4でツールチップをカスタマイズする方法【動くデモ付き】

結論:plugins.tooltip.callbacksで表示内容を差し替える

Chart.js v4でツールチップの表示内容を変えるには、options.plugins.tooltip.callbacks に関数を指定します。デフォルトのツールチップは「系列名: 数値」しか出せませんが、callbacks.label を上書きすれば単位付与や桁区切り、複数行表示まで自由に組み立てられます。

デモ:月別売上(円マーク+桁区切りで表示)
const chart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['1月', '2月', '3月', '4月'],
    datasets: [{ label: '売上', data: [1280000, 980000, 1520000, 1410000] }]
  },
  options: {
    plugins: {
      tooltip: {
        callbacks: {
          // タイトル(上段):軸ラベルをそのまま使う場合は省略可
          title: function (items) {
            return items[0].label + 'の実績';
          },
          // ラベル(本体):金額を3桁区切り+円表記に変換
          label: function (context) {
            const value = context.parsed.y;
            return '売上: ' + value.toLocaleString('ja-JP') + '円';
          }
        }
      }
    }
  }
});

ポイントは toLocaleString('ja-JP') です。Chart.js自体には桁区切りの機能がないため、数値の整形はすべてJavaScript側の標準機能に任せます。単位付与も同じ考え方で、文字列を組み立てて return するだけです。

各オプションの意味とバージョン注意点

callbacks に渡せる関数はいくつかありますが、業務アプリでよく使うのは次の3つです。

label

ツールチップ本体の各行を生成する。引数の context から context.parsed.y(値)や context.dataset.label(系列名)、context.label(軸ラベル)が取得できる。文字列を return すると1行、配列を return すると複数行になる。

title

ツールチップ上段の見出しを生成する。デフォルトは軸ラベル(月名など)がそのまま入るが、「◯月の実績」のように文言を足したいときに上書きする。引数は該当ポイントの配列なので items[0] から情報を取り出す。

footer

ツールチップ最下段に補足行を足す。複数系列の合計値や、前年同月比のような1行だけの注記を添えたいときに使う。使わない場合は指定しなくてよい。

バージョンでハマりやすいのは、v3以前の記事でよく見る tooltips(複数形・options直下)という書き方がv4では効かない点です。v4では options.plugins.tooltip(単数形・plugins配下)に統一されています。検索で出てくる古いサンプルをそのままコピペすると、エラーは出ないのにコールバックだけ無視される、という分かりにくい状態になるので注意してください。凡例のカスタマイズも同様にv3以前とv4でオプションの場所が変わっており、Chart.js凡例カスタマイズの記事で詳しく扱っています。

よくあるバリエーション

複数行で内訳を表示する

label コールバックは配列を返すと、ツールチップ内で複数行に分けて表示されます。合計と内訳を一緒に見せたいときに使います。

callbacks: {
  label: function (context) {
    const value = context.parsed.y;
    const tax = Math.round(value * 0.1);
    return [
      '売上(税抜): ' + value.toLocaleString('ja-JP') + '円',
      '消費税: ' + tax.toLocaleString('ja-JP') + '円'
    ];
  }
}

桁区切りだけを差し込みたいとき

単位付与や複数行までは不要で、数値の桁区切りだけ直したい場合は、系列名(context.dataset.label)を活かしつつ数値部分だけ toLocaleString に置き換えます。

callbacks: {
  label: function (context) {
    const label = context.dataset.label || '';
    const value = context.parsed.y.toLocaleString('ja-JP');
    return label + ': ' + value;
  }
}

桁区切りのためだけに専用のプラグインやライブラリを追加する必要はありません。toLocaleString はブラウザ標準のAPIなので、Chart.js側の設定はcallbacks.labelの中で数値を整形するだけで完結します。

円グラフ・ドーナツグラフで割合(%)を表示する

円グラフ系は各セグメントの値だけでは全体に対する割合が分かりにくいため、ツールチップに%を追加すると業務アプリでの見やすさが上がります。

callbacks: {
  label: function (context) {
    const value = context.parsed;
    const total = context.dataset.data.reduce((sum, v) => sum + v, 0);
    const percent = ((value / total) * 100).toFixed(1);
    return context.label + ': ' + value.toLocaleString('ja-JP') + '(' + percent + '%)';
  }
}

棒グラフ・折れ線グラフでは context.parsed.y、円グラフ・ドーナツグラフでは context.parsed と、値の取り出し方がグラフ種別で異なる点だけ注意してください。

ハマりどころ

callbacksの中でthisを使うと参照先がずれる

アロー関数で書くと this がツールチップ本体を指さなくなる。公式ドキュメントのサンプルは function () {} の通常関数で書かれていることが多く、ツールチップ内部の情報(this.chartなど)を参照する必要がなければアロー関数でも問題ないが、迷ったら通常関数に揃えるのが無難。

label関数の戻り値をundefinedにするとその行が消える

条件分岐で一部の系列だけツールチップ行を非表示にしたい場合、returnを書かずに関数を抜けると値が undefined になりその行ごと消える。意図的な非表示なら問題ないが、条件分岐の書き漏れで意図せず行が消えることがあるため確認する。

症状 原因 対処
callbacksを書いたのに反映されない v3以前のtooltips(複数形・options直下)で書いている v4のplugins.tooltip(単数形・plugins配下)に書き直す
桁区切りが3桁ごとにならない toLocaleString()にロケールを指定していない toLocaleString('ja-JP')のように明示する
複数行にならず配列がそのまま表示される labelから文字列同士を+で連結して1本の文字列にしてしまっている 複数行にしたい場合は文字列の配列をreturnする

まとめ

Chart.js v4でツールチップの表示内容を変えるには、plugins.tooltip.callbackslabel / title / footer に関数を渡すだけです。桁区切りや単位付与はChart.js自体の機能ではなく、コールバック内でtoLocaleStringなどのJavaScript標準機能を使って文字列を組み立てる、という発想で十分対応できます。

v3以前のtooltips(options直下・複数形)はv4では効かない。v4はplugins.tooltip(plugins配下・単数形)に統一されている。

関連するUI事例

Chart.js v4を使ったグラフの実装例です。

あわせて読みたい

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