Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[charts] Allow Zoom to be controllable #13858

Merged
merged 31 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
200f1cf
Setup controllable zoom provider
JCQuintas Jul 16, 2024
edd7287
Add props to chart components
JCQuintas Jul 16, 2024
490976b
Make sure props are passed to base components
JCQuintas Jul 16, 2024
2e1729c
Pass props to responsive container
JCQuintas Jul 16, 2024
a9bca05
Update typings
JCQuintas Jul 16, 2024
fa493a1
update setup zoom
JCQuintas Jul 16, 2024
6a22d69
use useCallback for function
JCQuintas Jul 16, 2024
0881fef
Add example
JCQuintas Jul 16, 2024
84c37b4
Diff will be reset at end
JCQuintas Jul 16, 2024
11fa572
Merge commit '8f3964d87a73fe7f463db05d004ba14cdc79d158' into zoom-con…
JCQuintas Jul 16, 2024
cbe460b
Update zoom and onZoomChange types
JCQuintas Jul 16, 2024
efd54c8
Update proptypes
JCQuintas Jul 16, 2024
474fe38
disable zoom props on heatmap
JCQuintas Jul 16, 2024
aa54fe5
Improve typings
JCQuintas Jul 16, 2024
3582782
Export only necessary public typings
JCQuintas Jul 16, 2024
f88f2e9
Update api
JCQuintas Jul 16, 2024
3532c2e
Merge commit '45facf87e7b86072c26ce8ffd71b26d256bc3c24' into zoom-con…
JCQuintas Jul 16, 2024
18b8b11
Apply suggestions from code review
JCQuintas Jul 17, 2024
5c6cb0e
From ...restProps to ...other
JCQuintas Jul 17, 2024
f447c60
Move useResponsiveChartContainerProps inside the pro version
JCQuintas Jul 17, 2024
59afaa6
Don't initialize zoom data for users
JCQuintas Jul 17, 2024
9063bff
Ensure app doesn't break with wrong axis id
JCQuintas Jul 17, 2024
8cbff71
Update API and document important public apis
JCQuintas Jul 17, 2024
5264729
Initialize zoom when not controlled
JCQuintas Jul 17, 2024
e089235
Got to initialize data regardless of control
JCQuintas Jul 17, 2024
cf74279
Merge commit 'cd68580bd2c80a44960952ce8fbdddf7c2ccbd89' into zoom-con…
JCQuintas Jul 18, 2024
dd59b07
Fix case
JCQuintas Jul 18, 2024
b9650e0
move entire hook logic to pro hook
JCQuintas Jul 22, 2024
ada828c
remove [[...]] usage
JCQuintas Jul 22, 2024
3b92675
Move default zoom data initialization to provider
JCQuintas Jul 22, 2024
43ab3fa
Use ref to prevent re-renders
JCQuintas Jul 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions docs/data/charts/zoom-and-pan/ZoomControlled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import * as React from 'react';
import { LineChartPro } from '@mui/x-charts-pro/LineChartPro';

import { Button } from '@mui/base';

export default function ZoomControlled() {
const [zoom, setZoom] = React.useState([
{
axisId: 'my-x-axis',
start: 20,
end: 40,
},
]);

return (
<div>
<Button onClick={() => setZoom([{ axisId: 'my-x-axis', start: 0, end: 100 }])}>
Reset zoom
</Button>
<LineChartPro
{...chartProps}
zoom={zoom}
onZoomChange={setZoom}
xAxis={[
{
zoom: true,
scaleType: 'point',
id: 'my-x-axis',
data: data.map((v, i) => i),
},
]}
/>
</div>
);
}

const data = [
{
y1: 443.28,
y2: 153.9,
},
{
y1: 110.5,
y2: 217.8,
},
{
y1: 175.23,
y2: 286.32,
},
{
y1: 195.97,
y2: 325.12,
},
{
y1: 351.77,
y2: 144.58,
},
{
y1: 43.253,
y2: 146.51,
},
{
y1: 376.34,
y2: 309.69,
},
{
y1: 31.514,
y2: 236.38,
},
{
y1: 231.31,
y2: 440.72,
},
{
y1: 108.04,
y2: 20.29,
},
{
y1: 321.77,
y2: 484.17,
},
{
y1: 120.18,
y2: 54.962,
},
{
y1: 366.2,
y2: 418.5,
},
{
y1: 451.45,
y2: 181.32,
},
{
y1: 294.8,
y2: 440.9,
},
{
y1: 121.83,
y2: 273.52,
},
{
y1: 287.7,
y2: 346.7,
},
{
y1: 134.06,
y2: 74.528,
},
{
y1: 104.5,
y2: 150.9,
},
{
y1: 413.07,
y2: 26.483,
},
{
y1: 74.68,
y2: 333.2,
},
{
y1: 360.6,
y2: 422.0,
},
{
y1: 330.72,
y2: 488.06,
},
];

const chartProps = {
width: 600,
height: 300,
series: [
{
label: 'Series A',
data: data.map((v) => v.y1),
},
{
label: 'Series B',
data: data.map((v) => v.y2),
},
],
};
145 changes: 145 additions & 0 deletions docs/data/charts/zoom-and-pan/ZoomControlled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import * as React from 'react';
import { LineChartPro } from '@mui/x-charts-pro/LineChartPro';
import { ZoomData } from '@mui/x-charts-pro/context';
import { Button } from '@mui/base';

export default function ZoomControlled() {
const [zoom, setZoom] = React.useState<ZoomData[]>([
{
axisId: 'my-x-axis',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently axisId is required. Should we allow {start,end} to be passed when there is only one zoom enabled?

start: 20,
end: 40,
},
]);

return (
<div>
<Button onClick={() => setZoom([{ axisId: 'my-x-axis', start: 0, end: 100 }])}>
Reset zoom
</Button>
<LineChartPro
{...chartProps}
zoom={zoom}
onZoomChange={setZoom}
xAxis={[
{
zoom: true,
scaleType: 'point',
id: 'my-x-axis',
data: data.map((v, i) => i),
},
]}
/>
</div>
);
}

const data = [
{
y1: 443.28,
y2: 153.9,
},
{
y1: 110.5,
y2: 217.8,
},
{
y1: 175.23,
y2: 286.32,
},
{
y1: 195.97,
y2: 325.12,
},
{
y1: 351.77,
y2: 144.58,
},
{
y1: 43.253,
y2: 146.51,
},
{
y1: 376.34,
y2: 309.69,
},
{
y1: 31.514,
y2: 236.38,
},
{
y1: 231.31,
y2: 440.72,
},
{
y1: 108.04,
y2: 20.29,
},
{
y1: 321.77,
y2: 484.17,
},
{
y1: 120.18,
y2: 54.962,
},
{
y1: 366.2,
y2: 418.5,
},
{
y1: 451.45,
y2: 181.32,
},
{
y1: 294.8,
y2: 440.9,
},
{
y1: 121.83,
y2: 273.52,
},
{
y1: 287.7,
y2: 346.7,
},
{
y1: 134.06,
y2: 74.528,
},
{
y1: 104.5,
y2: 150.9,
},
{
y1: 413.07,
y2: 26.483,
},
{
y1: 74.68,
y2: 333.2,
},
{
y1: 360.6,
y2: 422.0,
},
{
y1: 330.72,
y2: 488.06,
},
];

const chartProps = {
width: 600,
height: 300,
series: [
{
label: 'Series A',
data: data.map((v) => v.y1),
},
{
label: 'Series B',
data: data.map((v) => v.y2),
},
],
};
16 changes: 16 additions & 0 deletions docs/data/charts/zoom-and-pan/ZoomControlled.tsx.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Button onClick={() => setZoom([{ axisId: 'my-x-axis', start: 0, end: 100 }])}>
Reset zoom
</Button>
<LineChartPro
{...chartProps}
zoom={zoom}
onZoomChange={setZoom}
xAxis={[
{
zoom: true,
scaleType: 'point',
id: 'my-x-axis',
data: data.map((v, i) => i),
},
]}
/>
14 changes: 14 additions & 0 deletions docs/data/charts/zoom-and-pan/zoom-and-pan.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,17 @@ The following options are available:
- **panning**: Enables or disables panning.

{{"demo": "ZoomOptionsNoSnap.js", "hideToolbar": true, "bg": "playground"}}

## Controlled Zoom

You can control the zoom state by setting the `zoom` and `onZoomChange` props. This way, you can control the zoom state from outside the chart.
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved

The `onZoomChange` prop is a function that receives the new zoom state.

While the `zoom` prop is an array of objects that define the zoom state for each axis.
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved

- **axisId**: The id of the axis to control.
- **start**: The starting percentage of the axis range. Between 0 and 100.
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved
- **end**: The ending percentage of the zoom range.

{{"demo": "ZoomControlled.js"}}
13 changes: 13 additions & 0 deletions docs/pages/x/api/charts/chart-container-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
"describedArgs": ["highlightedItem"]
}
},
"onZoomChange": {
"type": { "name": "func" },
"signature": {
"type": "function(zoomData: Array<ZoomData>) => void",
"describedArgs": ["zoomData"]
}
},
"plugins": { "type": { "name": "arrayOf", "description": "Array&lt;object&gt;" } },
"xAxis": {
"type": {
Expand All @@ -50,6 +57,12 @@
"name": "arrayOf",
"description": "Array&lt;{ colorMap?: { colors: Array&lt;string&gt;, type: 'ordinal', unknownColor?: string, values?: Array&lt;Date<br>&#124;&nbsp;number<br>&#124;&nbsp;string&gt; }<br>&#124;&nbsp;{ color: Array&lt;string&gt;<br>&#124;&nbsp;func, max?: Date<br>&#124;&nbsp;number, min?: Date<br>&#124;&nbsp;number, type: 'continuous' }<br>&#124;&nbsp;{ colors: Array&lt;string&gt;, thresholds: Array&lt;Date<br>&#124;&nbsp;number&gt;, type: 'piecewise' }, data?: array, dataKey?: string, id?: string, max?: number, min?: number }&gt;"
}
},
"zoom": {
"type": {
"name": "arrayOf",
"description": "Array&lt;{ axisId: number<br>&#124;&nbsp;string, end: number, start: number }&gt;"
}
}
},
"name": "ChartContainerPro",
Expand Down
13 changes: 13 additions & 0 deletions docs/pages/x/api/charts/responsive-chart-container-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
"describedArgs": ["highlightedItem"]
}
},
"onZoomChange": {
"type": { "name": "func" },
"signature": {
"type": "function(zoomData: Array<ZoomData>) => void",
"describedArgs": ["zoomData"]
}
},
"plugins": { "type": { "name": "arrayOf", "description": "Array&lt;object&gt;" } },
"width": { "type": { "name": "number" } },
"xAxis": {
Expand All @@ -50,6 +57,12 @@
"name": "arrayOf",
"description": "Array&lt;{ colorMap?: { colors: Array&lt;string&gt;, type: 'ordinal', unknownColor?: string, values?: Array&lt;Date<br>&#124;&nbsp;number<br>&#124;&nbsp;string&gt; }<br>&#124;&nbsp;{ color: Array&lt;string&gt;<br>&#124;&nbsp;func, max?: Date<br>&#124;&nbsp;number, min?: Date<br>&#124;&nbsp;number, type: 'continuous' }<br>&#124;&nbsp;{ colors: Array&lt;string&gt;, thresholds: Array&lt;Date<br>&#124;&nbsp;number&gt;, type: 'piecewise' }, data?: array, dataKey?: string, id?: string, max?: number, min?: number }&gt;"
}
},
"zoom": {
"type": {
"name": "arrayOf",
"description": "Array&lt;{ axisId: number<br>&#124;&nbsp;string, end: number, start: number }&gt;"
}
}
},
"name": "ResponsiveChartContainerPro",
Expand Down
Loading