Skip to content

Commit

Permalink
[charts] Add onClick support (#11411)
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandre Fauquette <[email protected]>
  • Loading branch information
alexfauquette authored Feb 1, 2024
1 parent 5db3711 commit 9d35151
Show file tree
Hide file tree
Showing 60 changed files with 1,243 additions and 93 deletions.
4 changes: 4 additions & 0 deletions docs/data/charts-component-api-pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ const apiPages: MuiPage[] = [
pathname: '/x/api/charts/charts-legend',
title: 'ChartsLegend',
},
{
pathname: '/x/api/charts/charts-on-axis-click-handler',
title: 'ChartsOnAxisClickHandler',
},
{
pathname: '/x/api/charts/charts-reference-line',
title: 'ChartsReferenceLine',
Expand Down
96 changes: 96 additions & 0 deletions docs/data/charts/bars/BarClickNoSnap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import * as React from 'react';
import Stack from '@mui/material/Stack';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import IconButton from '@mui/material/IconButton';
import UndoOutlinedIcon from '@mui/icons-material/UndoOutlined';

import { BarChart } from '@mui/x-charts/BarChart';

import HighlightedCode from 'docs/src/modules/components/HighlightedCode';

const barChartsParams = {
series: [
{
id: 'series-1',
data: [3, 4, 1, 6, 5],
label: 'A',
stack: 'total',
highlightScope: {
highlighted: 'item',
},
},
{
id: 'series-2',
data: [4, 3, 1, 5, 8],
label: 'B',
stack: 'total',
highlightScope: {
highlighted: 'item',
},
},
{
id: 'series-3',
data: [4, 2, 5, 4, 1],
label: 'C',
highlightScope: {
highlighted: 'item',
},
},
],
xAxis: [{ data: ['0', '3', '6', '9', '12'], scaleType: 'band', id: 'axis1' }],
height: 400,
};

export default function BarClickNoSnap() {
const [itemData, setItemData] = React.useState();
const [axisData, setAxisData] = React.useState();

return (
<Stack
direction={{ xs: 'column', md: 'row' }}
spacing={{ xs: 0, md: 4 }}
sx={{ width: '100%' }}
>
<Box sx={{ flexGrow: 1 }}>
<BarChart
{...barChartsParams}
onItemClick={(event, d) => setItemData(d)}
onAxisClick={(event, d) => setAxisData(d)}
/>
</Box>

<Stack direction="column" sx={{ width: { xs: '100%', md: '40%' } }}>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<Typography>Click on the chart</Typography>
<IconButton
aria-label="reset"
size="small"
onClick={() => {
setItemData(null);
setAxisData(null);
}}
>
<UndoOutlinedIcon fontSize="small" />
</IconButton>
</Box>
<HighlightedCode
code={`// Data from item click
${itemData ? JSON.stringify(itemData, null, 2) : '// The data will appear here'}
// Data from axis click
${axisData ? JSON.stringify(axisData, null, 2) : '// The data will appear here'}
`}
language="json"
copyButtonHidden
/>
</Stack>
</Stack>
);
}
44 changes: 43 additions & 1 deletion docs/data/charts/bars/bars.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: React Bar chart
productId: x-charts
components: BarChart, BarElement, BarPlot
components: BarChart, BarElement, BarPlot, ChartsOnAxisClickHandler
---

# Charts - Bars
Expand Down Expand Up @@ -64,6 +64,48 @@ If you're using [composition](/x/react-charts/composition/), you should set the

{{"demo": "HorizontalBars.js"}}

## Click event

Bar charts provides two click handlers:

- `onItemClick` for click on a specific bar.
- `onAxisClick` for a click anywhere in the chart

They both provide the following signature.

```js
const clickHandler = (
event, // The mouse event.
params, // An object that identifies the clicked elements.
) => {};
```

{{"demo": "BarClickNoSnap.js"}}

:::info
Their is a slight difference between the `event` of `onItemClick` and `onAxisClick`:

- For `onItemClick` it's a React synthetic mouse event emitted by the bar component.
- For `onAxisClick` it's a native mouse event emitted by the svg component.

:::

### Composition

If you're using composition, you can get those click event as follow.
Notice that the `onAxisClick` will handle both bar and line series if you mix them.

```jsx
import ChartsOnAxisClickHandler from '@mui/x-charts/ChartsOnAxisClickHandler';
// ...

<ChartContainer>
{/* ... */}
<ChartsOnAxisClickHandler onAxisClick={onAxisClick} />
<BarPlot onItemClick={onItemClick} />
</ChartContainer>;
```

## Animation

To skip animation at the creation and update of your chart, you can use the `skipAnimation` prop.
Expand Down
102 changes: 102 additions & 0 deletions docs/data/charts/lines/LineClickNoSnap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import * as React from 'react';
import Stack from '@mui/material/Stack';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import IconButton from '@mui/material/IconButton';
import UndoOutlinedIcon from '@mui/icons-material/UndoOutlined';

import { LineChart } from '@mui/x-charts/LineChart';

import HighlightedCode from 'docs/src/modules/components/HighlightedCode';

const lineChartsParams = {
series: [
{
id: 'series-1',
data: [3, 4, 1, 6, 5],
label: 'A',
area: true,
stack: 'total',
highlightScope: {
highlighted: 'item',
},
},
{
id: 'series-2',
data: [4, 3, 1, 5, 8],
label: 'B',
area: true,
stack: 'total',
highlightScope: {
highlighted: 'item',
},
},
{
id: 'series-3',
data: [4, 2, 5, 4, 1],
label: 'C',
area: true,
stack: 'total',
highlightScope: {
highlighted: 'item',
},
},
],
xAxis: [{ data: [0, 3, 6, 9, 12], scaleType: 'linear', id: 'axis1' }],
height: 400,
};

export default function LineClickNoSnap() {
const [itemData, setItemData] = React.useState();
const [axisData, setAxisData] = React.useState();

return (
<Stack
direction={{ xs: 'column', md: 'row' }}
spacing={{ xs: 0, md: 4 }}
sx={{ width: '100%' }}
>
<Box sx={{ flexGrow: 1 }}>
<LineChart
{...lineChartsParams}
onAreaClick={(event, d) => setItemData(d)}
onMarkClick={(event, d) => setItemData(d)}
onLineClick={(event, d) => setItemData(d)}
onAxisClick={(event, d) => setAxisData(d)}
/>
</Box>

<Stack direction="column" sx={{ width: { xs: '100%', md: '40%' } }}>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<Typography>Click on the chart</Typography>
<IconButton
aria-label="reset"
size="small"
onClick={() => {
setItemData(null);
setAxisData(null);
}}
>
<UndoOutlinedIcon fontSize="small" />
</IconButton>
</Box>
<HighlightedCode
code={`// Data from item click
${itemData ? JSON.stringify(itemData, null, 2) : '// The data will appear here'}
// Data from axis click
${axisData ? JSON.stringify(axisData, null, 2) : '// The data will appear here'}
`}
language="json"
copyButtonHidden
/>
</Stack>
</Stack>
);
}
47 changes: 46 additions & 1 deletion docs/data/charts/lines/lines.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: React Line chart
productId: x-charts
components: LineChart, LineElement, LineHighlightElement, LineHighlightPlot, LinePlot, MarkElement, MarkPlot, AreaElement, AreaPlot, AnimatedLine, AnimatedArea
components: LineChart, LineElement, LineHighlightElement, LineHighlightPlot, LinePlot, MarkElement, MarkPlot, AreaElement, AreaPlot, AnimatedLine, AnimatedArea, ChartsOnAxisClickHandler
---

# Charts - Lines
Expand Down Expand Up @@ -91,6 +91,51 @@ However, it cannot extrapolate the curve before the first non-null data point or

{{"demo": "ConnectNulls.js"}}

## Click event

Line charts provides multiple click handlers:

- `onAreaClick` for click on a specific area.
- `onLineClick` for click on a specific line.
- `onMarkClick` for click on a specific mark.
- `onAxisClick` for a click anywhere in the chart

They all provide the following signature.

```js
const clickHandler = (
event, // The mouse event.
params, // An object that identifies the clicked elements.
) => {};
```

{{"demo": "LineClickNoSnap.js"}}

:::info
Their is a slight difference between the `event` of `onAxisClick` and the others:

- For `onAxisClick` it's a native mouse event emitted by the svg component.
- For others, it's a React synthetic mouse event emitted by the area, line, or mark component.

:::

### Composition

If you're using composition, you can get those click event as follow.
Notice that the `onAxisClick` will handle both bar and line series if you mix them.

```jsx
import ChartsOnAxisClickHandler from '@mui/x-charts/ChartsOnAxisClickHandler';
// ...

<ChartContainer>
{/* ... */}
<ChartsOnAxisClickHandler onAxisClick={onAxisClick} />
<LinePlot onItemClick={onLineClick} />
<AreaPlot onItemClick={onAreaClick} />
</ChartContainer>;
```

## Styling

### Interpolation
Expand Down
Loading

0 comments on commit 9d35151

Please sign in to comment.