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] On line chart click #10575

Closed
wants to merge 13 commits into from
Closed

Conversation

giladappsforce
Copy link
Contributor

on line chart click return the event, series data in clicked index, and the specific item clicked, with the index to extract data if needed.

Screen.Recording.2023-10-04.at.16.12.23.mov

@giladappsforce
Copy link
Contributor Author

#10549

@mui-bot
Copy link

mui-bot commented Oct 4, 2023

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 yarn l10n
  • Verify that you have added an export line in src/locales/index.ts for the new locale.
  • Run yarn docs:api which should add your new translation to the list of exported interfaces.
  • Clean files with yarn prettier.

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

Updated pages:

Generated by 🚫 dangerJS against 651e698

@zannager zannager added the component: charts This is the name of the generic UI component, not the React module! label Oct 4, 2023
}, {})
: null;

onClick?.({ event, seriesData, itemData });
Copy link
Member

Choose a reason for hiding this comment

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

?

Suggested change
onClick?.({ event, seriesData, itemData });
onClick?.(event, seriesData, itemData);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought it would be nicer to destructure anything you want but I removed it.

Copy link
Member

Choose a reason for hiding this comment

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

What's a bit weird, is that the same onClick applies to both the root of the svg and the items. Usually in react we would have a onClick on the surface, and another one on items.

So I agree with you that destructuring makes sense here

Suggested change
onClick?.({ event, seriesData, itemData });
onClick?.(event, { seriesData, itemData });

Another solution would have been to introduce onClick and onSurfaceClick to be used as follows:

const LineChart = ({onClick , onSurfaceClick}) => {
   return <ChartsContainer onClick={onSurfaceClick}>
		{/* ... */}
		<LinePlot onClick={onClick}/>
	</ChartsContainer>
}

The onSurfaceClick would be transmitted to the container and the onClick would be more like the pie charts event listener.

This would allow to disable the axis listener when not needed:

 disableAxisListener={
-  tooltip?.trigger !== 'axis' && axisHighlight?.x === 'none' && axisHighlight?.y === 'none'
+  !onSurfaceClick && tooltip?.trigger !== 'axis' && axisHighlight?.x === 'none' && axisHighlight?.y === 'none'
 }

Another advantage is more flexibility when using composition since you could set onClick only on some sub-components.

But your current solution is elegant, and has the advantage of ensuring that highlight and click are in sync.

@giladappsforce What do you think?

@alexfauquette alexfauquette self-requested a review October 9, 2023 09:54
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Oct 11, 2023
@github-actions
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 Oct 11, 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.

Hey,

Sorry for the review delay, I was a bit confused because I had in mind something like Nivo: you can click on an item and you receive data about this item.

This PR is more Rechart like: you click and you get information about all the item on the line

The solution seems good. It would be interesting to add a demo like the pie charts to easily experiment how it deals when clicking on an item

Comment on lines 48 to 52
const { axis, item } = React.useContext(InteractionContext);
const series = React.useContext(SeriesContext);

const onLineClick = (event: React.MouseEvent<SVGSVGElement, MouseEvent>) => {
const itemData = onClick
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 moving this into the useAxisEvent with another useEffect such that when the charts does not require such event because disableAxisListener=true it just get skipped

React.useEffect(() => {
    const element = svgRef.current;
    if (element === null || disableAxisListener) {
      return () => {};
    }
    
    const handleOnClick => { ... }
    
    element.addEventListener('click', handleOnClick)

    return () => {    element.removeEventListener('click', handleOnClick) }

    }, [axis, item, series, svgRef, disableAxisListener, onClick])

If you want something that should handle line, bar and scatter at the same time, you can have a look at the axis tooltip that does a similar job of gathering information from different series

@@ -18,6 +21,7 @@ export interface ChartsSurfaceProps {
sx?: SxProps<Theme>;
children?: React.ReactNode;
disableAxisListener?: boolean;
onClick?: OnLineClick;
Copy link
Member

Choose a reason for hiding this comment

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

I assume you plan to go with

onClick?: OnLineClick | OnBarClick | OnScatterClick;

I'm wondering if we coudl not do

onClick?: (event: React.MouseEvent<SVGElement>, params?: LineClickParams | BarClickParams | ScatterClickParams)

For PieChart it was not an issue since the onClick was passed to <PiePlot/> which is not a DOM element. It's a React.Fragment with multiple custom element. But here it's <Surface/> which correspond to the <svg /> which could get a native onClick

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

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

@michelengelen michelengelen changed the base branch from master to next November 6, 2023 14:21
MBilalShafi and others added 13 commits November 7, 2023 15:05
Co-authored-by: alexandre <[email protected]>
Co-authored-by: Alexandre Fauquette <[email protected]>
Co-authored-by: Lukas <[email protected]>
Signed-off-by: Michel Engelen <[email protected]>
Co-authored-by: Alexandre Fauquette <[email protected]>
Co-authored-by: Lukas <[email protected]>
Co-authored-by: Andrew Cherniavskii <[email protected]>
Co-authored-by: Bilal Shafi <[email protected]>
@alexfauquette
Copy link
Member

Closing since it's resolved by #11411 Sorry for the huge underestimation of the complexity of this feature. And thanks for this PR that helped me a lot to think about all the edge cases I did not had in mind 🙏

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! PR: out-of-date The pull request has merge conflicts and can't be merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.