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

Sunburst chart #4037

Merged
merged 25 commits into from Jan 10, 2024
Merged

Sunburst chart #4037

merged 25 commits into from Jan 10, 2024

Conversation

csdiehl
Copy link
Contributor

@csdiehl csdiehl commented Jan 4, 2024

Description

Adds an entirely new chart type, the Sunburst Chart - resolves #3842.

Note: this is a WIP. I've added a Typescript component for a responsive sunburst chart, a story to demonstrate the functionality, and mock data. I still need to add event handlers, and a tooltip - I wanted to give this a chance to be reviewed before changes grow too large, and I'm looking for guidance on the best way to integrate these elements to match the style of existing components.

Related Issue

#3842

Motivation and Context

This adds a popular and useful new hierarchical chart type that is not addressed by any existing component in the library.

How Has This Been Tested?

I have not added tests yet.

Screenshots (if appropriate):

Current state of the chart - responsive dimensions and labels, still needs interactivity.

Screenshot 2024-01-03 at 6 59 24 PM

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • I have added a storybook story or extended an existing story to show my changes
  • All new and existing tests passed.

@csdiehl csdiehl marked this pull request as draft January 4, 2024 03:08
Copy link
Member

@ckifer ckifer left a comment

Choose a reason for hiding this comment

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

To be honest, this looks awesome. Super clean.

We could maybe factor some of the logic out into testable functions, but besides that and the ability to customize everything this looks great.

You will definitely face issues when integrating with the current Tooltip situation and ideally we don't fit the style of the existing components because it is mostly bad 😅. @PavelVanecek is working on moving to an approach using Context instead of the giant generator function which will make this a lot easier.

Until then I think we can focus on getting this part to a good spot

package.json Outdated Show resolved Hide resolved
src/chart/SunburstChart.tsx Outdated Show resolved Hide resolved
Comment on lines 105 to 106
fontFamily="sans-serif"
fontWeight="bold"
Copy link
Member

Choose a reason for hiding this comment

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

some of these values are pretty arbitrary, probably we should allow the user to pass in their own Text props or a custom Text component

Copy link
Contributor

Choose a reason for hiding this comment

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

👍 We should evaluate all props to be maximum consistent with the existing API in other places.

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 think the remaining props needed to make it consistent are dataKey, event handlers and animation props (if those are needed for this chart type). What is the dataKey used for?

Copy link
Contributor

Choose a reason for hiding this comment

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

Given a dataset with multiple rows such as [{a:1, b:2}. {a:3, b:4}]
The dataKey for example for a Line component identifies which row to use for the line values. The dataKey on the XAxis identifies which row to use for the xAxis ticks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

got it - I added this in, so instead of just value, the user can pass any data key

src/chart/SunburstChart.tsx Outdated Show resolved Hide resolved
@csdiehl
Copy link
Contributor Author

csdiehl commented Jan 5, 2024

thanks for reviewing @ckifer! Makes sense - the tooltip integration was my biggest question. Looks like the API allows users to add a tooltip as a child component, but some charts, like treemap, also have their own tooltip functions.

I'll focus on addressing your comments and adding unit tests for what is already here.

@ckifer
Copy link
Member

ckifer commented Jan 6, 2024

I would way we probably want closer to how Tree Map works, if you want to create a similar function in the mean time I think that would be fine

children?: React.ReactNode;
fill?: string;
stroke?: string;
textOptions?: TextOptions;
Copy link
Contributor

Choose a reason for hiding this comment

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

Comments above each of these definitions will automatically land in storybook user facing documentation. We do not do this everywhere, but we totally should with all new Charts.

This will show up in the ArgsTable in the description column.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

seems like most of these already have default descriptions that fit pretty well, but I added comments for additional clarification. Let me know if anything is still unclear

fill?: string;
}

const hierarchy: SunburstData = {
Copy link
Contributor

Choose a reason for hiding this comment

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

The file is called hierarchy, the type used here is SunburstData though. Should this exist as a separate file?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file would make a lot of sense if we were to use a shared type between TreeMap and SunburstChart data? Is that possible / does it even make sense?

If not, I would recommend to integrate this data into the SunburstChart story.

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 think it would make sense to use the same type for both. But I think the size property should be re-named value since it could represent any quantitative value, and it should support a custom fill color.

For now, I'll just delete this file and integrate the data into the sunburst story to avoid changing treemap.

Copy link
Contributor

@nikolasrieble nikolasrieble left a comment

Choose a reason for hiding this comment

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

I tested it more thoroughly and reviewed the whole PR in detail.
This is a great contribution, I do not see this interfering with any ongoing refactoring, and it adds direct user value.

Thank you for putting in the effort and time ❤️ 💪 Great work.

Please do finalise by fixing the ArgsTable as shown in the screenshot.

test/polar/Sunburst.spec.tsx Outdated Show resolved Hide resolved
fill?: string;
}

const hierarchy: SunburstData = {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file would make a lot of sense if we were to use a shared type between TreeMap and SunburstChart data? Is that possible / does it even make sense?

If not, I would recommend to integrate this data into the SunburstChart story.

storybook/stories/API/chart/SunburstChart.mdx Show resolved Hide resolved
Copy link
Member

@ckifer ckifer left a comment

Choose a reason for hiding this comment

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

Looking good, added a few more comments

package.json Show resolved Hide resolved
src/chart/SunburstChart.tsx Show resolved Hide resolved
src/chart/SunburstChart.tsx Outdated Show resolved Hide resolved
storybook/stories/API/chart/SunburstChart.stories.tsx Outdated Show resolved Hide resolved
test/polar/Sunburst.spec.tsx Outdated Show resolved Hide resolved
const { x: textX, y: textY } = polarToCartesian(0, 0, innerR + radius / 2, -(start + arcLength - arcLength / 2));
currentAngle += arcLength;
sectors.push(
<g>
Copy link
Member

Choose a reason for hiding this comment

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

wonder if there are any accessibility concerns we can take care of up front? aria-labels, tabIndex, etc.?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that's a good idea - I set these attributes on the g element that wraps each data point, and tested that the chart is now keyboard accessible

@csdiehl csdiehl marked this pull request as ready for review January 9, 2024 07:28
@csdiehl
Copy link
Contributor Author

csdiehl commented Jan 9, 2024

Ok @ckifer and @nikolasrieble thanks for reviewing - I think I addressed all your comments, but let me know if I missed anything! I updated the props in the documentation to reflect only those that are currently available on this component

I also added tooltip, following the general approach used in Treemap It's not in the exactly right location, but I think I got pretty close

Copy link
Member

@ckifer ckifer left a comment

Choose a reason for hiding this comment

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

I wonder if we could release this as experimental somehow.. We don't currently have a process for that but

Copy link
Member

@ckifer ckifer left a comment

Choose a reason for hiding this comment

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

Looks awesome! Wondering if we would do well to add some sort of caveat to the chart that it is new or experimental, but I say lets merge it!

We can release it next minor and have the caveat exist in the changelog.

OR we could not export it yet and test it internally a bit.

Amazing contribution btw

@ckifer ckifer merged commit b0c71e3 into recharts:master Jan 10, 2024
5 checks passed
@ckifer
Copy link
Member

ckifer commented Jan 10, 2024

After looking at the deployed storybook you're right about the Text for sure, though not sure what we can do except leave it to the users to address themselves.

The Tooltip is definitely off a bit, we can keep iterating! 🚀

@uson1x
Copy link

uson1x commented Jan 10, 2024

What a timing! We were just about to hunt for a graph library for sunburst charts and here our beloved recharts adding it at the same moment.

I'm curious, maybe you have some ideas on how we could add animations to it for when you change the data?

In our case, we have a single layer (no children) of data to show and when user clicks on one of the segments, we want to async load new data for this segment from server and replace the existing single layer with a new single layer (but new numbers and colors). Would be nice to do it with some nice animations, so it feels more fluid.

Soo... I don't assume you had plans on working on sunburst animations next? 😄
And I hoped maybe you could share some pointers on how we could attempt to add those ourselves?

Thank you so much!

@csdiehl
Copy link
Contributor Author

csdiehl commented Jan 10, 2024

thanks @ckifer! I agree - we can fix anything that comes up in a separate PR. I'll leave it up to you about when to release. Looking forward to contributing more to the library!

@uson1x there is an onClick prop - so you could pass a callback to that that updates your data. But as of right now, it wouldn't animate. I see that animations are supported in some other charts, so that's something we could likely add later.

@csdiehl csdiehl deleted the sunburst-chart branch January 10, 2024 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sunburst Charts
6 participants