凡例(Legend)の配置・スタイル
凡例(Legend)は、チャート内の各データ系列が何を表しているかを示すラベル付きのインジケーター。複数系列を扱うチャートで、色やマーカーとデータの対応関係を明示するために使われる。
配置位置の変更(上・下・左・右)、ブランドに合わせたスタイリング、クリックによる系列の表示/非表示トグル、多系列時のスクロール対応。
主なバリエーション
- •配置位置の変更(上・下・左・右・チャート内)
- •カスタムアイコン・マーカー
- •クリックによる系列の表示/非表示トグル
- •スクロール可能な凡例(多系列対応)
- •カスタムHTML/JSXでの完全置き換え
ライブラリ横断比較
| 機能 | Recharts | ECharts | Plotly.js | Chart.js | Nivo | ApexCharts |
|---|---|---|---|---|---|---|
| 配置位置の変更 | ○ layout/verticalAlign/align | ○ left/top/orient | ○ x/y/orientation | ○ position/align | ○ anchor | ○ position/horizontalAlign |
| カスタムアイコン/マーカー | ○ iconType | ○ icon | △ 部分対応 | ○ usePointStyle | ○ symbolShape | ○ markers.shape |
| クリックで系列トグル | ○ デフォルト対応 | ○ selectedMode | ○ itemclick | ○ onClick cb | ○ toggleSerie | ○ onItemClick |
| スクロール可能な凡例 | × | ○ type:"scroll" | × | × | × | × |
| カスタムHTML/JSX | ○ content prop | × | × | × | × | × |
| スタイルカスタマイズ | ○ style/wrapperStyle | ○ textStyle | ○ font/bgcolor | ○ labels.font | ○ theme | ○ fontSize/labels |
○ = 対応 △ = 部分対応・制限あり × = 非対応
ライブラリ別コード例
各ライブラリで凡例をカスタマイズする際の設定部分を抜粋しています。 動くデモは各比較ページでご確認ください。
Recharts
import { Legend, LineChart, Line } from 'recharts';
// 基本的な配置設定
<LineChart data={data}>
<Legend
layout="horizontal" // 'horizontal' | 'vertical'
verticalAlign="bottom" // 'top' | 'middle' | 'bottom'
align="center" // 'left' | 'center' | 'right'
iconType="circle" // 'line' | 'square' | 'rect' | 'circle' | 'diamond' | 'star' | 'triangle' | 'wye'
iconSize={10}
/>
</LineChart>
// カスタムレンダラーで完全置き換え
const renderCustomLegend = (props) => {
const { payload } = props;
return (
<ul className="flex gap-4 justify-center mt-2">
{payload.map((entry, index) => (
<li key={index} className="flex items-center gap-1 text-sm">
<span
style={{
background: entry.color,
width: 12,
height: 12,
borderRadius: '50%',
display: 'inline-block',
}}
/>
{entry.value}
</li>
))}
</ul>
);
};
<Legend content={renderCustomLegend} />ECharts
// ECharts: legend オブジェクトで設定
const option = {
legend: {
show: true,
type: 'plain', // 'plain' | 'scroll'(スクロール対応・多系列向け)
orient: 'horizontal', // 'horizontal' | 'vertical'
left: 'center', // 'left' | 'center' | 'right' | px
top: 'bottom', // 'top' | 'middle' | 'bottom' | px
// アイコンスタイル
icon: 'circle', // 'circle' | 'rect' | 'triangle' | 'roundRect' など
itemWidth: 14,
itemHeight: 14,
// テキストスタイル
textStyle: { fontSize: 12, color: '#374151' },
// クリックで系列トグル(デフォルトで有効)
selectedMode: true, // true | false | 'single' | 'multiple'
// スクロール型(多系列対応)
// type: 'scroll',
// pageButtonPosition: 'end',
},
};Plotly.js
// Plotly.js: layout.legend で設定
const layout = {
showlegend: true,
legend: {
x: 0, // 0〜1(0=左端、1=右端)
y: 1, // 0〜1(0=下端、1=上端)
xanchor: 'left',
yanchor: 'auto',
orientation: 'h', // 'v'(縦)| 'h'(横)
// スタイル
bgcolor: 'rgba(255,255,255,0.8)',
bordercolor: '#e5e7eb',
borderwidth: 1,
font: { size: 12, color: '#374151' },
// アイテムクリックで系列トグル
itemclick: 'toggle', // 'toggle' | 'toggleothers' | false
itemdoubleclick: 'toggleothers',
},
};Chart.js
// Chart.js: plugins.legend で設定
const options = {
plugins: {
legend: {
display: true,
position: 'bottom', // 'top' | 'bottom' | 'left' | 'right' | 'chartArea'
align: 'center', // 'start' | 'center' | 'end'
labels: {
boxWidth: 12,
boxHeight: 12,
usePointStyle: true, // 折れ線グラフの点スタイルを使用
padding: 16,
font: { size: 12 },
color: '#374151',
// 特定系列をラベルから除外
filter: (item) => item.text !== '非表示系列',
},
// クリックハンドラ(デフォルトは表示/非表示トグル)
onClick: (e, legendItem, legend) => {
const index = legendItem.datasetIndex;
const ci = legend.chart;
ci.setDatasetVisibility(index, !ci.isDatasetVisible(index));
ci.update();
},
},
},
};Nivo
import { ResponsiveBar } from '@nivo/bar';
// legends プロップで設定(デフォルトは非表示のため明示が必要)
<ResponsiveBar
data={data}
keys={['series1', 'series2', 'series3']}
legends={[
{
dataFrom: 'keys', // 'keys' | 'indexes'
anchor: 'bottom', // 配置位置('top' | 'bottom' | 'left' | 'right' など)
direction: 'row', // 'row' | 'column'
justify: false,
translateX: 0,
translateY: 56,
itemsSpacing: 16,
itemWidth: 100,
itemHeight: 20,
symbolSize: 12,
symbolShape: 'circle', // 'circle' | 'square' | 'diamond' | 'triangle'
// クリックで系列トグル
toggleSerie: true,
},
]}
/>ApexCharts
// ApexCharts: legend オブジェクトで設定
const options = {
legend: {
show: true,
position: 'bottom', // 'top' | 'bottom' | 'left' | 'right'
horizontalAlign: 'center', // 'left' | 'center' | 'right'
// スタイル
fontSize: '13px',
fontFamily: 'inherit',
labels: {
colors: ['#374151'],
useSeriesColors: false,
},
// アイコン形状
markers: {
size: 6,
shape: 'circle', // 'circle' | 'square' | 'line' | 'plus' | 'cross'
offsetX: 0,
offsetY: 0,
},
// クリックで系列トグル(デフォルトで有効)
onItemClick: {
toggleDataSeries: true,
},
onItemHover: {
highlightDataSeries: true,
},
},
};まとめ・選び方のヒント
- •JSXで完全カスタマイズしたい → Recharts(content propにReactコンポーネントを渡せる)
- •多系列でスクロール対応が必要 → ECharts(type: 'scroll'で多系列凡例に対応)
- •クリックで系列トグルのデフォルト動作 → 全ライブラリで対応(設定方法は異なる)
- •JSON設定だけで柔軟にカスタマイズ → ECharts・ApexCharts(豊富なオプション)
- •Nivoで凡例を表示するには → legends配列を明示的に指定(デフォルトでは非表示)