ツールチップのカスタマイズ
ツールチップ(Tooltip)は、チャート上の要素にホバーしたときに詳細データを表示するポップアップUI。デフォルトのスタイルや表示内容では対応できない場合に、カスタムコンポーネントやフォーマッタ関数でカスタマイズする。
デザインに合わせたスタイル変更、単位・通貨の付加、複数系列の一括表示、条件付き非表示など、ユーザーが数値を素早く把握できる情報密度の調整が主なユースケース。
主なバリエーション
- •表示内容の変更(値のフォーマット・単位追加・複数系列の一括表示)
- •カスタムHTML/Reactコンポーネントでの完全置き換え
- •スタイル変更(背景色・フォント・影・角丸)
- •表示位置の制御(カーソル追従・固定・オフセット)
- •表示/非表示の条件制御
ライブラリ横断比較
| 機能 | Recharts | ECharts | Plotly.js | Chart.js | Nivo | ApexCharts |
|---|---|---|---|---|---|---|
| カスタムHTML/JSX | ○ content prop | ○ formatter | △ hovertemplate | ○ external cb | ○ tooltip prop | ○ custom fn |
| フォーマッタ関数 | ○ formatter | ○ formatter | ○ hovertemplate | ○ callbacks | ○ format | ○ y.formatter |
| 表示位置の制御 | △ 限定的 | ○ position fn | ○ layout設定 | ○ position | ○ followCursor | ○ followCursor |
| 遅延設定 | × | ○ showDelay | × | × | × | × |
| 複数系列の一括表示 | ○ デフォルト | ○ trigger:axis | ○ hovermode | ○ mode:index | △ 種類による | ○ shared |
| スタイルカスタマイズ | CSS | CSS+設定 | 設定 | 設定 | theme | 設定 |
○ = 対応 △ = 部分対応・制限あり × = 非対応
ライブラリ別コード例
各ライブラリでツールチップをカスタマイズする際の設定部分を抜粋しています。 動くデモは各比較ページでご確認ください。
Recharts
// カスタムツールチップコンポーネント(JSXで自由にレイアウト)
const CustomTooltip = ({ active, payload, label }) => {
if (active && payload?.length) {
return (
<div className="bg-white p-3 border border-gray-200 rounded shadow-md text-sm">
<p className="font-bold mb-1">{label}</p>
{payload.map((entry, i) => (
<p key={i} style={{ color: entry.color }}>
{entry.name}: {entry.value.toLocaleString()}
</p>
))}
</div>
);
}
return null;
};
// content prop にコンポーネントを渡す
<LineChart data={data}>
<Tooltip content={<CustomTooltip />} />
</LineChart>
// フォーマッタだけ変えたい場合
<Tooltip formatter={(value, name) => [`${value.toLocaleString()} 件`, name]} />ECharts
// ECharts: formatter 関数でHTMLを返す
const option = {
tooltip: {
trigger: 'axis', // 'axis' で複数系列を一括表示
formatter: (params) => {
let html = `<b>${params[0].name}</b><br/>`;
params.forEach(p => {
html += `${p.marker}${p.seriesName}: ${p.value.toLocaleString()}<br/>`;
});
return html;
},
backgroundColor: '#fff',
borderColor: '#e5e7eb',
textStyle: { color: '#374151' },
// 表示遅延制御(ECharts のみ)
showDelay: 0,
hideDelay: 100,
// 表示位置を関数で制御
position: (point, params, dom, rect, size) => {
return [point[0] + 10, point[1] - 30];
},
},
};Plotly.js
// Plotly.js: hovertemplate でツールチップ内容を制御
const data = [{
type: 'scatter',
x: ['1月', '2月', '3月', '4月', '5月'],
y: [100, 150, 130, 170, 200],
// %{x}, %{y} でデータを参照。<extra></extra> で系列名を非表示
hovertemplate: '<b>%{x}</b><br>売上: %{y:,}件<extra></extra>',
// hoverlabel でスタイルを変更
hoverlabel: {
bgcolor: '#1e293b',
bordercolor: '#475569',
font: { color: 'white', size: 13 },
},
}];
// 複数系列は hoverdistance / spikedistance で制御
const layout = {
hovermode: 'x unified', // 複数系列を一括表示
};Chart.js
// Chart.js: callbacks でラベルをカスタマイズ
const options = {
plugins: {
tooltip: {
callbacks: {
title: (items) => `📅 ${items[0].label}`,
label: (item) =>
` ${item.dataset.label}: ${item.parsed.y.toLocaleString()} 件`,
labelColor: (item) => ({
borderColor: item.dataset.borderColor,
backgroundColor: item.dataset.backgroundColor,
}),
},
// external で完全カスタムHTML(DOM操作)
// external: (context) => { ... },
// スタイル設定
backgroundColor: 'rgba(255,255,255,0.95)',
titleColor: '#111827',
bodyColor: '#374151',
borderColor: '#e5e7eb',
borderWidth: 1,
// 複数系列一括表示
mode: 'index',
intersect: false,
},
},
};Nivo
// Nivo: tooltip prop に React コンポーネントを渡す
import { ResponsiveLine } from '@nivo/line';
const CustomTooltip = ({ point }) => (
<div style={{
background: 'white',
padding: '8px 12px',
border: '1px solid #e5e7eb',
borderRadius: '6px',
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
}}>
<strong style={{ color: point.serieColor }}>{point.serieId}</strong>
<div>x: {point.data.xFormatted}</div>
<div>y: {point.data.yFormatted}</div>
</div>
);
<ResponsiveLine
data={data}
tooltip={CustomTooltip}
// followCursor で追従位置を制御
// ※ Nivo はデフォルトで系列ごとの個別ツールチップ
// 複数系列一括表示はチャート種類によって異なる
/>ApexCharts
// ApexCharts: y.formatter で値をカスタマイズ
const options = {
tooltip: {
y: {
formatter: (val) => `${val.toLocaleString()} 件`,
title: {
formatter: (seriesName) => `${seriesName}:`,
},
},
// custom で完全カスタムHTML
custom: ({ series, seriesIndex, dataPointIndex, w }) => {
const val = series[seriesIndex][dataPointIndex];
const label = w.globals.labels[dataPointIndex];
return `<div class="p-2 bg-white border rounded shadow text-sm">
<strong>${label}</strong><br/>
${val.toLocaleString()} 件
</div>`;
},
// 共有ツールチップ(複数系列一括)
shared: true,
followCursor: true,
},
};まとめ・選び方のヒント
- •JSXで自由にレイアウトしたい → Recharts・Nivo(Reactコンポーネントとして記述可能)
- •設定オブジェクトで手軽に済ませたい → ECharts・ApexCharts(formatter関数で大抵のケースに対応)
- •データサイエンス寄りの表示 → Plotly.js(hovertemplateで統計値の書式設定が簡単)
- •複数系列を一括表示したい → Recharts・ECharts・Chart.js・ApexCharts(Nivoは種類による)
- •表示遅延を制御したい → ECharts(showDelay/hideDelay を設定可能)