Conversation
WalkthroughThe PR refactors tooltip configuration across multiple chart components from a function-based approach to a memoized component-based pattern. Each chart component replaces its Changes
Sequence DiagramsequenceDiagram
participant ComponentA as Chart Component
participant OldPattern as SetTooltipEntrySettings<br/>(Old Pattern)
participant NewPattern as SetAreaTooltipEntrySettings<br/>(New Pattern)
participant Core as SetTooltipEntrySettings<br/>(Core)
participant Redux as Redux Store
rect rgb(240, 248, 255)
Note over ComponentA,Redux: OLD: Function-based Composition
ComponentA->>OldPattern: render with fn={getTooltipEntrySettings} args={props}
OldPattern->>OldPattern: fn(args) computes tooltipEntrySettings
OldPattern->>Core: <SetTooltipEntrySettings fn={fn} args={args} />
Core->>Core: useLayoutEffect: fn(args) to compute
Core->>Redux: dispatch setTooltipEntrySettings(computed)
end
rect rgb(255, 250, 240)
Note over ComponentA,Redux: NEW: Component-based Composition
ComponentA->>NewPattern: render with dataKey={...} stroke={...} etc
NewPattern->>NewPattern: Compute tooltipEntrySettings
NewPattern->>Core: <SetTooltipEntrySettings tooltipEntrySettings={config} />
Core->>Redux: dispatch setTooltipEntrySettings(config)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (8)
src/cartesian/Funnel.tsx (1)
127-163: Funnel tooltip wiring looks good; consider aligning with resolved defaultsThe new
SetFunnelTooltipEntrySettingscorrectly capturesdataDefinedOnItem, per-trapezoid positions, and the expected settings fields, and usingtrapezoidsfor positions is a nice improvement.One minor thing to consider: at the call site you pass
props.stroke,props.fill, andprops.hide, while the renderedFunnelWithStateuses the values fromresolveDefaultProps. If callers omit these props and rely ondefaultFunnelProps, the tooltip configuration will seestroke/fill/hideasundefined, so tooltip color/hidden state might not fully mirror the actual funnel appearance. If you want them to stay in sync even when only defaults are used, you could pass the resolvedstroke/fill/hidevalues intoSetFunnelTooltipEntrySettingsinstead.Also applies to: 385-400, 439-450
src/polar/Pie.tsx (1)
261-294: LGTM! Consider adding displayName for easier debugging.The memoized component pattern correctly fixes the tooltip state bug by ensuring stable references. The component will only re-render when its props change, creating a new
tooltipEntrySettingsobject that triggers the reference-based comparison inSetTooltipEntrySettings.Consider adding a displayName to improve the debugging experience:
const SetPieTooltipEntrySettings = React.memo( ({ dataKey, nameKey, sectors, stroke, strokeWidth, fill, name, hide, tooltipType, }: Pick< InternalProps, 'dataKey' | 'nameKey' | 'sectors' | 'stroke' | 'strokeWidth' | 'fill' | 'name' | 'hide' | 'tooltipType' >) => { const tooltipEntrySettings: TooltipPayloadConfiguration = { dataDefinedOnItem: sectors.map((p: PieSectorDataItem) => p.tooltipPayload), positions: sectors.map((p: PieSectorDataItem) => p.tooltipPosition), settings: { stroke, strokeWidth, fill, dataKey, nameKey, name: getTooltipNameProp(name, dataKey), hide, type: tooltipType, color: fill, unit: '', // why doesn't Pie support unit? }, }; return <SetTooltipEntrySettings tooltipEntrySettings={tooltipEntrySettings} />; }, ); +SetPieTooltipEntrySettings.displayName = 'SetPieTooltipEntrySettings';src/chart/Sankey.tsx (1)
443-471: LGTM! Consistent with the refactoring pattern.The implementation correctly follows the same memoized component pattern as other chart components. Consider adding displayName for debugging consistency across the codebase.
const SetSankeyTooltipEntrySettings = React.memo( ({ dataKey, nameKey, stroke, strokeWidth, fill, name, data, }: Pick<Props, 'dataKey' | 'nameKey' | 'stroke' | 'strokeWidth' | 'fill' | 'name' | 'data'>) => { const tooltipEntrySettings: TooltipPayloadConfiguration = { dataDefinedOnItem: data, positions: undefined, settings: { stroke, strokeWidth, fill, dataKey, name, nameKey, hide: false, type: undefined, color: fill, unit: '', }, }; return <SetTooltipEntrySettings tooltipEntrySettings={tooltipEntrySettings} />; }, ); +SetSankeyTooltipEntrySettings.displayName = 'SetSankeyTooltipEntrySettings';src/cartesian/Line.tsx (1)
176-209: LGTM! Consistent refactoring pattern.The Line component correctly implements the memoized tooltip configuration pattern. Consider adding displayName for consistency with other components.
+SetLineTooltipEntrySettings.displayName = 'SetLineTooltipEntrySettings';src/cartesian/Scatter.tsx (1)
218-258: LGTM! Well-structured with clear type definitions.The Scatter component introduces a dedicated type
InputRequiredToComputeTooltipEntrySettingswhich improves type clarity. The comment on Line 253 about unit support is helpful. Consider adding displayName for debugging.+SetScatterTooltipEntrySettings.displayName = 'SetScatterTooltipEntrySettings';src/chart/Treemap.tsx (1)
544-570: LGTM! Correctly handles Treemap's stateful nature.The component appropriately accepts
currentRootfrom Treemap's component state, ensuring tooltip configuration updates when navigation changes. The TODO comment on Line 554 provides helpful context. Consider adding displayName.+SetTreemapTooltipEntrySettings.displayName = 'SetTreemapTooltipEntrySettings';src/chart/SunburstChart.tsx (1)
126-158: LGTM! Correctly handles Map serialization.The conversion from Map to Record on Line 140 is necessary for Redux store compatibility, and the comment clearly explains this. The implementation follows the established pattern. Consider adding displayName.
+SetSunburstTooltipEntrySettings.displayName = 'SetSunburstTooltipEntrySettings';src/cartesian/Area.tsx (1)
195-228: LGTM! Completes the consistent refactoring pattern.The Area component correctly implements the memoized tooltip configuration, completing the PR-wide refactoring. Consider adding displayName for debugging consistency.
+SetAreaTooltipEntrySettings.displayName = 'SetAreaTooltipEntrySettings';
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
src/cartesian/Area.tsx(2 hunks)src/cartesian/Bar.tsx(2 hunks)src/cartesian/Funnel.tsx(2 hunks)src/cartesian/Line.tsx(2 hunks)src/cartesian/Scatter.tsx(3 hunks)src/chart/Sankey.tsx(3 hunks)src/chart/SunburstChart.tsx(2 hunks)src/chart/Treemap.tsx(2 hunks)src/polar/Pie.tsx(2 hunks)src/polar/Radar.tsx(2 hunks)src/polar/RadialBar.tsx(2 hunks)src/state/SetTooltipEntrySettings.tsx(2 hunks)src/state/tooltipSlice.ts(1 hunks)storybook/stories/API/component/LabelList.stories.tsx(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (13)
src/cartesian/Area.tsx (3)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/util/ChartUtils.ts (1)
getTooltipNameProp(642-653)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
src/state/SetTooltipEntrySettings.tsx (1)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)
src/chart/Sankey.tsx (2)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
src/polar/Radar.tsx (3)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/util/ChartUtils.ts (1)
getTooltipNameProp(642-653)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
src/cartesian/Funnel.tsx (2)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
src/chart/Treemap.tsx (2)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
src/cartesian/Line.tsx (3)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/util/ChartUtils.ts (1)
getTooltipNameProp(642-653)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
storybook/stories/API/component/LabelList.stories.tsx (2)
storybook/stories/API/props/utils.ts (1)
getStoryArgsFromArgsTypesObject(4-15)storybook/stories/API/props/LabelListProps.ts (1)
LabelListProps(44-110)
src/polar/RadialBar.tsx (3)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/util/ChartUtils.ts (1)
getTooltipNameProp(642-653)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
src/polar/Pie.tsx (3)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/util/ChartUtils.ts (1)
getTooltipNameProp(642-653)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
src/cartesian/Scatter.tsx (4)
src/util/types.ts (2)
DataKey(59-59)TooltipType(80-80)src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/util/ChartUtils.ts (1)
getTooltipNameProp(642-653)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
src/chart/SunburstChart.tsx (2)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
src/cartesian/Bar.tsx (3)
src/state/tooltipSlice.ts (1)
TooltipPayloadConfiguration(52-69)src/util/ChartUtils.ts (1)
getTooltipNameProp(642-653)src/state/SetTooltipEntrySettings.tsx (1)
SetTooltipEntrySettings(11-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build, Test, Pack
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
storybook/stories/API/component/LabelList.stories.tsx (1)
39-44: LGTM! Correct fix for property override order.The spread operator is now correctly positioned before the explicit property assignments, ensuring that
dataKey: 'uv'andposition: 'top'take precedence over any defaults fromgetStoryArgsFromArgsTypesObject(LabelListProps). This fixes the bug where defaults were overwriting explicit values.src/polar/Radar.tsx (1)
122-156: Radar tooltip settings component is consistent and correctly wiredThe memoized
SetRadarTooltipEntrySettingsbuilds aTooltipPayloadConfigurationthat aligns with legend naming/color logic and avoids item-level positions for now, and it’s fed with fully resolved props inRadar, so explicit props take precedence over defaults as expected. No issues spotted.Also applies to: 545-553
src/polar/RadialBar.tsx (1)
319-351: RadialBar tooltip configuration matches rendered data and stylingUsing
SetRadialBarTooltipEntrySettingswith selector-deriveddataand resolved stroke/fill/name gives a coherent tooltip configuration that mirrors the actual sectors, without changing external API. Looks good.Also applies to: 437-446
src/state/tooltipSlice.ts (1)
275-280: Replacing the whole tooltip payload entry is the right fixSwitching to
state.tooltipItemPayloads[index] = castDraft(next);keeps the index stable but updates the object reference, which addresses reference-based comparator issues without changing overall state shape. The guard onindex > -1still protects against missing entries. This looks correct.src/cartesian/Bar.tsx (1)
227-256: Bar tooltip entry settings are correctly encapsulated and passedThe new
SetBarTooltipEntrySettingsencapsulates the previous tooltip configuration into a memoized component, using the same stroke/fill/name/unit fields and feeding it with resolved props fromBarFn. This should preserve existing tooltip behavior while integrating cleanly with the new SetTooltipEntrySettings flow.Also applies to: 877-886
src/state/SetTooltipEntrySettings.tsx (1)
11-31: LGTM! This is the core fix for the tooltip state bug.The refactored signature accepting
tooltipEntrySettingsdirectly, combined with reference-based comparison on Line 27, correctly fixes the comparator issue mentioned in the PR objectives. The memoized wrapper components in chart files ensure thattooltipEntrySettingsreferences remain stable unless input props change, preventing unnecessary updates while still detecting legitimate changes.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6639 +/- ##
==========================================
+ Coverage 94.15% 94.17% +0.02%
==========================================
Files 494 494
Lines 41458 41666 +208
Branches 4826 4824 -2
==========================================
+ Hits 39033 39241 +208
Misses 2420 2420
Partials 5 5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Bundle ReportChanges will increase total bundle size by 7.64kB (0.29%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: recharts/bundle-es6Assets Changed:
view changes for bundle: recharts/bundle-cjsAssets Changed:
view changes for bundle: recharts/bundle-umdAssets Changed:
|
Description
We had two visual diff tests fail: https://www.chromatic.com/build?appId=63da8268a0da9970db6992aa&number=3175
The first one was trivial: the default was declared after the explicit prop and was overwriting it.
Second was more complicated. I made a mistake in #6616 in the comparator logic: it was looking up a tooltip settings by reference, which it could never find because it had created a new reference in the same reducer, so the original dispatch lost access to it. This means that the tooltip state stopped updating. Which means yes it fixed the infinite loop but it also broke initializing the tooltip position. I fixed it so that it's still memoized but updating properly.
Related Issue
#6613
Types of changes
Checklist:
Summary by CodeRabbit