diff --git a/packages/x-charts/src/BarChart/BarChart.tsx b/packages/x-charts/src/BarChart/BarChart.tsx
index 941f724b03039..132a40f058789 100644
--- a/packages/x-charts/src/BarChart/BarChart.tsx
+++ b/packages/x-charts/src/BarChart/BarChart.tsx
@@ -25,6 +25,7 @@ import {
import { ChartsAxisHighlight, ChartsAxisHighlightProps } from '../ChartsAxisHighlight';
import { ChartsClipPath } from '../ChartsClipPath';
import { ChartsAxisSlotsComponent, ChartsAxisSlotComponentProps } from '../models/axis';
+import OnClickHandler from '../OnClickHandler';
export interface BarChartSlotsComponent
extends ChartsAxisSlotsComponent,
@@ -58,6 +59,7 @@ export interface BarChartProps
*/
slotProps?: BarChartSlotComponentProps;
layout?: BarSeriesType['layout'];
+ onClick?: (event: any, series: any, itemData: any) => void;
}
const BarChart = React.forwardRef(function BarChart(props: BarChartProps, ref) {
@@ -82,6 +84,7 @@ const BarChart = React.forwardRef(function BarChart(props: BarChartProps, ref) {
children,
slots,
slotProps,
+ onClick,
} = props;
const id = useId();
@@ -143,6 +146,7 @@ const BarChart = React.forwardRef(function BarChart(props: BarChartProps, ref) {
+
{children}
@@ -241,6 +245,7 @@ BarChart.propTypes = {
right: PropTypes.number,
top: PropTypes.number,
}),
+ onClick: PropTypes.func,
/**
* Indicate which axis to display the right of the charts.
* Can be a string (the id of the axis) or an object `ChartsYAxisProps`.
diff --git a/packages/x-charts/src/LineChart/LineChart.tsx b/packages/x-charts/src/LineChart/LineChart.tsx
index fb8a7855ec353..47fe6e91367d1 100644
--- a/packages/x-charts/src/LineChart/LineChart.tsx
+++ b/packages/x-charts/src/LineChart/LineChart.tsx
@@ -32,6 +32,7 @@ import {
LineHighlightPlotSlotsComponent,
LineHighlightPlotSlotComponentProps,
} from './LineHighlightPlot';
+import OnClickHandler from '../OnClickHandler';
export interface LineChartSlotsComponent
extends ChartsAxisSlotsComponent,
@@ -74,6 +75,7 @@ export interface LineChartProps
* @default {}
*/
slotProps?: LineChartSlotComponentProps;
+ onClick?: (event: MouseEvent, series: any, itemData: any) => void;
}
const LineChart = React.forwardRef(function LineChart(props: LineChartProps, ref) {
const {
@@ -97,6 +99,7 @@ const LineChart = React.forwardRef(function LineChart(props: LineChartProps, ref
children,
slots,
slotProps,
+ onClick,
} = props;
const id = useId();
@@ -149,6 +152,7 @@ const LineChart = React.forwardRef(function LineChart(props: LineChartProps, ref
+
{children}
@@ -251,6 +255,7 @@ LineChart.propTypes = {
right: PropTypes.number,
top: PropTypes.number,
}),
+ onClick: PropTypes.func,
/**
* Indicate which axis to display the right of the charts.
* Can be a string (the id of the axis) or an object `ChartsYAxisProps`.
diff --git a/packages/x-charts/src/OnClickHandler.tsx b/packages/x-charts/src/OnClickHandler.tsx
new file mode 100644
index 0000000000000..47a714438f9cc
--- /dev/null
+++ b/packages/x-charts/src/OnClickHandler.tsx
@@ -0,0 +1,103 @@
+import * as React from 'react';
+import { SVGContext } from './context/DrawingProvider';
+import {
+ AxisInteractionData,
+ InteractionContext,
+ ItemInteractionData,
+} from './context/InteractionProvider';
+import { TriggerOptions } from './ChartsTooltip/utils';
+import { CartesianChartSeriesType, ChartSeriesType } from './models/seriesType/config';
+import { SeriesContext } from './context/SeriesContextProvider';
+import { CartesianContext } from './context/CartesianContextProvider';
+
+function hasData(
+ trigger: TriggerOptions,
+ displayedData: null | AxisInteractionData | ItemInteractionData,
+): boolean {
+ if (trigger === 'item') {
+ return displayedData !== null;
+ }
+
+ const hasAxisXData = (displayedData as AxisInteractionData).x !== null;
+ const hasAxisYData = (displayedData as AxisInteractionData).y !== null;
+
+ return hasAxisXData || hasAxisYData;
+}
+
+interface OnClickHandlerProps {
+ trigger: any;
+ onClick?: (event: any, series: any, itemData: any) => void;
+}
+
+function OnClickHandler({ trigger, onClick }: OnClickHandlerProps) {
+ const svgRef = React.useContext(SVGContext);
+ const { item, axis } = React.useContext(InteractionContext);
+
+ const series = React.useContext(SeriesContext);
+
+ const { xAxisIds, yAxisIds } = React.useContext(CartesianContext);
+
+ React.useEffect(() => {
+ const element = svgRef.current;
+ if (element === null) {
+ return () => {};
+ }
+ const handleMouseDown = (event: MouseEvent) => {
+ event.preventDefault();
+ if (onClick == null) {
+ return;
+ }
+
+ if (trigger === 'item') {
+ const displayedData = item as ItemInteractionData;
+ const tooltipHasData = hasData(trigger, displayedData);
+
+ if (tooltipHasData) {
+ const data = series[displayedData.type]!.series[displayedData.seriesId];
+ const displayedLabel =
+ data.type === 'pie' ? data.data[displayedData.dataIndex!] : data.label;
+
+ onClick(event, displayedLabel, displayedData);
+ }
+ } else {
+ const displayedData = axis as AxisInteractionData;
+
+ if (hasData(trigger, displayedData)) {
+ const isXaxis = (displayedData.x && displayedData.x.index) !== undefined;
+ const USED_AXIS_ID = isXaxis ? xAxisIds[0] : yAxisIds[0];
+ const dataIndex = isXaxis
+ ? displayedData.x && displayedData.x.index
+ : displayedData.y && displayedData.y.index;
+
+ if (dataIndex == null) {
+ return;
+ }
+ const data: any[] = [];
+ (
+ Object.keys(series).filter((seriesType) =>
+ ['bar', 'line', 'scatter'].includes(seriesType),
+ ) as CartesianChartSeriesType[]
+ ).forEach((seriesType) => {
+ series[seriesType]!.seriesOrder.forEach((seriesId) => {
+ const seriesItem = series[seriesType]!.series[seriesId];
+ const axisKey = isXaxis ? seriesItem.xAxisKey : seriesItem.yAxisKey;
+ if (axisKey === undefined || axisKey === USED_AXIS_ID) {
+ data.push(series[seriesType]!.series[seriesId]);
+ }
+ });
+ });
+
+ onClick(event, data, displayedData);
+ }
+ }
+ };
+
+ element.addEventListener('mousedown', handleMouseDown);
+ return () => {
+ element.removeEventListener('mousedown', handleMouseDown);
+ };
+ }, [axis, item, series, svgRef, trigger, xAxisIds, yAxisIds, onClick]);
+
+ return null;
+}
+export default OnClickHandler;
diff --git a/packages/x-charts/src/PieChart/PieChart.tsx b/packages/x-charts/src/PieChart/PieChart.tsx
index a4153bf963941..e39c6be7dfb02 100644
--- a/packages/x-charts/src/PieChart/PieChart.tsx
+++ b/packages/x-charts/src/PieChart/PieChart.tsx
@@ -21,9 +21,10 @@ import {
ChartsLegendSlotsComponent,
} from '../ChartsLegend';
import { ChartsAxisHighlight, ChartsAxisHighlightProps } from '../ChartsAxisHighlight';
-import { PiePlot, PiePlotProps, PiePlotSlotComponentProps, PiePlotSlotsComponent } from './PiePlot';
+import { PiePlot, PiePlotSlotComponentProps, PiePlotSlotsComponent } from './PiePlot';
import { PieValueType } from '../models/seriesType/pie';
import { ChartsAxisSlotsComponent, ChartsAxisSlotComponentProps } from '../models/axis';
+import OnClickHandler from '../OnClickHandler';
export interface PieChartSlotsComponent
extends ChartsAxisSlotsComponent,
@@ -46,7 +47,7 @@ export interface PieChartProps
* @deprecated Consider using `slotProps.legend` instead.
*/
legend?: ChartsLegendProps;
- onClick?: PiePlotProps['onClick'];
+ onClick?: (event: any, series: any, itemData: any) => void;
slots?: PieChartSlotsComponent;
/**
@@ -117,6 +118,7 @@ function PieChart(props: PieChartProps) {
+
{children}
);
diff --git a/packages/x-charts/src/ScatterChart/ScatterChart.tsx b/packages/x-charts/src/ScatterChart/ScatterChart.tsx
index 7decd47c93be4..f970e08c53918 100644
--- a/packages/x-charts/src/ScatterChart/ScatterChart.tsx
+++ b/packages/x-charts/src/ScatterChart/ScatterChart.tsx
@@ -26,6 +26,7 @@ import {
} from '../ChartsLegend';
import { ChartsAxisHighlight, ChartsAxisHighlightProps } from '../ChartsAxisHighlight';
import { ChartsAxisSlotsComponent, ChartsAxisSlotComponentProps } from '../models/axis';
+import OnClickHandler from '../OnClickHandler';
export interface ScatterChartSlotsComponent
extends ChartsAxisSlotsComponent,
@@ -58,6 +59,7 @@ export interface ScatterChartProps
* @default {}
*/
slotProps?: ScatterChartSlotComponentProps;
+ onClick?: (event: any, series: any, itemData: any) => void;
}
const ScatterChart = React.forwardRef(function ScatterChart(props: ScatterChartProps, ref) {
@@ -80,6 +82,7 @@ const ScatterChart = React.forwardRef(function ScatterChart(props: ScatterChartP
children,
slots,
slotProps,
+ onClick,
} = props;
return (
+
{children}
);
@@ -201,6 +205,7 @@ ScatterChart.propTypes = {
right: PropTypes.number,
top: PropTypes.number,
}),
+ onClick: PropTypes.func,
/**
* Indicate which axis to display the right of the charts.
* Can be a string (the id of the axis) or an object `ChartsYAxisProps`.
diff --git a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx
index ba5924156fec0..db145b64c9554 100644
--- a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx
+++ b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx
@@ -25,6 +25,7 @@ import {
LineHighlightPlotSlotComponentProps,
} from '../LineChart/LineHighlightPlot';
import { BarPlotSlotsComponent, BarPlotSlotComponentProps } from '../BarChart/BarPlot';
+import OnClickHandler from '../OnClickHandler';
export interface SparkLineChartSlotsComponent
extends AreaPlotSlotsComponent,
@@ -97,6 +98,7 @@ export interface SparkLineChartProps
* @default {}
*/
slotProps?: SparkLineChartSlotComponentProps;
+ onClick?: (event: any, series: any, itemData: any) => void;
}
const SPARKLINE_DEFAULT_MARGIN = {
@@ -124,6 +126,7 @@ const SparkLineChart = React.forwardRef(function SparkLineChart(props: SparkLine
data,
plotType = 'line',
valueFormatter = (v: number) => v.toString(),
+ onClick,
area,
curve = 'linear',
} = props;
@@ -166,6 +169,7 @@ const SparkLineChart = React.forwardRef(function SparkLineChart(props: SparkLine
axisHighlight?.y === 'none'
}
>
+
{plotType === 'bar' && (
)}
@@ -234,6 +238,7 @@ SparkLineChart.propTypes = {
right: PropTypes.number,
top: PropTypes.number,
}),
+ onClick: PropTypes.func,
/**
* Type of plot used.
* @default 'line'