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] PieChart onClick prop in the series data and demo #10506

Merged
merged 10 commits into from
Oct 2, 2023

Conversation

giladappsforce
Copy link
Contributor

@giladappsforce giladappsforce commented Sep 28, 2023

Fix #10507

Added a new prop to PieChart series data called onClick, it's propagated to the underlying SVG element which triggers it and sends back the item that was clicked.

also added demo section to show this behavior.

Verified

This commit was signed with the committer’s verified signature.
tisonkun tison
@giladappsforce
Copy link
Contributor Author

#10507

@mui-bot
Copy link

mui-bot commented Sep 28, 2023

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

Updated pages:

Generated by 🚫 dangerJS against 9a88b90

Verified

This commit was signed with the committer’s verified signature.
tisonkun tison
@zannager zannager added the component: charts This is the name of the generic UI component, not the React module! label Sep 28, 2023
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.

Thanks for your nice contribution 👍. I'm just concerned by how it would work with other charts that don't use an object per item such as bar charts

Comment on lines 20 to 32
<PieChart
series={[
{
data: [
{ id: 0, value: 10, label: 'series A', onClick: setClickedItem },
{ id: 1, value: 15, label: 'series B', onClick: setClickedItem },
{ id: 2, value: 20, label: 'series C', onClick: setClickedItem },
],
},
]}
width={400}
height={200}
/>
Copy link
Member

Choose a reason for hiding this comment

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

What would you think about this way of doing it? This is how Nivo and Rechart do it, and I think it scales better with other charts.

Suggested change
<PieChart
series={[
{
data: [
{ id: 0, value: 10, label: 'series A', onClick: setClickedItem },
{ id: 1, value: 15, label: 'series B', onClick: setClickedItem },
{ id: 2, value: 20, label: 'series C', onClick: setClickedItem },
],
},
]}
width={400}
height={200}
/>
<PieChart
series={[
{
data: [
{ id: 0, value: 10, label: 'series A' },
{ id: 1, value: 15, label: 'series B' },
{ id: 2, value: 20, label: 'series C' },
],
},
]}
onClick={setClickedItem}
width={400}
height={200}
/>

I think it could return 3 arguments: PieItemIdentifier is a small object that identifies the item. The item (what you are already passing) and maybe the event

I don't know if PieItemIdentifier and the item could be fusion. I such a case, it would be a nice signature (data, event) => void

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 that it would be more flexible
I just wonder if we should name it onItemClik (or similar) and keep onClick for the root node event.

Concerning the signature, the core puts the event on the 1st param, might make sense to follow the same nomenclature here

Copy link
Member

@alexfauquette alexfauquette Sep 29, 2023

Choose a reason for hiding this comment

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

Both recharts and nivo use onClick, and in 99% of the use case you want to trigger action on item click.

If you reach a level of customisation where you need to get click from the surface, you might want to use composition. Then it will be possible to do to the following

<ChartContainer onClick={handleSurfaceClick}>
  <BarPlot onClick={handleBarClick} />
  <LinePlot onClick={handleLineClick} />
</ChartContainer>

I agree with the event/data order

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved onclick handler to root component and added Identifier and event

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.

Thanks for the update. I added two commits.

One for minor modifications:

  • put native events first
  • use pieItemIdentifier typing
  • some small code cleaning

And a second one to improve the demonstration. If it's OK for you we can merge as it is

@@ -66,7 +66,7 @@ const PieArcRoot = styled('path', {
}));

export type PieArcProps = Omit<PieArcOwnerState, 'isFaded' | 'isHighlighted'> &
Omit<React.ComponentPropsWithoutRef<'path'>, 'onClick'> &
React.ComponentPropsWithoutRef<'path'> &
Copy link
Member

Choose a reason for hiding this comment

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

Since we now have the custom onClick set at the <PiePlot/> level, we can use native event listener type

Comment on lines 63 to 65
event: React.MouseEvent<SVGPathElement, MouseEvent>,
pieItemIdentifier: PieItemIdentifier,
item: DefaultizedPieValueType,
Copy link
Member

Choose a reason for hiding this comment

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

I modified the order.

Instead of using the pie slice id which is not mandatory to simplify the creation of basics pie charts (maybe it should be), I used the PieItemIdentifier which contains:

  • The type of the series ('pie')
  • The series id
  • The index of the pie slice

At least having the series' id is necessary if you plot a pie chart with multiple pie like for example the two level pie example

Comment on lines +125 to +126
onClick={(event) =>
onClick?.(event, { type: 'pie', seriesId, dataIndex: index }, item)
Copy link
Member

Choose a reason for hiding this comment

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

Just code simplification. Except if you see a drawback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason for the check is the cursor pointer, the check is currently if the onClick is undefined, with your change all pie slices have cursor pointer.

@@ -141,7 +138,6 @@ function PiePlot(props: PiePlotProps) {
outerRadius={outerRadius ?? availableRadius}
cornerRadius={cornerRadius}
id={seriesId}
onClick={() => null}
Copy link
Member

Choose a reason for hiding this comment

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

I don't see why having it

Comment on lines +6 to +10
const items = [
{ value: 10, label: 'series A ( no Id )' },
{ id: 'id_B', value: 15, label: 'series B' },
{ id: 'id_C', value: 20, label: 'series C' },
];
Copy link
Member

Choose a reason for hiding this comment

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

I moved the item out of the demo definition since it is not an editable state

@alexfauquette alexfauquette merged commit 1f77a73 into mui:master Oct 2, 2023
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.

[charts] Allows to get clicks from pie slice
5 participants