Skip to content

Conversation

@bernardobelchior
Copy link
Member

@bernardobelchior bernardobelchior commented Jun 3, 2025

Fixes #18185.

Adds an export menu to the charts toolbar. It is accessible and can be configured to hide/show options as well as export multiple image formats. Like the other PRs related to the toolbar, most of the code is a copy of the Data Grid's. I've left comments to a link to the original one.

Default toolbar:

Screen.Recording.2025-06-04.at.16.50.19.mov

Toolbar made through composition:

Screen.Recording.2025-06-04.at.16.50.57.mov

@mui-bot
Copy link

mui-bot commented Jun 3, 2025

Localization writing tips ✍️

Seems you are updating localization 🌍 files.

Thank you for contributing to the localization! 🎉 To make your PR perfect, here is a list of elements to check: ✔️

  • Verify if the PR title respects the release format. Here are two examples (depending if you update or add a locale file)

    [l10n] Improve Swedish (sv-SE) locale
    [l10n] Add Danish (da-DK) locale

  • Update the documentation of supported locales by running pnpm l10n
  • Verify that you have added an export line in src/locales/index.ts for the new locale.
  • Run pnpm docs:api which should add your new translation to the list of exported interfaces.
  • Clean files with pnpm prettier.

Deploy preview: https://deploy-preview-18210--material-ui-x.netlify.app/

Updated pages:

Bundle size report

Total Size Change: 🔺+47.4KB(+0.38%) - Total Gzip Change: 🔺+16.7KB(+0.43%)
Files: 122 total (0 added, 0 removed, 29 changed)

Show details for 100 more bundles (22 more not shown)

@mui/x-charts-pro/Heatmapparsed: 🔺+5.42KB(+2.83%) gzip: 🔺+1.91KB(+3.02%)
@mui/x-charts-pro/BarChartProparsed: 🔺+5.39KB(+2.51%) gzip: 🔺+1.87KB(+2.64%)
@mui/x-charts-pro/PieChartProparsed: 🔺+5.38KB(+2.78%) gzip: 🔺+1.79KB(+2.80%)
@mui/x-charts-proparsed: 🔺+5.37KB(+1.59%) gzip: 🔺+1.77KB(+1.69%)
@mui/x-charts-pro/LineChartProparsed: 🔺+5.37KB(+2.32%) gzip: 🔺+1.84KB(+2.45%)
@mui/x-charts-pro/ScatterChartProparsed: 🔺+5.37KB(+2.66%) gzip: 🔺+1.87KB(+2.83%)
@mui/x-charts-pro/RadarChartProparsed: 🔺+3.24KB(+1.93%) gzip: 🔺+990B(+1.81%)
@mui/x-charts-pro/ChartsToolbarProparsed: 🔺+3.2KB(+5.08%) gzip: 🔺+1.06KB(+4.73%)
@mui/x-charts-pro/ChartContainerProparsed: 🔺+2.36KB(+1.66%) gzip: 🔺+896B(+1.87%)
@mui/x-charts-pro/ChartDataProviderProparsed: 🔺+2.35KB(+1.74%) gzip: 🔺+890B(+1.96%)
@mui/x-charts-pro/FunnelChartparsed: 🔺+2.32KB(+1.11%) gzip: 🔺+903B(+1.34%)
@mui/x-chartsparsed: 🔺+159B(+0.06%) gzip: 🔺+88B(+0.11%)
@mui/x-charts/BarChartparsed: 🔺+159B(+0.09%) gzip: 🔺+80B(+0.14%)
@mui/x-charts/ChartContainerparsed: 🔺+159B(+0.14%) gzip: 🔺+89B(+0.23%)
@mui/x-charts/ChartDataProviderparsed: 🔺+159B(+0.15%) gzip: 🔺+87B(+0.24%)
@mui/x-charts/LineChartparsed: 🔺+159B(+0.08%) gzip: 🔺+90B(+0.15%)
@mui/x-charts/PieChartparsed: 🔺+159B(+0.10%) gzip: 🔺+85B(+0.16%)
@mui/x-charts/RadarChartparsed: 🔺+159B(+0.10%) gzip: 🔺+90B(+0.17%)
@mui/x-charts/ScatterChartparsed: 🔺+159B(+0.10%) gzip: 🔺+84B(+0.16%)
@mui/x-charts/SparkLineChartparsed: 🔺+159B(+0.09%) gzip: 🔺+88B(+0.15%)
@mui/x-charts/ChartsLocalizationProviderparsed: 🔺+157B(+11.65%) gzip: 🔺+84B(+11.60%)
@mui/x-charts-pro/ChartZoomSliderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsAxisparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsAxisHighlightparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsClipPathparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsGridparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsLabelparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsLegendparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsOverlayparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsReferenceLineparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsSurfaceparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsTextparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsTooltipparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsXAxisparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsYAxisparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/Gaugeparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/Toolbarparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-data-gridparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-data-grid-premiumparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-data-grid-premium/DataGridPremiumparsed: 0B(0.00%) gzip: 🔺+2B(0.00%)
@mui/x-data-grid-proparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-data-grid-pro/DataGridProparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-data-grid/DataGridparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickersparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-proparsed: 0B(0.00%) gzip: 🔺+1B(0.00%)
@mui/x-date-pickers-pro/AdapterDateFnsparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterDateFnsJalaliparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterDayjsparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterLuxonparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterMomentparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterMomentHijriparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterMomentJalaaliparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/DateRangeCalendarparsed: 0B(0.00%) gzip: 🔺+1B(0.00%)
@mui/x-date-pickers-pro/DateRangePickerparsed: 0B(0.00%) gzip: 🔺+2B(0.00%)
@mui/x-date-pickers-pro/DateRangePickerDayparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/DateRangePickerDay2parsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/DateTimeRangePickerparsed: 0B(0.00%) gzip: 🔺+1B(0.00%)
@mui/x-date-pickers-pro/DesktopDateRangePickerparsed: 0B(0.00%) gzip: 🔺+2B(0.00%)
@mui/x-date-pickers-pro/DesktopDateTimeRangePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/DesktopTimeRangePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/LocalizationProviderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/MobileDateRangePickerparsed: 0B(0.00%) gzip: 🔺+1B(0.00%)
@mui/x-date-pickers-pro/MobileDateTimeRangePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/MobileTimeRangePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/MultiInputDateRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/MultiInputDateTimeRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/MultiInputTimeRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/PickersRangeCalendarHeaderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/SingleInputDateRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/SingleInputDateTimeRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/SingleInputTimeRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/StaticDateRangePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/TimeRangePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterDateFnsparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterDateFnsBaseparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterDateFnsJalaliparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterDayjsparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterLuxonparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterMomentparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterMomentHijriparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterMomentJalaaliparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DateCalendarparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DateFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DatePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DateTimeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DateTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DayCalendarSkeletonparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DesktopDatePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DesktopDateTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DesktopTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DigitalClockparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/LocalizationProviderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MobileDatePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MobileDateTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MobileTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MonthCalendarparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MultiSectionDigitalClockparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/PickerDay2parsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/PickersActionBarparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/PickersCalendarHeaderparsed: 0B(0.00%) gzip: 0B(0.00%)

Details of bundle changes

Generated by 🚫 dangerJS against ca0ea1c

@bernardobelchior bernardobelchior force-pushed the charts-toolbar-export-menu branch 2 times, most recently from 6d3f13a to c24fe0b Compare June 4, 2025 12:53
'bottom-end': 'top right',
};

export function BasePopper(props: ChartBasePopperProps) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Basically a copy of Data Grid's BasePopper (source)

import ListItemText from '@mui/material/ListItemText';
import { ChartBaseMenuItemProps } from '../../slots/chartBaseSlotProps';

export function BaseMenuItem(props: ChartBaseMenuItemProps) {
Copy link
Member Author

Choose a reason for hiding this comment

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

A copy of Data Grid's BaseMenuItem (source)

height: '50%',
}));

const ChartsToolbarDivider = React.forwardRef<HTMLHRElement, ChartsToolbarDividerProps>(
Copy link
Member Author

Choose a reason for hiding this comment

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

A copy of Data Grid's GridToolbarDivider (source)

children: React.ReactNode;
}

function ChartsMenu(props: ChartsMenuProps) {
Copy link
Member Author

Choose a reason for hiding this comment

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

A copy of Data Grid's GridMenu (source)

@bernardobelchior bernardobelchior changed the title [WIP][charts-pro] Add export menu to charts toolbar [charts-pro] Add export menu to charts toolbar Jun 5, 2025
@bernardobelchior bernardobelchior marked this pull request as ready for review June 5, 2025 06:38
@bernardobelchior bernardobelchior requested review from JCQuintas and alexfauquette and removed request for alexfauquette June 5, 2025 06:38
@zannager zannager added the scope: charts Changes related to the charts. label Jun 5, 2025
@bernardobelchior bernardobelchior added the type: new feature Expand the scope of the product to solve a new problem. label Jun 5, 2025
@bernardobelchior bernardobelchior marked this pull request as draft June 5, 2025 07:22
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jun 5, 2025
@github-actions
Copy link

github-actions bot commented Jun 5, 2025

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@bernardobelchior bernardobelchior force-pushed the charts-toolbar-export-menu branch from 09fee1b to 5d235f5 Compare June 5, 2025 13:39
@github-actions github-actions bot added PR: out-of-date The pull request has merge conflicts and can't be merged. and removed PR: out-of-date The pull request has merge conflicts and can't be merged. labels Jun 5, 2025
@github-actions
Copy link

github-actions bot commented Jun 6, 2025

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@bernardobelchior bernardobelchior force-pushed the charts-toolbar-export-menu branch from 8ce65bc to 26100a2 Compare June 18, 2025 10:25
Charts can be exported using the browser's native print dialog or as an image.

{{"demo": "PrintChart.js"}}
To enable this functionality, you need to enable the chart's toolbar by passing the `showToolbar` prop to the chart component.
Copy link
Member

Choose a reason for hiding this comment

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

This is not true is it? The export functionality is enabled on the API level, not if the toolbar is shown or not 🤔

Copy link
Member

@JCQuintas JCQuintas left a comment

Choose a reason for hiding this comment

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

Left some copy improvements, everything else seems good

To enable this functionality, you need to enable the chart's toolbar by passing the `showToolbar` prop to the chart component.

## Export as image
The toolbar then renders a button that opens a menu with the export options.
Copy link
Member

Choose a reason for hiding this comment

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

The demo is self explenatory on the result

Suggested change
The toolbar then renders a button that opens a menu with the export options.

@JCQuintas
Copy link
Member

Maybe we could rewrite the Customization demo to use the "code preview"? So the users understand what is happening in the code for each option.

@alexfauquette alexfauquette merged commit 798d322 into mui:master Jun 20, 2025
23 checks passed
@bernardobelchior bernardobelchior deleted the charts-toolbar-export-menu branch June 23, 2025 06:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: charts Changes related to the charts. type: new feature Expand the scope of the product to solve a new problem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[charts] Add export button in charts toolbar

6 participants