Prevent overlapping PolarAngleAxis ticks#6611
Conversation
WalkthroughThe PR introduces a specialized tick selector for polar angle axes that deduplicates ticks mapped to the same circular position (0/360 degrees), updates component and test references to use this new selector, removes a console warning ignore pattern from test helpers, and adjusts test expectations to remove 360-degree tick assertions. Changes
Sequence DiagramsequenceDiagram
participant Component as PolarAngleAxis Component
participant Selector as selectPolarAngleAxisTicks
participant CoreSelector as selectPolarAxisTicks
participant Store as Redux State
Component->>Selector: Request angle axis ticks
Selector->>CoreSelector: Get all ticks for angleAxis
CoreSelector->>Store: Query ticks from state
Store-->>CoreSelector: Return raw ticks array
CoreSelector-->>Selector: Return ticks
Selector->>Selector: Normalize tick angles to 0–359.999
Selector->>Selector: Deduplicate by position (keep first)
Selector-->>Component: Return deduplicated ticks
Note over Selector: Removes 360° duplicates of 0°
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 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 (1)
src/state/selectors/polarScaleSelectors.ts (1)
99-122: Consider floating-point precision when comparing coordinates.The deduplication logic correctly normalizes circular coordinates and removes duplicates. However, using floating-point
tick.coordinatevalues directly as Map keys could lead to near-duplicate angles being treated as distinct (e.g., 0.0000001 and 0.0000002).If coordinates are always integers or have controlled precision, this is fine. Otherwise, consider rounding to a fixed precision before using as a Map key:
const uniqueTicksMap = new Map<number, CartesianTickItem>(); ticks.forEach(tick => { - const normalizedCoordinate = (tick.coordinate + 360) % 360; + const normalizedCoordinate = Math.round(((tick.coordinate + 360) % 360) * 1e10) / 1e10; if (!uniqueTicksMap.has(normalizedCoordinate)) { uniqueTicksMap.set(normalizedCoordinate, tick); } });Verify whether tick coordinates can have floating-point precision issues by checking how D3 generates these values:
#!/bin/bash # Description: Check how tick coordinates are generated and if they're integers or floats # Search for where CartesianTickItem coordinates are assigned ast-grep --pattern 'coordinate: $_' # Look for D3 tick generation rg -n -C3 'ticks\(\)' --type=ts --type=tsx
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (30)
test-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Reversed-Angle-Axis-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Reversed-Angle-Axis-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Reversed-Angle-Axis-1-webkit-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Reversed-Both-Axes-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Reversed-Both-Axes-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Reversed-Both-Axes-1-webkit-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Reversed-Radius-Axis-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Reversed-Radius-Axis-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Reversed-Radius-Axis-1-webkit-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Custom-Domain-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Custom-Domain-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Custom-Domain-1-webkit-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Data-Keys-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Data-Keys-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Data-Keys-1-webkit-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Data-Keys-And-Types-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Data-Keys-And-Types-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Data-Keys-And-Types-1-webkit-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Default-Axes-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Default-Axes-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Default-Axes-1-webkit-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Radius-Axis-Vertically-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Radius-Axis-Vertically-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Radius-Axis-Vertically-1-webkit-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Types-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Types-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Rings-With-Types-1-webkit-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Stacked-RadialBar-Chart-1-chromium-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Stacked-RadialBar-Chart-1-firefox-linux.pngis excluded by!**/*.pngtest-vr/__snapshots__/tests/RadialBarChart.spec-vr.tsx-snapshots/Stacked-RadialBar-Chart-1-webkit-linux.pngis excluded by!**/*.png
📒 Files selected for processing (5)
omnidoc/omnidoc.spec.ts(1 hunks)src/polar/PolarAngleAxis.tsx(2 hunks)src/state/selectors/polarScaleSelectors.ts(1 hunks)test/helper/consoleWarningToError.ts(0 hunks)test/polar/PolarAngleAxis.spec.tsx(0 hunks)
💤 Files with no reviewable changes (2)
- test/polar/PolarAngleAxis.spec.tsx
- test/helper/consoleWarningToError.ts
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Do not hardcode any user-facing strings or formatting choices in the library code; leave internationalization to library users
Files:
src/polar/PolarAngleAxis.tsxsrc/state/selectors/polarScaleSelectors.ts
🧠 Learnings (7)
📚 Learning: 2025-10-25T07:35:46.188Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-10-25T07:35:46.188Z
Learning: Applies to test/**/vitest.setup.ts : Ensure vi.useFakeTimers() is configured in the Vitest setup file
Applied to files:
omnidoc/omnidoc.spec.ts
📚 Learning: 2025-10-25T07:35:46.188Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-10-25T07:35:46.188Z
Learning: Write unit tests using Vitest and React Testing Library
Applied to files:
omnidoc/omnidoc.spec.ts
📚 Learning: 2025-10-25T07:36:02.229Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T07:36:02.229Z
Learning: When running unit tests, prefer running a single test file via: npm run test -- path/to/TestFile.spec.tsx
Applied to files:
omnidoc/omnidoc.spec.ts
📚 Learning: 2025-10-25T07:35:46.188Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-10-25T07:35:46.188Z
Learning: Applies to test/**/*.test.{ts,tsx} : Prefer using the createSelectorTestCase helper when writing or modifying tests
Applied to files:
omnidoc/omnidoc.spec.ts
📚 Learning: 2025-10-25T07:35:46.188Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-10-25T07:35:46.188Z
Learning: Applies to test/**/*.test.{ts,tsx} : When using user-event, initialize with userEvent.setup({ advanceTimers: vi.runOnlyPendingTimers }) or use test/helper/userEventSetup.ts
Applied to files:
omnidoc/omnidoc.spec.ts
📚 Learning: 2025-10-25T07:35:46.188Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-10-25T07:35:46.188Z
Learning: Applies to test/**/*.test.{ts,tsx} : Avoid vi.runAllTimers() in tests to prevent infinite loops caused by chained scheduled timers
Applied to files:
omnidoc/omnidoc.spec.ts
📚 Learning: 2025-10-25T07:36:02.229Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T07:36:02.229Z
Learning: Recharts aims for simple, declarative, and composable charts; prioritize consistency, usability, performance, and accessibility
Applied to files:
src/polar/PolarAngleAxis.tsx
🧬 Code graph analysis (2)
src/polar/PolarAngleAxis.tsx (2)
src/state/hooks.ts (1)
useAppSelector(40-50)src/state/selectors/polarScaleSelectors.ts (1)
selectPolarAngleAxisTicks(99-122)
src/state/selectors/polarScaleSelectors.ts (3)
src/state/store.ts (1)
RechartsRootState(94-94)src/state/cartesianAxisSlice.ts (1)
AxisId(8-8)src/util/types.ts (1)
CartesianTickItem(769-773)
⏰ 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 (3)
omnidoc/omnidoc.spec.ts (1)
1-1: LGTM!The addition of the
testimport is correct and necessary for thetest.eachusage on lines 139 and 160.src/polar/PolarAngleAxis.tsx (2)
20-20: LGTM!The import change correctly updates to use the specialized angle axis tick selector.
260-260: LGTM!The selector usage is correct and properly integrates the new deduplication logic for angle axis ticks. The parameters match the expected signature, and the return type is compatible with the existing code flow.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6611 +/- ##
=======================================
Coverage 94.16% 94.16%
=======================================
Files 493 493
Lines 41067 41081 +14
Branches 4773 4778 +5
=======================================
+ Hits 38671 38685 +14
Misses 2391 2391
Partials 5 5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Bundle ReportChanges will increase total bundle size by 1.43kB (0.05%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: recharts/bundle-cjsAssets Changed:
view changes for bundle: recharts/bundle-umdAssets Changed:
view changes for bundle: recharts/bundle-es6Assets Changed:
|
Description
Recharts sometimes renders duplicated ticks on angles 0 and 360, depending on how many ticks d3 decides to render. So let's add a condition to protect against that.
Related Issue
I couldn't find anyone complaining about it but we had plenty of examples in our own storybook.
Types of changes
Checklist:
Summary by CodeRabbit
Release Notes
Bug Fixes
Tests