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] Experiment with plugins for series+axes #15865

Open
wants to merge 37 commits into
base: master
Choose a base branch
from

Conversation

alexfauquette
Copy link
Member

@alexfauquette alexfauquette commented Dec 12, 2024

This PR is an attempt to migrate the axes, series and zoom to the plugin framework.

Modifications

Renaming that could be extracted

  • ZoomOptions -> ZoomOption: Even if we have multiple options, it's too easy to mix the zoom option of an axis and the object that map axes ids to their options
  • SeriesFormatterResult -> SeriesProcessorResult
  • SeriesFormatter -> SeriesProcessor
  • SeriesFormatterParams -> SeriesProcessorParams
  • ExtremumGetter -> CartesianExtremumGetter
  • ChartsPlugin -> ChartSeriesTypeConfig the definition of extremums, cologetter, ... for a series type

Logic

Instance

The isPointInside got moved from the drawing area to the instance. It's our first instance method 🎉

Renaming plugins

The plugins props which was an array of configuration objects, defining for each series how to compute the extremums, preprocess the data, ... is now an object called seriesConfig. That's only sementic modification

- plugins={[ barConfig, lineConfig ]}
+ seriesConfig={{ bar: barConfig, line: lineConfig }}

Selector usage

The data modification is now done in selectors. We have 3 states: series, cartesianAxes, and zoom which describe the state of the chart.

One issue with this strategy is that useXAxis() is defined in the MIT package. And if we want to have the BarPlot supporting zoom out of the box for pro users, we need to have the zoom selectors that get zoom data.

The workaround is to put types and selectors for zoom in the MIT package. But populate and manage the state in the pro package.

Zoom API

The zoom seems to be working ok. The new API proposed it the following one:

  • onZoomChange now provide the new zoom value in its argument.
  • zoom props is replaced by initialZoom which is only used to initialize the zoom.
  • The apiRef get a method setZoomData that use can call to set the zoom data. Maybe setZoom would be a better name

@mui-bot
Copy link

mui-bot commented Dec 12, 2024

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

Generated by 🚫 dangerJS against b38dc27

Comment on lines 73 to 81
useEnhancedEffect(() => {
store.update((prevState) => ({
...prevState,
zoom: {
...prevState.zoom,
zoomData,
},
}));
}, [store, zoomData]);
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be inside the setZoomDataCallback instead? 🤔

@alexfauquette alexfauquette marked this pull request as ready for review December 17, 2024 12:09
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Dec 17, 2024
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 Dec 17, 2024
@zannager zannager added the component: charts This is the name of the generic UI component, not the React module! label Dec 17, 2024
Copy link

codspeed-hq bot commented Dec 17, 2024

CodSpeed Performance Report

Merging #15865 will improve performances by 9.86%

Comparing alexfauquette:all-pluggin-way (12fadbe) with master (d9e6746)

Summary

⚡ 1 improvements
✅ 5 untouched benchmarks

Benchmarks breakdown

Benchmark master alexfauquette:all-pluggin-way Change
ScatterChartPro with big data amount 165.9 ms 151 ms +9.86%

@@ -45,20 +53,24 @@ export const useChartContainerProps = (
...other,
};

const chartDataProviderProps: ChartDataProviderProps = {
const chartDataProviderProps: Omit<
ChartDataProviderProps<[UseChartCartesianAxisSignature<TSeries>], TSeries>,
Copy link
Member Author

Choose a reason for hiding this comment

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

For typing reasons, I set the cartesian plugin here, such that props related to cartesian axes are correctly typed

Comment on lines +90 to +91
const { xAxis, xAxisIds } = useXAxes();
const { yAxis, yAxisIds } = useYAxes();
Copy link
Member Author

Choose a reason for hiding this comment

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

You might see lots of them. The initial idea was to split x/y axes such that updating one does not impact the other. Finally I'm not sure it's that usefull

<ChartProvider pluginParams={{ width: 100, height: 100, series: [] }}>
<ChartsSurface
ref={ref}
disableAxisListener // TODO: remove during v8 when charts store is always available
Copy link
Member Author

Choose a reason for hiding this comment

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

The store is available but not yet the axes, so removing it still make the CI crash

Comment on lines +2 to +4
// 'use client';
// import * as React from 'react';
// import { computeAxisValue } from '../../internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisValue';
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 just commented the file about polar coordinate. They got introduced when starting the effort on radar chart.

They should be translated into a useChartPolarAxisPlugin

Comment on lines -9 to -16
if (skipError) {
// TODO: Remove once store is used by all charts.
// This line is only for `useAxisEvents` which is in the surface of the Gauge.
// But the Gauge don't have store yet because it does not need the interaction provider.
// Will be fixed when every thing move to the store since every component will have access to it.
// @ts-ignore
return context?.store;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

That one is good to remove 🎉

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!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants