-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[charts] Add VisibilityManager logic to allow managing series/items
#20571
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
base: master
Are you sure you want to change the base?
Conversation
|
Deploy preview: https://deploy-preview-20571--material-ui-x.netlify.app/ Bundle size report
|
CodSpeed Performance ReportMerging #20571 will not alter performanceComparing Summary
Footnotes |
| // We sort the keys based on the original stacking order to ensure consistency | ||
| const idOrder = stackedData.sort((a, b) => a.index - b.index).map((s) => s.key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about why this is needed. For me D3 takes care of the ordering with stackingOrder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to use the exact same order as stackedData.
IIRC the issue was that some ordering functions change the order based on value, so if we have value 0 for a hidden series it would be ordered first/last in the stack.
| const keyIndex = keys.indexOf(key); | ||
| const seriesId = ids[keyIndex]; | ||
|
|
||
| if (!isIdentifierVisible?.(`${seriesId}`)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assunme the `${seriesId}` is here to be sure seriesId are string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I could move it into the isIdentifierVisible though
| } | ||
| return d[key] ?? 0; | ||
| }) | ||
| .offset(stackingOffset)(d3Dataset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would assume the stackingOrder is needed for the visible stack and not for the one with all series.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mentioned above
| // Post-process visibleStackedData to fix positions for hidden series | ||
| // Hidden series should collapse to the cumulative position of visible series before them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure about this part.
On one side, the animations it creates look nice. On the other one, it looks like something that should be the responsability of the animation, not the data processing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum, I think I can achieve the same by tweaking the animation logic. Let me try
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the necessary changes: 114188a
seems reasonable @bernardobelchior wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its missing line chart adjustments that needs to be made, but it works nicely for barchart, animations are the same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My only remaining concern would be performances, because we render all the items even the one that ends up being hidden.
But I assume this could be simply solved by something like "if animation is disabled, useBarPlotData filter out hidden series"
| const visibleValues = series.visibleStackedData[dataIndex]; | ||
| const visibleValueCoordinates = visibleValues.map((v) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit pick: you don't need to rename values by visibleValues in the rendering part since every thing here is based on the visible stuff
|
|
||
| export const VISIBILITY_SEPARATOR = '-'; | ||
|
|
||
| export const buildIdentifier = (ids: string | (string | number)[]) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be more explicit in types like that?
| export const buildIdentifier = (ids: string | (string | number)[]) => { | |
| export const buildIdentifier = (ids: SeriesId | [SeriesId, ItemId]) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, we maybe need to add number as in ids: string | number | (string | number)[], but in general my idea was that this could eventually also be used by things like sankey, which doesn't use seriesId
| selectorVisibilityMap, | ||
| (visibilityMap) => { | ||
| return { | ||
| // Return an object as selectors don't correctly memoize direct functions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's the case, then we have an issue with highlight selectors 😮
| store, | ||
| params, | ||
| }) => { | ||
| // Manage controlled state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ther eis an helper for th ewarning messages
useAssertModelConsistencyOutsideOfProduction
| * Function to check if an item is visible based on its identifier. | ||
| * @param {string | (string | number)[]} identifier The identifier of the item. | ||
| * @returns {boolean} Whether the item is visible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "identifier" naming is a bit confusing because it conflicts with the identifiers used in highlight and tooltip.
The array signatures looks surprising too.
Just an idea that came in mind while writing the comment:
IsIdentifierVisible = (seriesId: SeriesId, itemId?: string | number) => booleanThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The array makes it easier to use imo, but the types are more complex.
My idea was if it is a string, use as is, but I think a better API might be (id: string|number, ...ids: (string|number)[])
This way we concatenate if there are more than 1 args
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The (id: string|number, ...ids: (string|number)[]) looks effectively better. The array was giving the feeling that we can provide multiple items at the same time
| // Calculate the cumulative sum of all visible series before this one | ||
| // Only accumulate values with the same sign |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you're doing back the job done in visibleStackedData. You could "just" need to find the id of the first visible series before this one and use it's stacked value
Split from #20404
Code is the same, but removed the implementation part to decrease complexity.
This should be ready to review/merge as the plugin is not hooked into anything.
Docs on:
https://deploy-preview-20404--material-ui-x.netlify.app/x/react-charts/legend/#toggle-visibility