クリックイベント・インタラクション

イベントハンドリングは、チャート要素のクリック・ホバーなどのユーザー操作を検知して処理する仕組み。棒グラフのクリックでドリルダウン、凡例のクリックでフィルタリング、要素選択でデータ詳細を表示するなど、インタラクティブなダッシュボード構築に必須。

バークリックで詳細ページへ遷移、ホバーでカスタム情報パネルを表示、ブラシ選択で期間フィルタ、ズームで時系列データの拡大確認。

主なバリエーション
  • 要素クリックイベント(データポイント・バー・セグメント)
  • ホバーイベント
  • 凡例クリックイベント
  • ブラシ選択・ズーム
  • イベントからのデータ取得

ライブラリ横断比較

機能RechartsEChartsPlotly.jsChart.jsNivoApexCharts
要素クリックイベント
onClick prop
chart.on('click')
onClick prop
onClick option
onClick prop
chart.events.click
ホバーイベント
onMouseEnter
chart.on('mouseover')
onHover prop
onHover option
onMouseEnter
dataPointMouseEnter
凡例クリックイベント×
legendselectchanged
×××
legendClick
ブラシ選択/ズーム
Brush component
dataZoom
onSelected/onRelayout
プラグイン要
×
selection
イベントからのデータ取得
payload
params.value
event.points
elements[]
datum
config.globals

○ = 対応  △ = 部分対応・制限あり  × = 非対応

ライブラリ別コード例

各ライブラリでイベントハンドリングを実装する際の設定部分を抜粋しています。 動くデモは各比較ページでご確認ください。

Recharts

// Recharts: 各コンポーネントに onClick / onMouseEnter を設定
<BarChart
  data={data}
  onClick={(data, index) => {
    // チャートエリア全体のクリック
    console.log('チャートクリック:', data, index);
  }}
>
  <Bar
    dataKey="value"
    onClick={(data, index) => {
      console.log('バークリック:', data, index);
      // data = { value: 100, month: '1月', payload: {...} }
    }}
    onMouseEnter={(data, index) => {
      console.log('バーホバー:', data);
    }}
    cursor="pointer"
  />
</BarChart>

// 折れ線グラフのポイントクリック
<Line
  dataKey="value"
  activeDot={{
    onClick: (event, data) => {
      console.log('ポイントクリック:', data);
    },
  }}
/>

ECharts

// ECharts: chart.on() でイベントを登録
import * as echarts from 'echarts';

const chart = echarts.init(chartRef.current);
chart.setOption(option);

// クリックイベント
chart.on('click', (params) => {
  console.log(
    'クリック:', params.seriesName, params.name, params.value
  );
  // params.componentType: 'series' | 'markPoint' など
  // params.seriesIndex, params.dataIndex, params.data
});

// ホバーイベント
chart.on('mouseover', (params) => {
  console.log('ホバー:', params.name, params.value);
});

// 凡例クリック
chart.on('legendselectchanged', (params) => {
  console.log('凡例トグル:', params.name, params.selected);
});

// イベントを解除
// chart.off('click');

Plotly.js

// react-plotly.js: イベントプロップで処理
import Plot from 'react-plotly.js';

<Plot
  data={data}
  layout={layout}

  // クリックイベント
  onClick={(event) => {
    const point = event.points[0];
    console.log('クリック:', point.x, point.y, point.data.name);
  }}

  // ホバーイベント
  onHover={(event) => {
    const point = event.points[0];
    console.log('ホバー:', point.x, point.y);
  }}

  // 選択イベント(ボックス/ラッソ選択)
  onSelected={(event) => {
    if (event?.points) {
      const selected = event.points.map(p => ({ x: p.x, y: p.y }));
      console.log('選択:', selected);
    }
  }}

  // ズームイベント
  onRelayout={(event) => {
    console.log('ズーム/パン:', event['xaxis.range[0]'], event['xaxis.range[1]']);
  }}
/>

Chart.js

// Chart.js: onClick / onHover オプションで処理
const options = {
  onClick: (event, elements, chart) => {
    if (elements.length > 0) {
      const element = elements[0];
      const datasetIndex = element.datasetIndex;
      const dataIndex = element.index;
      const value = chart.data.datasets[datasetIndex].data[dataIndex];
      const label = chart.data.labels[dataIndex];
      console.log(`クリック: ${label} = ${value}`);
    }
  },

  onHover: (event, elements, chart) => {
    // ホバー時のカーソルを変更
    event.native.target.style.cursor =
      elements.length > 0 ? 'pointer' : 'default';
  },

  // ホバー検出の設定
  interaction: {
    mode: 'nearest',     // 'point' | 'index' | 'dataset' | 'nearest' | 'x' | 'y'
    intersect: true,
  },
};

Nivo

import { ResponsiveBar } from '@nivo/bar';

// onClick / onMouseEnter / onMouseLeave プロップ
<ResponsiveBar
  data={data}

  onClick={(datum, event) => {
    console.log('クリック:', datum.id, datum.value, datum.indexValue);
    // datum: { id, value, formattedValue, indexValue, data, color }
  }}

  onMouseEnter={(datum, event) => {
    console.log('ホバー開始:', datum.id, datum.value);
  }}

  onMouseLeave={(datum, event) => {
    console.log('ホバー終了');
  }}
/>

// 折れ線グラフ(ResponsiveLine)
<ResponsiveLine
  data={data}
  onClick={(point, event) => {
    console.log('ポイントクリック:', point.data.x, point.data.y);
  }}
/>

ApexCharts

// ApexCharts: chart.events で各イベントを設定
const options = {
  chart: {
    events: {
      // 要素クリック
      click: (event, chartContext, config) => {
        const { seriesIndex, dataPointIndex } = config;
        if (dataPointIndex >= 0) {
          const value = config.globals.series[seriesIndex][dataPointIndex];
          const label = config.globals.labels[dataPointIndex];
          console.log(`クリック: ${label} = ${value}`);
        }
      },

      // データポイントホバー
      dataPointMouseEnter: (event, chartContext, config) => {
        console.log('ホバー:', config.dataPointIndex);
      },

      // 凡例クリック
      legendClick: (chartContext, seriesIndex, config) => {
        console.log('凡例クリック: 系列', seriesIndex);
      },

      // ズーム(selection / zoom が有効な場合)
      zoomed: (chartContext, { xaxis, yaxis }) => {
        console.log('ズーム:', xaxis.min, xaxis.max);
      },
    },
  },
};

まとめ・選び方のヒント

  • Reactらしいイベント設定 → Recharts・Nivo・Plotly.js(react-plotly.js)(props として渡せる)
  • 命令的なイベント登録 → ECharts(chart.on()でイベントリスナーを登録)
  • 凡例クリックイベントが充実 → ECharts(legendselectchanged)・ApexCharts(legendClick)
  • ブラシ選択・ズームが組み込み → ECharts(dataZoom)・ApexCharts(selection)・Plotly.js(box select/lasso)
  • クリックデータの取り出し方 → ライブラリによってコールバック引数の構造が異なるため、コード例を参照