Skip to content

Isolate Label positioning logic to new file#6829

Merged
PavelVanecek merged 2 commits into
mainfrom
cartesian-positioner
Jan 3, 2026
Merged

Isolate Label positioning logic to new file#6829
PavelVanecek merged 2 commits into
mainfrom
cartesian-positioner

Conversation

@PavelVanecek

@PavelVanecek PavelVanecek commented Dec 27, 2025

Copy link
Copy Markdown
Collaborator

Description

Non-functional refactoring. Move function from one file to another.

Related Issue

#5055
#2541
#488
#6643
#807
#5115

Motivation and Context

I like the API for Label positioning and I plan to reuse it for Legend and Tooltip positions in the future. For now only refactor though, no new features.

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)
  • Refactor

Checklist:

  • 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 VR test, or extended an existing story or VR test to show my changes

Summary by CodeRabbit

  • New Features

    • Added a cartesian positioning module providing types and utilities to compute element positions, anchors, offsets, and optional clamped sizing within trapezoid-style layouts.
  • Refactor

    • Label positioning now delegates to the new positioning utilities, simplifying rendering branches and view-box handling.
  • Tests

    • Added a comprehensive test suite covering many layout shapes, positions, clamping and edge cases.
    • Removed an obsolete test suite for the previous positioning implementation.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 27, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a new cartesian positioning utility (getCartesianPosition), refactors Label to use it, introduces type overloads for cartesianViewBoxToTrapezoid, updates snapshot manifests, removes legacy tests for getAttrsOfCartesianLabel, and adds a new comprehensive test suite for getCartesianPosition.

Changes

Cohort / File(s) Summary
Snapshot manifest updates
scripts/snapshots/es6Files.txt, scripts/snapshots/libFiles.txt, scripts/snapshots/typesFiles.txt
Added entries for es6/cartesian/getCartesianPosition.js, lib/cartesian/getCartesianPosition.js, and types/cartesian/getCartesianPosition.d.ts.
New cartesian positioning module
src/cartesian/getCartesianPosition.tsx
New public types (CartesianLabelPosition, GetCartesianPositionOptions, CartesianPosition) and getCartesianPosition function computing x/y, horizontalAnchor, verticalAnchor, and optional width/height for trapezoidal cartesian view boxes with offset and optional clamping to parentViewBox.
Label component refactor
src/component/Label.tsx
Replaced in-file Cartesian positioning with getCartesianPosition; added LabelPosition public type, introduced polarViewBoxToTrapezoid helper, adjusted isPolar type guard, and removed getAttrsOfCartesianLabel export.
Context typing
src/context/chartLayoutContext.tsx
Added two TypeScript overload signatures for cartesianViewBoxToTrapezoid (undefined → undefined, CartesianViewBoxRequired
Tests removed
test/component/Label.getAttrsOfCartesianLabel.spec.ts
Removed legacy test suite that targeted the deleted getAttrsOfCartesianLabel implementation.
Tests added
test/cartesian/getCartesianPosition.spec.ts
New comprehensive tests for getCartesianPosition covering rectangular and funnel view boxes, reversed funnels, negative dimensions, object-based positions (numeric and percent), center fallback, and clamp behavior with parentViewBox.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Label as Label component
participant Util as getCartesianPosition
participant Context as chartLayoutContext/cartesianViewBoxToTrapezoid
participant Parent as ParentViewBox (optional)
Note over Label,Util: Cartesian label render flow
Label->>Util: call getCartesianPosition(options: parentViewBox?, viewBox, position, offset, clamp)
Util->>Context: cartesianViewBoxToTrapezoid(viewBox)
Context-->>Util: trapezoid geometry
Util->>Util: compute anchors (top/bottom/left/right/inside/etc.), apply offsets
alt clamp && parentViewBox provided
Util->>Parent: clamp coordinates to parentViewBox
Parent-->>Util: clamped x,y,width,height
end
Util-->>Label: return CartesianPosition { x, y, horizontalAnchor, verticalAnchor, width?, height? }
Label->>Label: map to SVG attrs and render

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • ckifer

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: isolating Label positioning logic from Label.tsx into a new getCartesianPosition module.
Description check ✅ Passed The description covers key template sections with motivation and related issues, though testing details are minimal and type-of-change checkbox formatting differs from template.
✨ Finishing touches
  • 📝 Generate docstrings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
test/cartesian/useCartesianPosition.spec.ts (2)

554-575: Remove leftover debugging comments.

These comments appear to be developer notes from implementation/debugging and should be cleaned up before merging.

🔎 Suggested fix
     it('should return correct attributes for position "insideLeft"', () => {
       const options: GetCartesianPositionOptions = {
         position: 'insideLeft',
         offset,
         viewBox,
         parentViewBox,
         clamp: true,
       };
       const actual = getCartesianPosition(options);
-      // Wait, insideLeft logic clamps width?
-      // In original:
-      /*
-            if (position === 'insideLeft') {
-              return {
-                ...
-                ...sizeAttrs,
-              };
-            }
-            */
-      // sizeAttrs = parentViewBox ? { width: midHeightWidth, height } : {};
-
       const expected: CartesianPosition = {
         x: 105,
         y: 100,
         horizontalAnchor: 'start',
         verticalAnchor: 'middle',
-        width: 200, // midHeightWidth -> (200+200)/2 = 200
+        width: 200,
         height: 100,
       };
       expect(actual).toEqual(expected);
     });

590-611: Remove leftover debugging comments.

Similar to above, these comments should be cleaned up.

🔎 Suggested fix
     it('should NOT clamp attributes for position "top"', () => {
       const options: GetCartesianPositionOptions = {
         position: 'top',
         offset,
         viewBox,
         parentViewBox,
         clamp: false,
       };
       const actual = getCartesianPosition(options);
-      // Height and width should NOT be present if not clamped, ideally, or just standard.
-      // My implementation returns width/height only if clamped?
-      // "const sizeAttrs = clamp && parentViewBox ? { width: midHeightWidth, height } : {};"
-      // For top/bottom/left/right, they return size if clamped inside their blocks.
-
       const expected: CartesianPosition = {
         x: 200,
         y: 45,
         horizontalAnchor: 'middle',
         verticalAnchor: 'end',
       };
       expect(actual).toEqual(expected);
     });
src/cartesian/CartesianPosition.tsx (2)

71-76: Consider removing implementation notes.

These comments appear to be development notes explaining assumptions. If they're meant to stay, they could be condensed.

🔎 Suggested simplification
-  // We assume parentViewBox is generic if provided.
-  // If parentViewBox is Polar, we might ignore it or handle it differently in the future.
-  // For now, if we are here we assume we are not doing polar positioning logic *inside* this hook,
-  // but if parentViewBox is passed for clamping, we check if it is generic enough.
-  // The original code did: `if (parentViewBoxFromProps != null && !isPolar(parentViewBoxFromProps))`
-  // We will assume `parentViewBox` passed here is relevant for Cartesian.
+  // parentViewBox is assumed to be Cartesian if provided; polar viewBoxes should be filtered by callers.

264-270: Add a comment documenting the fallthrough positions.

Several positions defined in CartesianLabelPosition fall through to this default case: 'inside', 'outside', 'insideStart', 'insideEnd', 'end', 'center', 'centerTop', 'centerBottom', and 'middle'. All resolve to center positioning. Consider adding a comment to document this behavior.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd31202 and 00ca94f.

📒 Files selected for processing (8)
  • scripts/snapshots/es6Files.txt
  • scripts/snapshots/libFiles.txt
  • scripts/snapshots/typesFiles.txt
  • src/cartesian/CartesianPosition.tsx
  • src/component/Label.tsx
  • src/context/chartLayoutContext.tsx
  • test/cartesian/useCartesianPosition.spec.ts
  • test/component/Label.getAttrsOfCartesianLabel.spec.ts
💤 Files with no reviewable changes (1)
  • test/component/Label.getAttrsOfCartesianLabel.spec.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.{ts,tsx}: Never use any type (implicit or explicit) in TypeScript code
Prefer unknown over any and refine the type in TypeScript
Type function parameters and return values explicitly in TypeScript, do not rely on implicit any or inference; exceptions are React components and trivial functions
Do not use as type assertions in TypeScript; the only exception is as const

All imports from recharts must use the public API entry point (e.g., import { TooltipIndex } from 'recharts'). Imports from internal paths like recharts/types/* or recharts/src/* are not allowed and will fail the linter.

Files:

  • src/context/chartLayoutContext.tsx
  • test/cartesian/useCartesianPosition.spec.ts
  • src/component/Label.tsx
  • src/cartesian/CartesianPosition.tsx
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Ensure code lints by running npm run lint and follows Airbnb's Style Guide

Files:

  • src/context/chartLayoutContext.tsx
  • test/cartesian/useCartesianPosition.spec.ts
  • src/component/Label.tsx
  • src/cartesian/CartesianPosition.tsx
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not hardcode any strings or formatting choices in library code; users should provide localized strings as desired

Files:

  • src/context/chartLayoutContext.tsx
  • src/component/Label.tsx
  • src/cartesian/CartesianPosition.tsx
test/**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Aim for 100% unit test code coverage when writing new code

Files:

  • test/cartesian/useCartesianPosition.spec.ts
test/**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (test/README.md)

test/**/*.{test,spec}.{ts,tsx}: Aim for 100% unit test code coverage when writing new code
Prefer to use the createSelectorTestCase helper function when writing or modifying tests
Use the expectLastCalledWith helper function instead of expect(spy).toHaveBeenLastCalledWith(...) for better typing and autocompletion
Verify the number of selector calls using the spy object from createSelectorTestCase to spot unnecessary re-renders and improve performance
Mock getBoundingClientRect in tests using the helper function provided in test/helper/MockGetBoundingClientRect.ts
Use vi.useFakeTimers() in all tests due to Redux autoBatchEnhancer dependency on timers and requestAnimationFrame
Call vi.runOnlyPendingTimers() to advance timers after renders when not using createSelectorTestCase helper, and avoid vi.runAllTimers() to prevent infinite loops
Use userEvent.setup({ advanceTimers: vi.runOnlyPendingTimers }) or the userEventSetup helper function from test/helper/userEventSetup.ts when creating userEvent instances
When testing tooltips on hover, use vi.runOnlyPendingTimers() after each userEvent.hover() call or use the showTooltip helper function from tooltipTestHelpers.ts to account for requestAnimationFrame delays

Files:

  • test/cartesian/useCartesianPosition.spec.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

When running unit tests, prefer to run a single test file using npm run test -- path/to/TestFile.spec.tsx rather than running all tests with npm test

Unit tests should be placed in the test directory, with some tests also allowed in www/test. Test files follow the naming convention *.spec.tsx.

Files:

  • test/cartesian/useCartesianPosition.spec.ts
🧠 Learnings (6)
📚 Learning: 2025-12-16T08:12:13.355Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6783
File: test/util/ChartUtils.spec.tsx:15-16
Timestamp: 2025-12-16T08:12:13.355Z
Learning: In the recharts codebase, files in the `test` folder are allowed to import from internal paths (e.g., `../../src/state/cartesianAxisSlice`) and do not need to use the public API entry point (`src/index.ts`). The public API import restriction applies only to non-test code.

Applied to files:

  • scripts/snapshots/es6Files.txt
  • scripts/snapshots/libFiles.txt
  • test/cartesian/useCartesianPosition.spec.ts
  • scripts/snapshots/typesFiles.txt
  • src/component/Label.tsx
📚 Learning: 2025-12-14T13:58:49.197Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6771
File: src/shape/Curve.tsx:39-40
Timestamp: 2025-12-14T13:58:49.197Z
Learning: In the recharts codebase, hooks like useAppSelector and other hooks (e.g., useChartLayout()) return undefined when used outside Redux Provider context, instead of throwing. This enables components that call these hooks, such as Curve, to operate in standalone mode by falling back to prop values. During code reviews, ensure TSX files gracefully handle undefined results from hooks and implement fallbacks (e.g., via default props or explicit prop-based values) rather than assuming the hook is always within Provider.

Applied to files:

  • src/context/chartLayoutContext.tsx
  • src/component/Label.tsx
  • src/cartesian/CartesianPosition.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Mock `getBoundingClientRect` in tests using the helper function provided in `test/helper/MockGetBoundingClientRect.ts`

Applied to files:

  • test/cartesian/useCartesianPosition.spec.ts
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Add tests when adding new functionality or changing existing functionality; prefer unit tests for helper functions or RTL tests for rendering

Applied to files:

  • test/cartesian/useCartesianPosition.spec.ts
📚 Learning: 2025-12-26T15:59:11.238Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.238Z
Learning: Applies to **/*.{ts,tsx} : All imports from `recharts` must use the public API entry point (e.g., `import { TooltipIndex } from 'recharts'`). Imports from internal paths like `recharts/types/*` or `recharts/src/*` are not allowed and will fail the linter.

Applied to files:

  • scripts/snapshots/typesFiles.txt
  • src/component/Label.tsx
📚 Learning: 2025-11-23T13:30:10.395Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6669
File: www/src/docs/exampleComponents/ScatterChart/ScatterChartWithLabels.tsx:2-2
Timestamp: 2025-11-23T13:30:10.395Z
Learning: The `TooltipIndex` type from recharts is defined in `src/state/tooltipSlice.ts` but is not currently exported from the public API entry points. It should not be imported from `recharts/types/state/tooltipSlice` as this is an internal implementation path. An ESLint rule is needed to prevent regressions.

Applied to files:

  • scripts/snapshots/typesFiles.txt
🧬 Code graph analysis (2)
src/context/chartLayoutContext.tsx (1)
src/util/types.ts (2)
  • CartesianViewBoxRequired (1010-1010)
  • TrapezoidViewBox (1024-1052)
src/cartesian/CartesianPosition.tsx (4)
src/util/types.ts (2)
  • TrapezoidViewBox (1024-1052)
  • CartesianViewBoxRequired (1010-1010)
src/component/Text.tsx (2)
  • TextAnchor (61-61)
  • TextVerticalAnchor (70-70)
src/context/chartLayoutContext.tsx (1)
  • cartesianViewBoxToTrapezoid (24-38)
src/util/DataUtils.ts (3)
  • isNumber (24-25)
  • isPercent (21-22)
  • getPercentValue (51-82)
⏰ 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 (11)
scripts/snapshots/libFiles.txt (1)

19-19: Snapshot entry correctly added.

The new lib/cartesian/CartesianPosition.js entry is properly placed in alphabetical order within the cartesian section, consistent with the new module being introduced.

scripts/snapshots/typesFiles.txt (1)

19-19: Snapshot entry correctly added.

The new types/cartesian/CartesianPosition.d.ts entry is properly placed in alphabetical order, matching the new public type declarations.

scripts/snapshots/es6Files.txt (1)

19-19: Snapshot entry correctly added.

The new es6/cartesian/CartesianPosition.js entry is properly placed in alphabetical order, consistent with the lib and types snapshot updates.

src/context/chartLayoutContext.tsx (1)

22-38: Type overloads correctly improve type safety.

The function overloads provide precise type narrowing:

  • Passing undefined returns undefined
  • Passing a valid box returns TrapezoidViewBox

This eliminates the need for callers to handle undefined when they know they're passing a defined value, while preserving safety when the input might be undefined. Implementation correctly handles both cases.

src/cartesian/CartesianPosition.tsx (2)

66-69: Clean implementation with proper type safety.

The function signature is well-typed with explicit parameter and return types. The call to cartesianViewBoxToTrapezoid(viewBox) is type-safe because the overload guarantees a TrapezoidViewBox return when the input is defined (which it always is here since viewBox is required).


246-262: Good acknowledgment of known limitation.

The TODO comment appropriately documents a known approximation when using percentage-based coordinates on trapezoid shapes. This is transparent about the current behavior.

src/component/Label.tsx (5)

163-167: Good defensive handling of undefined context.

The updated logic correctly handles the case when chartContext is undefined (outside Provider context) by returning undefined instead of attempting to convert. This aligns with the codebase pattern where hooks return undefined outside Redux Provider context.


333-335: Type guard correctly updated for undefined handling.

The isPolar type guard now properly handles the case where viewBox might be undefined, returning false safely via the viewBox != null check.


354-370: New helper converts polar viewBox to trapezoid representation.

The polarViewBoxToTrapezoid function correctly converts a polar viewBox (circular) to a trapezoid by using the bounding square of the outer circle. The diameter-based dimensions create a square trapezoid representation suitable for Cartesian positioning.


451-471: Refactored Cartesian label positioning using new utility.

The integration with getCartesianPosition is well-implemented:

  • Null guard for cartesianBox prevents runtime errors
  • parentViewBox is filtered through isPolar to pass undefined for polar cases
  • clamp: true enables width/height constraints

The conditional spread pattern on lines 468-469 works but could be slightly cleaner.

🔎 Optional simplification
     positionAttrs = {
       x: cartesianResult.x,
       y: cartesianResult.y,
       textAnchor: cartesianResult.horizontalAnchor,
       verticalAnchor: cartesianResult.verticalAnchor,
-      ...(cartesianResult.width !== undefined ? { width: cartesianResult.width } : {}),
-      ...(cartesianResult.height !== undefined ? { height: cartesianResult.height } : {}),
+      ...(cartesianResult.width != null && { width: cartesianResult.width }),
+      ...(cartesianResult.height != null && { height: cartesianResult.height }),
     };

Or keep the explicit pattern for clarity—both are valid.


445-450: Comment indicates future refactoring intent.

The TODO comment about "Generic Polar Hook" suggests this area is flagged for future work, which aligns with the PR description mentioning potential reuse for Legend and Tooltip positioning.

});
});

describe('in regular Funnel (wide on top, narrow on bottom', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Minor typo: missing closing parenthesis in describe block name.

The describe block name is missing a closing parenthesis.

🔎 Suggested fix
-  describe('in regular Funnel (wide on top, narrow on bottom', () => {
+  describe('in regular Funnel (wide on top, narrow on bottom)', () => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
describe('in regular Funnel (wide on top, narrow on bottom', () => {
describe('in regular Funnel (wide on top, narrow on bottom)', () => {
🤖 Prompt for AI Agents
In test/cartesian/useCartesianPosition.spec.ts around line 237, the describe
block title string "in regular Funnel (wide on top, narrow on bottom" is missing
a closing parenthesis; edit that line to add the missing ')' before the closing
quote so the title reads "in regular Funnel (wide on top, narrow on bottom)"
ensuring the string and parentheses are balanced.

Comment on lines +614 to +634
describe('in reversed Funnel (narrow on top, wide on bottom', () => {
const viewBox: TrapezoidViewBox = { x: 100, y: 50, upperWidth: 150, lowerWidth: 200, width: 175, height: 100 };

// ... (rest of tests would be similar, checking a few key ones to be sure)

it('should return correct attributes for position "insideTop"', () => {
const options: GetCartesianPositionOptions = {
position: 'insideTop',
offset: 0,
viewBox,
};
const actual = getCartesianPosition(options);
const expected: CartesianPosition = {
x: 175,
y: 50,
horizontalAnchor: 'middle',
verticalAnchor: 'start',
};
expect(actual).toEqual(expected);
});
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find CartesianLabelPosition type definition
echo "=== CartesianLabelPosition definition ==="
rg "type CartesianLabelPosition|interface CartesianLabelPosition" src/ -A 10

echo ""
echo "=== Checking test file for position tests ==="
rg "position: '[^']+'" test/cartesian/useCartesianPosition.spec.ts | sort -u | head -30

echo ""
echo "=== Checking line 617 area in test file ==="
sed -n '610,625p' test/cartesian/useCartesianPosition.spec.ts

Repository: recharts/recharts

Length of output: 1764


🏁 Script executed:

#!/bin/bash
# Get the full CartesianLabelPosition definition
echo "=== Full CartesianLabelPosition definition ==="
rg "export type CartesianLabelPosition" src/cartesian/CartesianPosition.tsx -A 15

echo ""
echo "=== Check if any of the claimed missing positions appear anywhere in the codebase ==="
for pos in 'insideStart' 'insideEnd' 'end' 'centerTop' 'centerBottom' 'middle'; do
  count=$(rg "position.*['\"]$pos['\"]" src/ test/ | wc -l)
  echo "$pos: found $count times"
done

echo ""
echo "=== Check what positions are actually tested ==="
rg "position: '[^']+'" test/cartesian/useCartesianPosition.spec.ts | sed "s/.*position: '//" | sed "s/',.*//" | sort -u

Repository: recharts/recharts

Length of output: 816


Incomplete test coverage for reversed Funnel — update missing positions list.

The test suite is incomplete (confirmed by the placeholder comment), but the list of missing positions contains inaccuracies. CartesianLabelPosition only defines these positions that are tested:

'top' | 'left' | 'right' | 'bottom' | 'insideLeft' | 'insideRight' | 'insideTop' | 'insideBottom' | 'insideTopLeft' | 'insideBottomLeft' | 'insideTopRight' | 'insideBottomRight'

And these that are actually not tested:

  • 'inside'
  • 'outside'
  • 'insideStart'

The positions 'insideEnd', 'end', 'centerTop', 'centerBottom', and 'middle' do not exist in CartesianLabelPosition and should not be listed as missing. Consider completing test coverage for the three actual missing positions per the 100% coverage guideline.

@codecov

codecov Bot commented Dec 27, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.15385% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.85%. Comparing base (8bb5aa4) to head (6d49545).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/cartesian/getCartesianPosition.tsx 96.38% 6 Missing ⚠️
src/component/Label.tsx 95.23% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6829      +/-   ##
==========================================
- Coverage   93.85%   93.85%   -0.01%     
==========================================
  Files         531      532       +1     
  Lines       49391    49408      +17     
  Branches     5163     5166       +3     
==========================================
+ Hits        46355    46370      +15     
- Misses       3029     3031       +2     
  Partials        7        7              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

Copy link
Copy Markdown
Contributor

Staging Deployment Details

These deployments will remain available for 30 days.

To update snapshots: Comment /update-snapshots on this PR to automatically update the baseline screenshots.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
test/cartesian/getCartesianPosition.spec.ts (1)

599-817: Incomplete test coverage for several CartesianLabelPosition values.

Per the past review, the test suite doesn't cover these position values defined in CartesianLabelPosition: 'inside', 'outside', and 'insideStart'. Additionally, based on the type definition in the source file, the following positions are also untested: 'insideEnd', 'end', 'centerTop', 'centerBottom', and 'middle'.

Per coding guidelines, aim for 100% unit test code coverage when writing new code.

🧹 Nitpick comments (1)
test/cartesian/getCartesianPosition.spec.ts (1)

9-9: Describe block name doesn't match the function under test.

The describe block is named 'useCartesianPosition' but the function being tested is getCartesianPosition. This naming mismatch could cause confusion.

Suggested fix
-describe('useCartesianPosition', () => {
+describe('getCartesianPosition', () => {
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 00ca94f and d3814d2.

📒 Files selected for processing (6)
  • scripts/snapshots/es6Files.txt
  • scripts/snapshots/libFiles.txt
  • scripts/snapshots/typesFiles.txt
  • src/cartesian/getCartesianPosition.tsx
  • src/component/Label.tsx
  • test/cartesian/getCartesianPosition.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/snapshots/es6Files.txt
  • scripts/snapshots/typesFiles.txt
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.{ts,tsx}: Never use any type (implicit or explicit) in TypeScript code
Prefer unknown over any and refine the type in TypeScript
Type function parameters and return values explicitly in TypeScript, do not rely on implicit any or inference; exceptions are React components and trivial functions
Do not use as type assertions in TypeScript; the only exception is as const

All imports from recharts must use the public API entry point (e.g., import { TooltipIndex } from 'recharts'). Imports from internal paths like recharts/types/* or recharts/src/* are not allowed and will fail the linter.

Files:

  • src/cartesian/getCartesianPosition.tsx
  • test/cartesian/getCartesianPosition.spec.ts
  • src/component/Label.tsx
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Ensure code lints by running npm run lint and follows Airbnb's Style Guide

Files:

  • src/cartesian/getCartesianPosition.tsx
  • test/cartesian/getCartesianPosition.spec.ts
  • src/component/Label.tsx
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not hardcode any strings or formatting choices in library code; users should provide localized strings as desired

Files:

  • src/cartesian/getCartesianPosition.tsx
  • src/component/Label.tsx
test/**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Aim for 100% unit test code coverage when writing new code

Files:

  • test/cartesian/getCartesianPosition.spec.ts
test/**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (test/README.md)

test/**/*.{test,spec}.{ts,tsx}: Aim for 100% unit test code coverage when writing new code
Prefer to use the createSelectorTestCase helper function when writing or modifying tests
Use the expectLastCalledWith helper function instead of expect(spy).toHaveBeenLastCalledWith(...) for better typing and autocompletion
Verify the number of selector calls using the spy object from createSelectorTestCase to spot unnecessary re-renders and improve performance
Mock getBoundingClientRect in tests using the helper function provided in test/helper/MockGetBoundingClientRect.ts
Use vi.useFakeTimers() in all tests due to Redux autoBatchEnhancer dependency on timers and requestAnimationFrame
Call vi.runOnlyPendingTimers() to advance timers after renders when not using createSelectorTestCase helper, and avoid vi.runAllTimers() to prevent infinite loops
Use userEvent.setup({ advanceTimers: vi.runOnlyPendingTimers }) or the userEventSetup helper function from test/helper/userEventSetup.ts when creating userEvent instances
When testing tooltips on hover, use vi.runOnlyPendingTimers() after each userEvent.hover() call or use the showTooltip helper function from tooltipTestHelpers.ts to account for requestAnimationFrame delays

Files:

  • test/cartesian/getCartesianPosition.spec.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

When running unit tests, prefer to run a single test file using npm run test -- path/to/TestFile.spec.tsx rather than running all tests with npm test

Unit tests should be placed in the test directory, with some tests also allowed in www/test. Test files follow the naming convention *.spec.tsx.

Files:

  • test/cartesian/getCartesianPosition.spec.ts
🧠 Learnings (7)
📚 Learning: 2025-12-14T13:58:49.197Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6771
File: src/shape/Curve.tsx:39-40
Timestamp: 2025-12-14T13:58:49.197Z
Learning: In the recharts codebase, hooks like useAppSelector and other hooks (e.g., useChartLayout()) return undefined when used outside Redux Provider context, instead of throwing. This enables components that call these hooks, such as Curve, to operate in standalone mode by falling back to prop values. During code reviews, ensure TSX files gracefully handle undefined results from hooks and implement fallbacks (e.g., via default props or explicit prop-based values) rather than assuming the hook is always within Provider.

Applied to files:

  • src/cartesian/getCartesianPosition.tsx
  • src/component/Label.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Mock `getBoundingClientRect` in tests using the helper function provided in `test/helper/MockGetBoundingClientRect.ts`

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
📚 Learning: 2025-12-16T08:12:13.355Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6783
File: test/util/ChartUtils.spec.tsx:15-16
Timestamp: 2025-12-16T08:12:13.355Z
Learning: In the recharts codebase, files in the `test` folder are allowed to import from internal paths (e.g., `../../src/state/cartesianAxisSlice`) and do not need to use the public API entry point (`src/index.ts`). The public API import restriction applies only to non-test code.

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
  • scripts/snapshots/libFiles.txt
  • src/component/Label.tsx
📚 Learning: 2025-12-26T15:59:11.238Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.238Z
Learning: Applies to test-vr/**/*.spec.ts : Visual regression tests should follow the naming convention `*.spec.ts` and be placed in the `test-vr` directory. When updating snapshots, new files created in `test-vr/__snapshots__` should be committed to the repository.

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Verify the number of selector calls using the spy object from `createSelectorTestCase` to spot unnecessary re-renders and improve performance

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
📚 Learning: 2025-11-23T13:30:10.395Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6669
File: www/src/docs/exampleComponents/ScatterChart/ScatterChartWithLabels.tsx:2-2
Timestamp: 2025-11-23T13:30:10.395Z
Learning: The `TooltipIndex` type from recharts is defined in `src/state/tooltipSlice.ts` but is not currently exported from the public API entry points. It should not be imported from `recharts/types/state/tooltipSlice` as this is an internal implementation path. An ESLint rule is needed to prevent regressions.

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
📚 Learning: 2025-12-26T15:59:11.238Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.238Z
Learning: Applies to **/*.{ts,tsx} : All imports from `recharts` must use the public API entry point (e.g., `import { TooltipIndex } from 'recharts'`). Imports from internal paths like `recharts/types/*` or `recharts/src/*` are not allowed and will fail the linter.

Applied to files:

  • src/component/Label.tsx
🧬 Code graph analysis (3)
src/cartesian/getCartesianPosition.tsx (4)
src/util/types.ts (2)
  • TrapezoidViewBox (1024-1052)
  • CartesianViewBoxRequired (1010-1010)
src/component/Text.tsx (2)
  • TextAnchor (61-61)
  • TextVerticalAnchor (70-70)
src/context/chartLayoutContext.tsx (1)
  • cartesianViewBoxToTrapezoid (24-38)
src/util/DataUtils.ts (3)
  • isNumber (24-25)
  • isPercent (21-22)
  • getPercentValue (51-82)
test/cartesian/getCartesianPosition.spec.ts (2)
src/util/types.ts (2)
  • TrapezoidViewBox (1024-1052)
  • CartesianViewBoxRequired (1010-1010)
src/cartesian/getCartesianPosition.tsx (3)
  • GetCartesianPositionOptions (33-49)
  • getCartesianPosition (66-264)
  • CartesianPosition (51-58)
src/component/Label.tsx (4)
src/context/chartLayoutContext.tsx (1)
  • cartesianViewBoxToTrapezoid (24-38)
src/util/types.ts (3)
  • CartesianViewBoxRequired (1010-1010)
  • TrapezoidViewBox (1024-1052)
  • PolarViewBoxRequired (1022-1022)
src/util/DataUtils.ts (1)
  • isNumber (24-25)
src/cartesian/getCartesianPosition.tsx (1)
  • getCartesianPosition (66-264)
⏰ 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 (7)
scripts/snapshots/libFiles.txt (1)

30-30: LGTM!

The new lib/cartesian/getCartesianPosition.js entry is correctly placed in alphabetical order within the snapshot manifest.

test/cartesian/getCartesianPosition.spec.ts (1)

1-8: LGTM!

Test file structure is well-organized with clear test cases across multiple scenarios (rectangle, regular funnel, reversed funnel, negative dimensions, clamping). Imports from internal paths are correctly used per project conventions for test files.

src/cartesian/getCartesianPosition.tsx (2)

60-65: LGTM!

Well-documented function with clear JSDoc. The implementation correctly handles:

  • Trapezoid geometry calculations for funnel charts
  • Sign-based logic for negative dimensions
  • Clamping against parent view box
  • Multiple position variants with consistent anchor calculations

69-69: No issue here. The function cartesianViewBoxToTrapezoid has overloaded signatures: it returns undefined only when passed undefined, and returns TrapezoidViewBox when passed a required, non-undefined value. Since viewBox in GetCartesianPositionOptions is required (non-optional), TypeScript correctly resolves the return type to TrapezoidViewBox, making the destructuring on line 69 type-safe.

src/component/Label.tsx (3)

354-370: LGTM!

The polarViewBoxToTrapezoid helper cleanly converts polar viewBox to trapezoid format for unified positioning. The diameter-based bounding box calculation is correct for circular polar charts.


333-335: LGTM!

The isPolar type guard is correctly updated to handle undefined viewBox, improving type safety when determining which positioning logic to use.


463-470: LGTM!

Clean mapping from CartesianPosition to LabelPositionAttributes with proper handling of optional width and height properties.

Comment thread src/cartesian/getCartesianPosition.tsx
Comment thread src/component/Label.tsx
Comment on lines +455 to +461
const cartesianResult = getCartesianPosition({
viewBox: cartesianBox,
position,
offset: props.offset,
parentViewBox: isPolar(parentViewBox) ? undefined : parentViewBox,
clamp: true,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Type mismatch: parentViewBox may not satisfy CartesianViewBoxRequired.

getCartesianPosition expects parentViewBox?: CartesianViewBoxRequired (with all properties required), but parentViewBox from props has type ViewBox which includes CartesianViewBox (with optional properties). Passing a CartesianViewBox with undefined x, y, width, or height could cause runtime errors in the clamping logic.

Consider adding validation or type narrowing:

Suggested fix
+const isCartesianViewBoxRequired = (
+  box: ViewBox | undefined,
+): box is CartesianViewBoxRequired =>
+  box != null &&
+  !isPolar(box) &&
+  isNumber(box.x) &&
+  isNumber(box.y) &&
+  isNumber(box.width) &&
+  isNumber(box.height);

 const cartesianResult = getCartesianPosition({
   viewBox: cartesianBox,
   position,
   offset: props.offset,
-  parentViewBox: isPolar(parentViewBox) ? undefined : parentViewBox,
+  parentViewBox: isCartesianViewBoxRequired(parentViewBox) ? parentViewBox : undefined,
   clamp: true,
 });
🤖 Prompt for AI Agents
In src/component/Label.tsx around lines 455-461, the value passed as
parentViewBox may be a CartesianViewBox with optional x,y,width,height but
getCartesianPosition requires CartesianViewBoxRequired; validate/narrow the prop
before calling: if parentViewBox is polar keep undefined, otherwise check that
x, y, width and height are defined (or coerce defaults) and only pass a
fully-populated CartesianViewBoxRequired; if any required field is missing
either supply sensible defaults or bail out/skip clamping so you never pass an
object with undefined required fields to getCartesianPosition.

@codecov

codecov Bot commented Dec 27, 2025

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 7.55kB (0.27%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
recharts/bundle-cjs 1.2MB 3.07kB (0.26%) ⬆️
recharts/bundle-es6 1.04MB 2.95kB (0.28%) ⬆️
recharts/bundle-umd 529.33kB 1.53kB (0.29%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: recharts/bundle-cjs

Assets Changed:

Asset Name Size Change Total Size Change (%)
component/Label.js -4.89kB 15.75kB -23.71%
cartesian/getCartesianPosition.js (New) 7.97kB 7.97kB 100.0% 🚀
view changes for bundle: recharts/bundle-es6

Assets Changed:

Asset Name Size Change Total Size Change (%)
component/Label.js -4.76kB 14.02kB -25.37%
cartesian/getCartesianPosition.js (New) 7.72kB 7.72kB 100.0% 🚀
view changes for bundle: recharts/bundle-umd

Assets Changed:

Asset Name Size Change Total Size Change (%)
Recharts.js 1.53kB 529.33kB 0.29%

@github-actions

Copy link
Copy Markdown
Contributor

Staging Deployment Details

These deployments will remain available for 30 days.

To update snapshots: Comment /update-snapshots on this PR to automatically update the baseline screenshots.

@ckifer

ckifer commented Jan 2, 2026

Copy link
Copy Markdown
Member

ah RIP, conflicts :(

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/component/Label.tsx (1)

460-466: Type safety issue: parentViewBox may not satisfy CartesianViewBoxRequired.

The type mismatch flagged in the previous review remains unresolved. getCartesianPosition expects parentViewBox?: CartesianViewBoxRequired (all properties required), but parentViewBox from props has type ViewBox which includes CartesianViewBox with optional x, y, width, and height. The current code only filters out polar viewBoxes but doesn't validate that all required Cartesian properties are defined.

If a CartesianViewBox with undefined properties is passed, this could cause runtime NaN errors in the clamping logic (e.g., Math.max(y - parentViewBox.y, 0) when parentViewBox.y is undefined).

🔎 Proposed fix
+const isCartesianViewBoxRequired = (
+  box: ViewBox | undefined,
+): box is CartesianViewBoxRequired =>
+  box != null &&
+  !isPolar(box) &&
+  isNumber(box.x) &&
+  isNumber(box.y) &&
+  isNumber(box.width) &&
+  isNumber(box.height);
+
 const cartesianResult = getCartesianPosition({
   viewBox: cartesianBox,
   position,
   offset: props.offset,
-  parentViewBox: isPolar(parentViewBox) ? undefined : parentViewBox,
+  parentViewBox: isCartesianViewBoxRequired(parentViewBox) ? parentViewBox : undefined,
   clamp: true,
 });
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d3814d2 and 6d49545.

📒 Files selected for processing (8)
  • scripts/snapshots/es6Files.txt
  • scripts/snapshots/libFiles.txt
  • scripts/snapshots/typesFiles.txt
  • src/cartesian/getCartesianPosition.tsx
  • src/component/Label.tsx
  • src/context/chartLayoutContext.tsx
  • test/cartesian/getCartesianPosition.spec.ts
  • test/component/Label.getAttrsOfCartesianLabel.spec.ts
💤 Files with no reviewable changes (1)
  • test/component/Label.getAttrsOfCartesianLabel.spec.ts
✅ Files skipped from review due to trivial changes (1)
  • scripts/snapshots/es6Files.txt
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/cartesian/getCartesianPosition.tsx
  • scripts/snapshots/libFiles.txt
  • src/context/chartLayoutContext.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.{ts,tsx}: Never use any type (implicit or explicit) in TypeScript code
Prefer unknown over any and refine the type in TypeScript
Type function parameters and return values explicitly in TypeScript, do not rely on implicit any or inference; exceptions are React components and trivial functions
Do not use as type assertions in TypeScript; the only exception is as const

All imports from recharts must use the public API entry point (e.g., import { TooltipIndex } from 'recharts'). Imports from internal paths like recharts/types/* or recharts/src/* are not allowed and will fail the linter.

Files:

  • test/cartesian/getCartesianPosition.spec.ts
  • src/component/Label.tsx
test/**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Aim for 100% unit test code coverage when writing new code

Files:

  • test/cartesian/getCartesianPosition.spec.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Ensure code lints by running npm run lint and follows Airbnb's Style Guide

Files:

  • test/cartesian/getCartesianPosition.spec.ts
  • src/component/Label.tsx
test/**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (test/README.md)

test/**/*.{test,spec}.{ts,tsx}: Aim for 100% unit test code coverage when writing new code
Prefer to use the createSelectorTestCase helper function when writing or modifying tests
Use the expectLastCalledWith helper function instead of expect(spy).toHaveBeenLastCalledWith(...) for better typing and autocompletion
Verify the number of selector calls using the spy object from createSelectorTestCase to spot unnecessary re-renders and improve performance
Mock getBoundingClientRect in tests using the helper function provided in test/helper/MockGetBoundingClientRect.ts
Use vi.useFakeTimers() in all tests due to Redux autoBatchEnhancer dependency on timers and requestAnimationFrame
Call vi.runOnlyPendingTimers() to advance timers after renders when not using createSelectorTestCase helper, and avoid vi.runAllTimers() to prevent infinite loops
Use userEvent.setup({ advanceTimers: vi.runOnlyPendingTimers }) or the userEventSetup helper function from test/helper/userEventSetup.ts when creating userEvent instances
When testing tooltips on hover, use vi.runOnlyPendingTimers() after each userEvent.hover() call or use the showTooltip helper function from tooltipTestHelpers.ts to account for requestAnimationFrame delays

Files:

  • test/cartesian/getCartesianPosition.spec.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

When running unit tests, prefer to run a single test file using npm run test -- path/to/TestFile.spec.tsx rather than running all tests with npm test

Unit tests should be placed in the test directory, with some tests also allowed in www/test. Test files follow the naming convention *.spec.tsx.

Files:

  • test/cartesian/getCartesianPosition.spec.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not hardcode any strings or formatting choices in library code; users should provide localized strings as desired

Files:

  • src/component/Label.tsx
🧠 Learnings (7)
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Mock `getBoundingClientRect` in tests using the helper function provided in `test/helper/MockGetBoundingClientRect.ts`

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
📚 Learning: 2025-12-16T08:12:13.355Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6783
File: test/util/ChartUtils.spec.tsx:15-16
Timestamp: 2025-12-16T08:12:13.355Z
Learning: In the recharts codebase, files in the `test` folder are allowed to import from internal paths (e.g., `../../src/state/cartesianAxisSlice`) and do not need to use the public API entry point (`src/index.ts`). The public API import restriction applies only to non-test code.

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
  • scripts/snapshots/typesFiles.txt
  • src/component/Label.tsx
📚 Learning: 2025-12-26T15:59:11.254Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to test-vr/**/*.spec.ts : Visual regression tests should follow the naming convention `*.spec.ts` and be placed in the `test-vr` directory. When updating snapshots, new files created in `test-vr/__snapshots__` should be committed to the repository.

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Verify the number of selector calls using the spy object from `createSelectorTestCase` to spot unnecessary re-renders and improve performance

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
📚 Learning: 2025-11-23T13:30:10.395Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6669
File: www/src/docs/exampleComponents/ScatterChart/ScatterChartWithLabels.tsx:2-2
Timestamp: 2025-11-23T13:30:10.395Z
Learning: The `TooltipIndex` type from recharts is defined in `src/state/tooltipSlice.ts` but is not currently exported from the public API entry points. It should not be imported from `recharts/types/state/tooltipSlice` as this is an internal implementation path. An ESLint rule is needed to prevent regressions.

Applied to files:

  • test/cartesian/getCartesianPosition.spec.ts
📚 Learning: 2025-12-26T15:59:11.254Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to **/*.{ts,tsx} : All imports from `recharts` must use the public API entry point (e.g., `import { TooltipIndex } from 'recharts'`). Imports from internal paths like `recharts/types/*` or `recharts/src/*` are not allowed and will fail the linter.

Applied to files:

  • scripts/snapshots/typesFiles.txt
  • src/component/Label.tsx
📚 Learning: 2025-12-14T13:58:49.197Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6771
File: src/shape/Curve.tsx:39-40
Timestamp: 2025-12-14T13:58:49.197Z
Learning: In the recharts codebase, hooks like useAppSelector and other hooks (e.g., useChartLayout()) return undefined when used outside Redux Provider context, instead of throwing. This enables components that call these hooks, such as Curve, to operate in standalone mode by falling back to prop values. During code reviews, ensure TSX files gracefully handle undefined results from hooks and implement fallbacks (e.g., via default props or explicit prop-based values) rather than assuming the hook is always within Provider.

Applied to files:

  • src/component/Label.tsx
🧬 Code graph analysis (2)
test/cartesian/getCartesianPosition.spec.ts (2)
src/util/types.ts (2)
  • TrapezoidViewBox (1028-1056)
  • CartesianViewBoxRequired (1014-1014)
src/cartesian/getCartesianPosition.tsx (3)
  • GetCartesianPositionOptions (33-49)
  • getCartesianPosition (66-264)
  • CartesianPosition (51-58)
src/component/Label.tsx (4)
src/context/chartLayoutContext.tsx (1)
  • cartesianViewBoxToTrapezoid (24-38)
src/util/types.ts (3)
  • CartesianViewBoxRequired (1014-1014)
  • TrapezoidViewBox (1028-1056)
  • PolarViewBoxRequired (1026-1026)
src/util/DataUtils.ts (1)
  • isNumber (24-25)
src/cartesian/getCartesianPosition.tsx (1)
  • getCartesianPosition (66-264)
⏰ 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 (5)
scripts/snapshots/typesFiles.txt (1)

30-30: LGTM!

The new type declaration file is correctly added to the public types snapshot and properly sorted alphabetically within the cartesian section.

src/component/Label.tsx (3)

15-26: LGTM!

The import changes correctly reflect the refactoring: getPercentValue has been removed since it's now used internally by getCartesianPosition, and the new imports for CartesianLabelPosition and getCartesianPosition have been properly added.


359-375: LGTM!

The new polarViewBoxToTrapezoid helper correctly converts polar viewBoxes to trapezoid format by calculating the bounding rectangle. The logic properly handles the conversion: x = cx - outerRadius, y = cy - outerRadius, and sets all dimensions to diameter = outerRadius * 2.


468-475: LGTM!

The mapping from getCartesianPosition result to positionAttrs is well-structured. The conditional spreading of optional width and height properties correctly handles cases where clamping is enabled versus disabled.

test/cartesian/getCartesianPosition.spec.ts (1)

1-818: Add tests for all CartesianLabelPosition values to achieve 100% coverage.

The test suite covers 13 explicit position branches and object positions, but the CartesianLabelPosition type defines 22 possible values. The following 8 positions are missing test coverage: 'inside', 'outside', 'insideStart', 'insideEnd', 'end', 'centerTop', 'centerBottom', and 'middle'. These positions are not explicitly handled in the implementation and currently fall through to the default case (which returns center coordinates). Add test cases for each to document this behavior explicitly, or if these positions are not intended to be supported, remove them from the CartesianLabelPosition type definition.

⛔ Skipped due to learnings
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Aim for 100% unit test code coverage when writing new code
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to test/**/*.spec.{ts,tsx} : Aim for 100% unit test code coverage when writing new code

} from '../../src/cartesian/getCartesianPosition';
import { CartesianViewBoxRequired, TrapezoidViewBox } from '../../src/util/types';

describe('useCartesianPosition', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix describe block name to match function under test.

The describe block is named 'useCartesianPosition' but the function being tested is getCartesianPosition (not a hook). The name should match the function to avoid confusion.

🔎 Proposed fix
-describe('useCartesianPosition', () => {
+describe('getCartesianPosition', () => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
describe('useCartesianPosition', () => {
describe('getCartesianPosition', () => {
🤖 Prompt for AI Agents
In test/cartesian/getCartesianPosition.spec.ts around line 9, the describe block
is incorrectly named 'useCartesianPosition' while the test targets the
getCartesianPosition function; rename the describe string to
'getCartesianPosition' (or another exact name matching the exported function
under test) so the test suite accurately reflects the unit under test and avoid
implying it's a hook.

@github-actions

github-actions Bot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor

Staging Deployment Details

These deployments will remain available for 30 days.

To update snapshots: Comment /update-snapshots on this PR to automatically update the baseline screenshots.

@PavelVanecek
PavelVanecek merged commit 1ba4139 into main Jan 3, 2026
43 checks passed
@PavelVanecek
PavelVanecek deleted the cartesian-positioner branch January 3, 2026 12:27
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.

2 participants