-
Notifications
You must be signed in to change notification settings - Fork 823
Charts: Add standalone Legend component #44245
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
Conversation
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! |
Code Coverage SummaryCoverage changed in 5 files.
2 files are newly checked for coverage.
Full summary · PHP report · JS report Coverage check overridden by
Coverage tests to be added later
|
ce9977f
to
b018ace
Compare
- Create ChartLegendOptions interface with showValues, withGlyph, glyphSize, and renderGlyph options - Add ChartLegendProps interface extending LegendProps with chartId for future context integration - Implement useChartLegendData hook with overloads for SeriesData[] and DataPoint[]/DataPointPercentage[] - Support both series data and point data with proper color, shape, and glyph handling - Include valueDisplay preference for DataPointPercentage items - Return properly typed LegendItemWithGlyph[] or LegendItemWithoutGlyph[] arrays
- Create ChartLegend component as a wrapper around BaseLegend - Accept chartId prop for future context integration - Pass through all legend props to BaseLegend for consistent behavior - Enables standalone legend usage independent of chart showLegend prop
- Replace inline legend items creation with useChartLegendData hook - Pass withGlyph and glyphSize options to maintain existing functionality - Eliminates duplicate legend creation logic - Maintains all existing legend behavior and styling
- Replace inline legend items creation with useChartLegendData hook - Add useChartTheme hook to get provider theme for consistent legend colors - Move hook call to proper position to avoid rules-of-hooks violation - Remove duplicate legend creation logic - Maintains all existing legend behavior and styling
- Replace inline legend items creation with useChartLegendData hook in both components - Enable showValues option for both charts to display percentages in legend - Move hook calls to proper position to avoid rules-of-hooks violations - Remove duplicate legend creation logic - Maintain valueDisplay support for properly formatted percentage values - Keep all existing legend behavior and styling
- Export ChartLegend component and useChartLegendData hook from main index - Export ChartLegendProps and ChartLegendOptions types - Add chart-legend module index file with all exports - Makes standalone legend functionality available to consumers
- Create multiple story examples showing different usage patterns - Include stories for standalone usage, chart integration, and alignment options - Add stories demonstrating usage with LineChart, BarChart, and PieChart - Include examples for multiple charts sharing a legend - Add comprehensive test suite for ChartLegend component and useChartLegendData hook - Test both SeriesData and DataPointPercentage data types - Test memoization, glyph handling, and value display functionality - Fix TypeScript any usage in mock functions
- Resolve merge conflicts from chart context foundation PR - Fix duplicate legendItems declarations in PieChart and PieSemiCircleChart - Maintain custom color handling in PieSemiCircleChart using accessors - Fix type-only import for AnnotationStyles - Fix duplicate identifier in ChartLegend stories
- Add chart context integration to automatically retrieve legend data - Support chartId prop for standalone usage - Maintain fallback to items prop for manual data passing - Add story demonstrating standalone usage with chartId - Component works with showLegend=false charts - Accepts all BaseLegend props through inheritance
- Create validateSeriesData for line/bar charts - Create validatePercentageData for pie charts - Create validateSemiCircleData for semi-circle charts - Create validateBarChartData for bar-specific validation - Eliminates ~60 lines of duplicated validation code
- Enhances existing Legend to support chartId prop - Automatically retrieves legend data from chart context - Falls back to manual items prop for backward compatibility - Enables standalone legend usage with <Legend chartId="my-chart" />
- Extract formatPointValue for consistent value formatting - Extract createBaseLegendItem for common legend item creation - Extract processSeriesData and processPointData functions - Eliminates ~50 lines of duplicated mapping logic - Improves code readability and testability
- Split LegendProps into BaseLegendProps and LegendProps - BaseLegendProps for direct usage (items required) - LegendProps for context usage (items optional, chartId added) - Export new Legend component alongside BaseLegend - Export useChartLegendData and ChartLegendOptions
Thanks so much @adamwoodnz for such a thorough check and review, it's ended up being quite the mission of a PR to work through. I believe I've fixed up and addressed all of your comments with the exception of:
Both are coming in followups to this PR. If you get a chance, take another look through and see if you think this is okay enough now as it is to get it merged and keep moving forward 😄 |
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
* @param options - Configuration options for legend generation | ||
* @return Array of legend items ready for display | ||
*/ | ||
export function useChartLegendData< |
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.
Love this hook 🪝
@@ -275,7 +287,7 @@ const PieSemiCircleChartInternal: FC< PieSemiCircleChartProps > = ( { | |||
) } | |||
|
|||
{ showLegend && ( | |||
<Legend | |||
<BaseLegend |
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 wonder why chartId is not passed here, which is not consistent with the implementation in line chart
b022a55
to
701da72
Compare
…alone-legend-component' into add/charts-50-standalone-legend-component
shapeStyle: group?.options?.legendShapeStyle, | ||
} ) ), | ||
[ dataSorted, getColor ] | ||
// Memoize metadata to prevent unnecessary re-registration |
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.
Let's centralize the logic to useChartRegistration
so that it wouldn't have to be repeated every time.
@@ -347,17 +346,28 @@ const BarChartInternal: FC< BarChartProps > = ( { | |||
className={ styles[ 'bar-chart__legend' ] } | |||
shape={ legendShape } | |||
ref={ legendRef } | |||
chartId={ chartId } |
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 changed BaseLengend
to Legend
like what's happening in line chart. Please revert if this was intentional.
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 went ahead a tweaked a couple of small things. Hope you don't mind.
Maybe it's worth to take another review from @adamwoodnz, but it otherwise looks good to me!
------UPDATE------
It's awesome to see the standalone legends. Really cool 👍
Hi @adamwoodnz & @annacmc, I'm curious to hear your thoughts - is it possible we consolidate the providers for themes, annotations (is this one internal) and legends to reduce the burden of chart lib adoption? |
I initially tried adding the internal line chart context to the chart context, but it was complicated. I eventually decided I couldn't think of a reason another chart would need access to that information, so I kept it simple and scoped it to the chart instance. In terms of adoption friction; I don't think a consumer would ever need to deal with it as it currently stands, as it's constructed by the chart for the sole purpose of the annotations overlay. I can see a benefit to the chart context providing the theme though. |
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.
Clipping issues seem fixed, nice!
LGTM
related to: CHARTS-50: Standalone Legend Component
Proposed changes:
This feature adds a flexible standalone Legend component that can work
independently with manual data or automatically integrate with charts through a
shared context system. The new
useChartLegendData
hook processes chart data(SeriesData, DataPointPercentage) into legend format, while the Chart Context
allows legends to be shared between multiple charts using chartId props. All
existing chart components have been updated to support this system while
maintaining backward compatibility.
Other information:
Jetpack product discussion
Does this pull request change what data or activity we track or use?
No data tracking changes.
Testing instructions:
Storybook Testing
Core Functionality
standalone legends via chartId
Performance & Quality
Regression Testing
showLegend={true}