Skip to content

[charts] Add charts toolbar with zoom options #17615

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

Merged
merged 19 commits into from
May 5, 2025

Conversation

bernardobelchior
Copy link
Member

@bernardobelchior bernardobelchior commented Apr 29, 2025

Add charts toolbar with zoom options. Part of #17557.

Designs.

Screen.Recording.2025-04-30.at.10.27.52.mov

This PR closely follows the Data Grid's toolbar implementation. This PR does not yet implement customization of the toolbar, which will be done in subsequent PRs, along with other improvements such as defining the toolbar's position.

Copy link

github-actions bot commented Apr 29, 2025

Thanks for adding a type label to the PR! 👍

@bernardobelchior bernardobelchior added new feature New feature or request component: charts This is the name of the generic UI component, not the React module! labels Apr 29, 2025
@mui-bot
Copy link

mui-bot commented Apr 29, 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
  • Clean files with pnpm prettier.

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

Updated pages:

Generated by 🚫 dangerJS against cc3d855

Copy link

codspeed-hq bot commented Apr 29, 2025

CodSpeed Performance Report

Merging #17615 will not alter performance

Comparing bernardobelchior:charts-zoom-toolbar (cc3d855) with master (e567c6e)

Summary

✅ 8 untouched benchmarks

@bernardobelchior bernardobelchior force-pushed the charts-zoom-toolbar branch 2 times, most recently from 89d6ed8 to 5a4ec1e Compare April 30, 2025 09:28
@bernardobelchior bernardobelchior marked this pull request as ready for review April 30, 2025 09:29
@bernardobelchior bernardobelchior requested review from alexfauquette and JCQuintas and removed request for alexfauquette April 30, 2025 09:29
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 30, 2025
Copy link

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

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 30, 2025
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.

Works nicely. I've added some comments on things I didn't understand or where the API could be improved for discussion

Comment on lines 4 to 15
export interface ChartsIconSlots {
/**
* Icon displayed on the toolbar's zoom in button.
* @default ChartsZoomInIcon
*/
zoomInIcon: React.ComponentType<IconProps>;
/**
* Icon displayed on the toolbar's zoom out button.
* @default ChartsZoomOutIcon
*/
zoomOutIcon: React.ComponentType<IconProps>;
}
Copy link
Member

Choose a reason for hiding this comment

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

Should this be in the pro package?

Or something like

export interface ChartsIconSlotsExtension {}
export interface ChartsIconSlots extends ChartsIconSlotsExtension { }

To allow doing

declare module '@mui/x-charts' {
  interface ChartsIconSlotsExtension {
	  /**
	   * Icon displayed on the toolbar's zoom in button.
	   * @default ChartsZoomInIcon
	   */
	  zoomInIcon: React.ComponentType<IconProps>;
	  /**
	   * Icon displayed on the toolbar's zoom out button.
	   * @default ChartsZoomOutIcon
	   */
	  zoomOutIcon: React.ComponentType<IconProps>;
  }
}

A bit similar to #14063

Copy link
Member Author

Choose a reason for hiding this comment

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

Done 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

I did it, but I'm now reconsidering. We are still exporting the pro icons from the community package, so there isn't a big benefit in extending the types, is there?

Another option would be for the pro package to export a ChartsSlotsPro type which would extend from ChartsSlots. That way we could move the pro-only components to that package instead of increasing the bundle size of the community version.

If you think that's a good idea, I could do it in a follow-up PR, what do you think?

Copy link
Member Author

Choose a reason for hiding this comment

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

Moved the pro slots to the pro package

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label May 2, 2025
Copy link

github-actions bot commented May 2, 2025

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

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label May 2, 2025
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.

Small nitpick, but otherwise looking good


export type ChartsSlots = ChartsBaseSlots & ChartsIconSlots;

export const materialSlots: ChartsSlots = { ...baseSlots, ...iconSlots };
Copy link
Member

Choose a reason for hiding this comment

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

I find it a bit weird we export materialSlots, as it is technically not a slot. 🤔

Copy link
Member Author

@bernardobelchior bernardobelchior May 5, 2025

Choose a reason for hiding this comment

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

Why do you say it isn't a slot?

At the moment, it might not be, be it'll be in a follow-up PR.

We'll use it like this:

 <ScatterChartPro
  {...params}
  xAxis={[{ zoom: true }]}
  yAxis={[{ zoom: true }]}
  showToolbar
  slots={{ baseIconButton: CustomIconButton }}
/>

Copy link
Member

Choose a reason for hiding this comment

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

My understanding is that the slot is the part that can be overridden. So the slot is aptly named a "slot", where something else (a component in this case) fits into.

This means the items here are not slots, they are components that are used in the slots by default. 😆

Copy link
Member Author

Choose a reason for hiding this comment

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

Do you have a suggestion for the name? I can change it in a follow-up PR.

Copy link
Member

Choose a reason for hiding this comment

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

If the goal is to have a single object import, I would go with materialComponents maybe?

But my preferred way would be

export { IconButton } from '@mui/material/IconButton'

since the object way probably doesn't treeshake properly

Copy link
Member Author

@bernardobelchior bernardobelchior May 5, 2025

Choose a reason for hiding this comment

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

What do you think of defaultSlotsMaterial?

But my preferred way would be

What do you mean? I thought you meant the constant. Didn't get what you meant 😅

Copy link
Member

Choose a reason for hiding this comment

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

defaultSlotsMaterial can work.

What do you mean? I thought you meant the constant. Didn't get what you meant 😅

Yeah, IconButton is a component. My secondary point with that comment is that we are exporting an object here which is a list of components, which probably breaks treeshaking, since whenever any of the components is used it will load all of them

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, I'll use that 👍

My secondary point with that comment is that we are exporting an object here which is a list of components, which probably breaks treeshaking, since whenever any of the components is used it will load all of them

It'll break tree-shaking nevertheless because we need to select the component in runtime. We'll never be able to remove the code from those components from the bundle because if a slot goes missing in runtime we'll need to use the default from MUI.

That's one of the conclusions I arrived at here, but decided to keep the same API as the Data Grid.

If we want to fix the tree-shaking issue we need to find another way to register the default slots.

Copy link
Member Author

Choose a reason for hiding this comment

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

PR: #17710

@bernardobelchior bernardobelchior merged commit 31dccb6 into mui:master May 5, 2025
22 checks passed
@bernardobelchior bernardobelchior deleted the charts-zoom-toolbar branch May 5, 2025 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: charts This is the name of the generic UI component, not the React module! new feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants