Skip to content

Commit f3b5092

Browse files
[charts] Add charts toolbar with zoom options
1 parent 8641dbf commit f3b5092

File tree

26 files changed

+385
-34
lines changed

26 files changed

+385
-34
lines changed

docs/translations/api-docs/charts/bar-chart-pro/bar-chart-pro.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"typeDescriptions": { "zoomData": "Updated zoom data." }
6060
},
6161
"series": {
62-
"description": "The series to display in the bar chart. An array of <a href='/x/api/charts/bar-series-type/'>BarSeriesType</a> objects."
62+
"description": "The series to display in the bar chart. An array of [[BarSeriesType]] objects."
6363
},
6464
"showToolbar": { "description": "If true, shows the default chart toolbar." },
6565
"skipAnimation": {
@@ -71,10 +71,10 @@
7171
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
7272
},
7373
"xAxis": {
74-
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
74+
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
7575
},
7676
"yAxis": {
77-
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
77+
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
7878
},
7979
"zAxis": { "description": "The configuration of the z-axes." },
8080
"zoomData": { "description": "The list of zoom data related to each axis." }

docs/translations/api-docs/charts/bar-chart/bar-chart.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
}
5353
},
5454
"series": {
55-
"description": "The series to display in the bar chart. An array of <a href='/x/api/charts/bar-series-type/'>BarSeriesType</a> objects."
55+
"description": "The series to display in the bar chart. An array of [[BarSeriesType]] objects."
5656
},
5757
"skipAnimation": {
5858
"description": "If <code>true</code>, animations are skipped. If unset or <code>false</code>, the animations respects the user&#39;s <code>prefers-reduced-motion</code> setting."
@@ -63,10 +63,10 @@
6363
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
6464
},
6565
"xAxis": {
66-
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
66+
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
6767
},
6868
"yAxis": {
69-
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
69+
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
7070
}
7171
},
7272
"classDescriptions": {},

docs/translations/api-docs/charts/chart-container-pro/chart-container-pro.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
4040
},
4141
"xAxis": {
42-
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
42+
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
4343
},
4444
"yAxis": {
45-
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
45+
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
4646
},
4747
"zAxis": { "description": "The configuration of the z-axes." }
4848
},

docs/translations/api-docs/charts/chart-container/chart-container.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@
4141
}
4242
},
4343
"radiusAxis": {
44-
"description": "The configuration of the radial-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
44+
"description": "The configuration of the radial-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
4545
},
4646
"rotationAxis": {
47-
"description": "The configuration of the rotation-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
47+
"description": "The configuration of the rotation-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
4848
},
4949
"series": {
5050
"description": "The array of series to display. Each type of series has its own specificity. Please refer to the appropriate docs page to learn more about it."
@@ -59,10 +59,10 @@
5959
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
6060
},
6161
"xAxis": {
62-
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
62+
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
6363
},
6464
"yAxis": {
65-
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
65+
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
6666
},
6767
"zAxis": { "description": "The configuration of the z-axes." }
6868
},

docs/translations/api-docs/charts/funnel-chart/funnel-chart.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
}
4949
},
5050
"series": {
51-
"description": "The series to display in the funnel chart. An array of FunnelSeriesType objects."
51+
"description": "The series to display in the funnel chart. An array of [[FunnelSeriesType]] objects."
5252
},
5353
"skipAnimation": {
5454
"description": "If <code>true</code>, animations are skipped. If unset or <code>false</code>, the animations respects the user&#39;s <code>prefers-reduced-motion</code> setting."

docs/translations/api-docs/charts/heatmap/heatmap.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"typeDescriptions": { "highlightedItem": "The newly highlighted item." }
3535
},
3636
"series": {
37-
"description": "The series to display in the bar chart. An array of HeatmapSeriesType objects."
37+
"description": "The series to display in the bar chart. An array of [[HeatmapSeriesType]] objects."
3838
},
3939
"slotProps": { "description": "The props used for each component slot." },
4040
"slots": { "description": "Overridable component slots." },
@@ -46,10 +46,10 @@
4646
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
4747
},
4848
"xAxis": {
49-
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
49+
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
5050
},
5151
"yAxis": {
52-
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
52+
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
5353
},
5454
"zAxis": { "description": "The configuration of the z-axes." }
5555
},

docs/translations/api-docs/charts/line-chart-pro/line-chart-pro.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"typeDescriptions": { "zoomData": "Updated zoom data." }
5454
},
5555
"series": {
56-
"description": "The series to display in the line chart. An array of <a href='/x/api/charts/line-series-type/'>LineSeriesType</a> objects."
56+
"description": "The series to display in the line chart. An array of [[LineSeriesType]] objects."
5757
},
5858
"showToolbar": { "description": "If true, shows the default chart toolbar." },
5959
"skipAnimation": { "description": "If <code>true</code>, animations are skipped." },
@@ -63,10 +63,10 @@
6363
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
6464
},
6565
"xAxis": {
66-
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
66+
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
6767
},
6868
"yAxis": {
69-
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
69+
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
7070
},
7171
"zAxis": { "description": "The configuration of the z-axes." },
7272
"zoomData": { "description": "The list of zoom data related to each axis." }

docs/translations/api-docs/charts/line-chart/line-chart.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"onLineClick": { "description": "Callback fired when a line element is clicked." },
4747
"onMarkClick": { "description": "Callback fired when a mark element is clicked." },
4848
"series": {
49-
"description": "The series to display in the line chart. An array of <a href='/x/api/charts/line-series-type/'>LineSeriesType</a> objects."
49+
"description": "The series to display in the line chart. An array of [[LineSeriesType]] objects."
5050
},
5151
"skipAnimation": { "description": "If <code>true</code>, animations are skipped." },
5252
"slotProps": { "description": "The props used for each component slot." },
@@ -55,10 +55,10 @@
5555
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
5656
},
5757
"xAxis": {
58-
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
58+
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
5959
},
6060
"yAxis": {
61-
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
61+
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
6262
}
6363
},
6464
"classDescriptions": {},

docs/translations/api-docs/charts/pie-chart/pie-chart.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"onItemClick": { "description": "Callback fired when a pie arc is clicked." },
2828
"series": {
29-
"description": "The series to display in the pie chart. An array of <a href='/x/api/charts/pie-series-type/'>PieSeriesType</a> objects."
29+
"description": "The series to display in the pie chart. An array of [[PieSeriesType]] objects."
3030
},
3131
"skipAnimation": {
3232
"description": "If <code>true</code>, animations are skipped. If unset or <code>false</code>, the animations respects the user&#39;s <code>prefers-reduced-motion</code> setting."

docs/translations/api-docs/charts/radar-chart/radar-chart.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
},
3131
"radar": { "description": "The configuration of the radar scales." },
3232
"series": {
33-
"description": "The series to display in the bar chart. An array of RadarSeriesType objects."
33+
"description": "The series to display in the bar chart. An array of [[RadarSeriesType]] objects."
3434
},
3535
"shape": { "description": "The grid shape." },
3636
"skipAnimation": {

docs/translations/api-docs/charts/radar-data-provider/radar-data-provider.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
"radar": { "description": "The configuration of the radar scales." },
2929
"series": {
30-
"description": "The series to display in the bar chart. An array of RadarSeriesType objects."
30+
"description": "The series to display in the bar chart. An array of [[RadarSeriesType]] objects."
3131
},
3232
"skipAnimation": {
3333
"description": "If <code>true</code>, animations are skipped. If unset or <code>false</code>, the animations respects the user&#39;s <code>prefers-reduced-motion</code> setting."

docs/translations/api-docs/charts/scatter-chart-pro/scatter-chart-pro.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"typeDescriptions": { "zoomData": "Updated zoom data." }
5858
},
5959
"series": {
60-
"description": "The series to display in the scatter chart. An array of <a href='/x/api/charts/scatter-series-type/'>ScatterSeriesType</a> objects."
60+
"description": "The series to display in the scatter chart. An array of [[ScatterSeriesType]] objects."
6161
},
6262
"showToolbar": { "description": "If true, shows the default chart toolbar." },
6363
"skipAnimation": {
@@ -72,10 +72,10 @@
7272
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
7373
},
7474
"xAxis": {
75-
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
75+
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
7676
},
7777
"yAxis": {
78-
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
78+
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
7979
},
8080
"zAxis": { "description": "The configuration of the z-axes." },
8181
"zoomData": { "description": "The list of zoom data related to each axis." }

docs/translations/api-docs/charts/scatter-chart/scatter-chart.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
}
5151
},
5252
"series": {
53-
"description": "The series to display in the scatter chart. An array of <a href='/x/api/charts/scatter-series-type/'>ScatterSeriesType</a> objects."
53+
"description": "The series to display in the scatter chart. An array of [[ScatterSeriesType]] objects."
5454
},
5555
"skipAnimation": {
5656
"description": "If <code>true</code>, animations are skipped. If unset or <code>false</code>, the animations respects the user&#39;s <code>prefers-reduced-motion</code> setting."
@@ -64,10 +64,10 @@
6464
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
6565
},
6666
"xAxis": {
67-
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
67+
"description": "The configuration of the x-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
6868
},
6969
"yAxis": {
70-
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of <a href='/x/api/charts/axis-config/'>AxisConfig</a> objects."
70+
"description": "The configuration of the y-axes. If not provided, a default axis config is used. An array of [[AxisConfig]] objects."
7171
},
7272
"zAxis": { "description": "The configuration of the z-axes." }
7373
},

docs/translations/api-docs/charts/spark-line-chart/spark-line-chart.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@
6767
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
6868
},
6969
"xAxis": {
70-
"description": "The xAxis configuration. Notice it is a single <a href='/x/api/charts/axis-config/'>AxisConfig</a> object, not an array of configuration."
70+
"description": "The xAxis configuration. Notice it is a single [[AxisConfig]] object, not an array of configuration."
7171
},
7272
"yAxis": {
73-
"description": "The yAxis configuration. Notice it is a single <a href='/x/api/charts/axis-config/'>AxisConfig</a> object, not an array of configuration."
73+
"description": "The yAxis configuration. Notice it is a single [[AxisConfig]] object, not an array of configuration."
7474
}
7575
},
7676
"classDescriptions": {},

packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { ChartsSurface } from '@mui/x-charts/ChartsSurface';
1515
import { ChartZoomSlider } from '../ChartZoomSlider';
1616
import { ChartsToolbarPro } from '../ChartsToolbarPro';
1717
import { ChartZoomSlider } from '../ChartZoomSlider';
18+
import { ChartsToolbarPro } from '../ChartsToolbarPro/ChartsToolbarPro';
1819
import { ChartContainerProProps } from '../ChartContainerPro';
1920
import { useChartContainerProProps } from '../ChartContainerPro/useChartContainerProProps';
2021
import { ChartDataProviderPro } from '../ChartDataProviderPro';
@@ -114,6 +115,8 @@ BarChartPro.propTypes = {
114115
exportAsImage: PropTypes.func.isRequired,
115116
exportAsPrint: PropTypes.func.isRequired,
116117
setZoomData: PropTypes.func.isRequired,
118+
zoomIn: PropTypes.func.isRequired,
119+
zoomOut: PropTypes.func.isRequired,
117120
}),
118121
}),
119122
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
'use client';
2+
3+
import * as React from 'react';
4+
import { ToolbarButton } from '@mui/x-charts/Toolbar';
5+
import { useChartContext } from '@mui/x-charts/context/ChartProvider';
6+
import { useIsHydrated } from '@mui/x-charts/hooks/useIsHydrated';
7+
import materialSlots, { type ChartsSlots } from '@mui/x-charts/material';
8+
import { useChartsLocalization } from '@mui/x-charts/hooks';
9+
import { UseChartProExportSignature } from '../internals/plugins/useChartProExport';
10+
11+
type ChartsToolbarExportButtonSlots = Partial<
12+
Pick<ChartsSlots, 'baseMenu' | 'baseMenuItem' | 'baseTooltip' | 'exportIcon'>
13+
>;
14+
15+
type ChartsToolbarExportButtonSlotProps = {
16+
[K in keyof Required<ChartsToolbarExportButtonSlots>]: React.ComponentProps<
17+
Required<ChartsToolbarExportButtonSlots>[K]
18+
>;
19+
};
20+
21+
interface ChartsToolbarExportButtonProps {
22+
slots?: ChartsToolbarExportButtonSlots;
23+
slotProps?: ChartsToolbarExportButtonSlotProps;
24+
}
25+
26+
export function ChartsToolbarExportButton({ slots, slotProps }: ChartsToolbarExportButtonProps) {
27+
const buttonRef = React.useRef<HTMLButtonElement>(null);
28+
const [menuOpen, setMenuOpen] = React.useState(false);
29+
const handleClose = () => setMenuOpen(false);
30+
const { publicAPI } = useChartContext<[UseChartProExportSignature]>();
31+
const isHydrated = useIsHydrated();
32+
const ExportIcon = slots?.exportIcon ?? materialSlots.exportIcon;
33+
const Tooltip = slots?.baseTooltip ?? materialSlots.baseTooltip;
34+
const Menu = slots?.baseMenu ?? materialSlots.baseMenu;
35+
const MenuItem = slots?.baseMenuItem ?? materialSlots.baseMenuItem;
36+
const { localeText } = useChartsLocalization();
37+
const canExport = publicAPI.exportAsPrint || publicAPI.exportAsImage;
38+
39+
if (!canExport) {
40+
return null;
41+
}
42+
43+
return (
44+
<React.Fragment>
45+
<Tooltip title={localeText.export}>
46+
<ToolbarButton ref={buttonRef} onClick={() => setMenuOpen(true)}>
47+
<ExportIcon {...slotProps?.exportIcon} />
48+
</ToolbarButton>
49+
</Tooltip>
50+
{isHydrated && (
51+
<Menu anchorEl={() => buttonRef.current} open={menuOpen} onClose={handleClose}>
52+
{publicAPI.exportAsPrint ? (
53+
<MenuItem
54+
onClick={() => {
55+
publicAPI.exportAsPrint();
56+
handleClose();
57+
}}
58+
>
59+
{localeText.print}
60+
</MenuItem>
61+
) : null}
62+
{publicAPI.exportAsImage ? (
63+
<MenuItem
64+
onClick={() => {
65+
publicAPI.exportAsImage();
66+
handleClose();
67+
}}
68+
>
69+
{localeText.exportAsImage}
70+
</MenuItem>
71+
) : null}
72+
</Menu>
73+
)}
74+
</React.Fragment>
75+
);
76+
}

0 commit comments

Comments
 (0)