Click events & drill-down
Every chart fires onClick (vanilla) / onPointClick (React) when the user clicks a hovered datum. The handler receives a third argument — a ChartClickEvent — with everything you need to identify what was clicked.
Try it
Section titled “Try it”Click any bar with a mouse, or tap one on a touch device. The badge below the chart reports the label, value, modifier keys, and whether the input came from mouse or touch.
interface ChartClickEvent<TDatum = Record<string, any>> { index: number; // datum index along the chart's primary axis seriesIndex: number; // -1 when click is not series-specific label: string; // categorical label at `index` (e.g. x-tick) value: number; // numeric value at the clicked position datum: TDatum | undefined; // the original row passed to setData() series: Dataset | undefined; data: ResolvedData; // same as the second positional argument nativeEvent: MouseEvent; // for stopPropagation, modifier keys, coordinates}Drill-down navigation
Section titled “Drill-down navigation”Use event.datum to navigate using the original row — no need to keep a parallel lookup.
import { Bar } from '@arshad-shah/swift-chart/react';import { useRouter } from 'next/router';
export function RevenueByRegion({ orders }) { const router = useRouter(); return ( <Bar data={orders} mapping={{ x: 'region', y: 'revenue' }} onPointClick={(_i, _d, e) => { if (!e.datum) return; router.push(`/regions/${e.datum.id}`); }} /> );}Modifier-key behaviour
Section titled “Modifier-key behaviour”Open in a new tab on ⌘-click (or middle-click) instead of replacing the current view.
onPointClick={(_i, _d, e) => { const url = `/orders/${e.datum.id}`; if (e.nativeEvent.metaKey || e.nativeEvent.ctrlKey) { window.open(url, '_blank'); } else { router.push(url); }}}Analytics
Section titled “Analytics”onPointClick={(_i, _d, e) => { analytics.track('chart_click', { chart: 'revenue_by_region', label: e.label, value: e.value, series: e.series?.label, seriesIndex: e.seriesIndex, });}}Series-aware vs column-wide clicks
Section titled “Series-aware vs column-wide clicks”event.seriesIndex reports which series was clicked when the chart can pinpoint one:
| Chart | seriesIndex on click |
|---|---|
| Single-series (pie, treemap, gauge) | 0 |
| Bubble / scatter | the group index — clicks land on a single point |
| Heatmap | the row (y-axis) index of the clicked cell |
| Marimekko | the row index of the clicked segment |
| Multi-series line / area / grouped-bar | -1 — the click is column-wide, no single series is identified |
When seriesIndex is -1, event.series is undefined and event.value is NaN — read event.label and event.data.datasets instead.
When datum is undefined
Section titled “When datum is undefined”event.datum is the original row from setData(rows, mapping). It is undefined when:
- the chart was fed a pre-built
{ labels, datasets }shape (the original row never existed) - the chart’s internal layout breaks index alignment (heatmap — read
event.labelandevent.valueinstead)
Sankey and network charts surface the clicked node object as event.datum.
Vanilla / imperative
Section titled “Vanilla / imperative”import { BarChart } from '@arshad-shah/swift-chart';
new BarChart('#chart', { onClick: (index, data, event) => { console.log('clicked', event.label, event.value, event.datum); },}).setData(orders, { x: 'region', y: 'revenue' });Touch devices
Section titled “Touch devices”A finger tap on a chart fires the same onClick / onPointClick handler with the index of the touched datum — event.nativeEvent is the synthetic MouseEvent that the browser dispatches after touchend, so modifier-key checks (metaKey, ctrlKey) read as false on touch. Use event.label, event.value, and event.datum for routing logic that needs to work on both pointers and touch.
Backward compatibility
Section titled “Backward compatibility”The third argument is additive — existing two-argument handlers (index, data) => … keep working unchanged.