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] Let the useXxxSeries support array of ids and document them #15545

Merged
merged 16 commits into from
Feb 11, 2025

Conversation

JCQuintas
Copy link
Member

@JCQuintas JCQuintas commented Nov 21, 2024

  • added docs to all public hooks
  • Improve types of useXxxSeries hooks and add more use-cases

@JCQuintas JCQuintas added breaking change component: charts This is the name of the generic UI component, not the React module! v8.x labels Nov 21, 2024
@JCQuintas JCQuintas self-assigned this Nov 21, 2024
@mui-bot
Copy link

mui-bot commented Nov 21, 2024

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

Generated by 🚫 dangerJS against 07ae309

Copy link

codspeed-hq bot commented Nov 21, 2024

CodSpeed Performance Report

Merging #15545 will not alter performance

Comparing JCQuintas:remove-unstable-useseries (07ae309) with master (e71e831)

Summary

✅ 6 untouched benchmarks

@alexfauquette
Copy link
Member

I'm wondering if the current hook is the best DX. If we provide something like

useBarSeries(['seriesId1', 'seriesId2']) // Returns the config of the series
useBarSeries() // Returns all bar series in the correct order

It might be easier to use

@JCQuintas
Copy link
Member Author

Do you see a lot of value in returning an array for allowing multiple items to be returned or only allow one return per call?

const a = useSeries('a')
const b = useSeries('b')

vs

const [a,b] useSeries('a', 'b')

@alexfauquette
Copy link
Member

The array has the advantage to be easier to understand and to allow adding extra arguments later. But I'm not sure if passing an array like useBarSeries(['seriesId1', 'seriesId2']) could cause perf issue because at each render it would creat a new array 🤔

Maybe we should wait for the end of the plugin migration to see if one DX allows easier perf otpimisation than the other

@JCQuintas
Copy link
Member Author

The array has the advantage to be easier to understand and to allow adding extra arguments later. But I'm not sure if passing an array like useBarSeries(['seriesId1', 'seriesId2']) could cause perf issue because at each render it would creat a new array 🤔

Maybe we should wait for the end of the plugin migration to see if one DX allows easier perf otpimisation than the other

Optimisation-wise we can just ...args into the dep array. Though we have to disable the eslint error for exaustive deps 🙃

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

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

bernardobelchior added a commit to bernardobelchior/mui-x that referenced this pull request Feb 4, 2025
bernardobelchior added a commit to bernardobelchior/mui-x that referenced this pull request Feb 4, 2025
bernardobelchior added a commit to bernardobelchior/mui-x that referenced this pull request Feb 5, 2025
bernardobelchior added a commit to bernardobelchior/mui-x that referenced this pull request Feb 6, 2025
bernardobelchior added a commit to bernardobelchior/mui-x that referenced this pull request Feb 7, 2025
@JCQuintas JCQuintas force-pushed the remove-unstable-useseries branch from 6d2192a to 7a70ef4 Compare February 7, 2025 18:17
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 7, 2025
@JCQuintas JCQuintas changed the title [charts] Stabilize useSeries and useXxxSeries hooks [charts] Document public hooks and improve types Feb 7, 2025
@JCQuintas JCQuintas changed the title [charts] Document public hooks and improve types [charts] Add typedocs to pubic hooks and improve types Feb 7, 2025

/**
* Get all the X axes.
Copy link
Member

Choose a reason for hiding this comment

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

I think that's how we standardize the docs naming for x/y axes

Suggested change
* Get all the X axes.
* Get all the x-axes.

Comment on lines 6 to 29
export function useSeriesOfType<T extends keyof ChartsSeriesConfig>(
seriesType: T,
...seriesIds: SeriesId[]
) {
const series = useSeries();

return React.useMemo(
() => {
if (seriesIds.length === 0) {
return series[seriesType];
}

if (seriesIds.length === 1) {
return series?.[seriesType]?.series[seriesIds[0]];
}

return seriesIds.map((id) => series?.[seriesType]?.series[id]).filter(Boolean);
},
// DANGER: Ensure that the dependencies array is correct.
// eslint-disable-next-line react-compiler/react-compiler
// eslint-disable-next-line react-hooks/exhaustive-deps
[series[seriesType], ...seriesIds],
);
}
Copy link
Member

Choose a reason for hiding this comment

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

Did you consider using selectors directly for the meoization?

export const selectorScatterSeries = createSelector(
  [selectorChartSeriesProcessed],
  (series) => series.scatter)
);


export const selectorScatterSeriesWithIds = createSelector(
  [
    selectorScatterSeries,
    (_, ids: SeriesId | SeriesId[]
  ],
  (scatterSeries, ids) => {
    if(typeof ids === 'object'){
        return ids.map(id => scatterSeries.series[id] ?? null)
    }
    return scatterSeries.series[ids] ?? null
  }
);

Then

useScatterSeries(ids?:  SeriesId | SeriesId[]){
  const store = useStore()

  return useSelector(store, ids===undefined ? selectorScatterSeries : selectorScatterSeriesWithIds, ids);
}

As long as the ids stay the same, you should benefit from selector memoization

Copy link
Member Author

Choose a reason for hiding this comment

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

It was quite hard to create a place where I could mock the return values, so in the end I'm testing them with the real chart components 😓

@alexfauquette alexfauquette changed the title [charts] Add typedocs to pubic hooks and improve types [charts] Let the useXxxSeries support array of ids and document them Feb 10, 2025
@alexfauquette
Copy link
Member

I've allowed my self to update your PR title

@JCQuintas
Copy link
Member Author

I've allowed my self to update your PR title

Good, because it said pubic hooks before 😳

import { useStore } from './store/useStore';
import { useSelector } from './store/useSelector';

export function createSeriesSelectorsOfType<T extends keyof ChartsSeriesConfig>(seriesType: T) {
Copy link
Member Author

Choose a reason for hiding this comment

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

@alexfauquette tried to simplify the logic and keep it in a single place, so we can use createSeriesSelectorsOfType('pie'), etc on the actual hooks.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not 100% sure, but your idea is to call something like

useScatterSeries('id1', 'id2')

But then the following lines will transform 'id1', 'id2' into ['id1', 'id2'] and so generate a new array which break the memoization.

export function useScatterSeries(...seriesIds: SeriesId[]): any {
  return selectorSeries(seriesIds);
}

For me the only way to let user (or react compiler) memorize the ids is to pass directly an array

Copy link

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

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 11, 2025
Comment on lines 9 to 35
/**
* Get access to the internal state of bar series.
* The returned object contains:
* - series: a mapping from ids to series attributes.
* - seriesOrder: the array of series ids.
* @returns {{ series: Record<SeriesId, DefaultizedBarSeriesType>; seriesOrder: SeriesId[]; } | undefined} barSeries
*/
export function useBarSeries(): ProcessedSeries['bar'];
/**
* Get access to the internal state of bar series.
*
* @param {SeriesId} seriesId The id of the series to get.
* @returns {ChartSeriesDefaultized<'bar'> | undefined} barSeries
*/
export function useBarSeries(seriesId: SeriesId): ChartSeriesDefaultized<'bar'> | undefined;
/**
* Get access to the internal state of bar series.
*
* @param {SeriesId[]} seriesIds The ids of the series to get. Order is preserved.
* @returns {ChartSeriesDefaultized<'bar'>[] | undefined} barSeries
*/
export function useBarSeries(
...seriesIds: SeriesId[]
): (ChartSeriesDefaultized<'bar'> | undefined)[];
export function useBarSeries(...seriesIds: SeriesId[]): any {
return selectorSeries(seriesIds);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Should we divide the logic for useAllScatterSeries/useScatterSeriesAll from the rest? The return values are wildly different 🤔

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 would add it to another PR though 😅

Copy link
Member

Choose a reason for hiding this comment

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

I agree. Finding a good name for this hook is the main difficulty. Maybe useScatterSeriesContext or useScatterSeriesState even if it does not exactly translate what it is

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

@alexfauquette alexfauquette left a comment

Choose a reason for hiding this comment

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

🎉

@JCQuintas JCQuintas added the enhancement This is not a bug, nor a new feature label Feb 11, 2025
@JCQuintas JCQuintas merged commit 9b0bc3f into mui:master Feb 11, 2025
21 checks passed
@JCQuintas JCQuintas deleted the remove-unstable-useseries branch February 11, 2025 13:59
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! enhancement This is not a bug, nor a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants