Skip to content

fix(Pie): skip minAngle redistribution when no segment needs it#7097

Merged
PavelVanecek merged 2 commits intorecharts:mainfrom
Harikrushn9118:fix/pie-minangle-threshold
Mar 8, 2026
Merged

fix(Pie): skip minAngle redistribution when no segment needs it#7097
PavelVanecek merged 2 commits intorecharts:mainfrom
Harikrushn9118:fix/pie-minangle-threshold

Conversation

@Harikrushn9118
Copy link
Copy Markdown
Contributor

@Harikrushn9118 Harikrushn9118 commented Mar 5, 2026

Fixes #6814

What's the problem?

Right now minAngle always reserves angle space for every non-zero segment and redistributes proportionally — even when all segments are already above the threshold. So with data like [300, 30, 20, 10] and minAngle={9}, you get [279°, 36°, 27°, 18°] instead of the natural [300°, 30°, 20°, 10°].

As @gregalexsmith showed in the issue, the angles shift for no reason.

What does this fix do?

Before doing the redistribution, I check whether any non-zero segment's natural angle actually falls below minAngle. If none do, we skip the redistribution entirely (set effectiveMinAngle = 0).

Had to move the sum calculation up a few lines so it's available before we compute realTotalAngle — we need sum to figure out each segment's natural angle.

How it works

const needsMinAngleAdjustment =
  minAngle > 0 &&
  sum > 0 &&
  displayedData.some(entry => {
    const percent = val / sum;
    return val !== 0 && percent * absDeltaAngle < minAngle;
  });
const effectiveMinAngle = needsMinAngleAdjustment ? minAngle : 0;

When minAngle IS needed (some segment is too small), behavior is exactly the same as before.

Testing

  • All 112 existing Pie tests pass
  • Verified the math manually against the debug logs from the issue

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Summary by CodeRabbit

  • Bug Fixes

    • Pie chart now only applies minimum-angle adjustments when at least one segment would otherwise fall below the threshold, preventing unnecessary redistribution and preserving natural segment spacing.
  • Tests

    • Added a unit test verifying that when all segments exceed the minimum-angle threshold, their angles remain unchanged.

When all segments already have angles above the minAngle threshold,
the redistribution logic was still kicking in and shifting every
segment's angle unnecessarily.

Moved sum calculation before realTotalAngle so we can check each
segment's natural angle first. If none fall below minAngle, we
set effectiveMinAngle to 0 and skip the whole redistribution.

Fixes recharts#6814
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 478ea0a0-f9d7-46d2-804b-3c0df321e944

📥 Commits

Reviewing files that changed from the base of the PR and between e1b42af and 93d8105.

📒 Files selected for processing (1)
  • test/chart/PieChart.spec.tsx

Walkthrough

ComputePieSectors now only redistributes the minAngle budget when at least one non-zero segment would otherwise fall below the threshold by introducing needsMinAngleAdjustment and effectiveMinAngle, and uses effectiveMinAngle in subsequent angle and total-angle calculations.

Changes

Cohort / File(s) Summary
Pie component logic
src/polar/Pie.tsx
Added needsMinAngleAdjustment guard and effectiveMinAngle; use effectiveMinAngle when computing realTotalAngle and per-sector tempEndAngle so minAngle redistribution occurs only if needed. Comments and a guard expression were added.
Tests
test/chart/PieChart.spec.tsx
Added unit test "minAngle does not shift segments when all are already above the threshold" verifying no redistribution occurs for data where all natural angles exceed minAngle.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • PavelVanecek
  • ckifer
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: skipping minAngle redistribution when unnecessary.
Description check ✅ Passed The description covers all required sections: motivation, solution, how it works, testing, and type of change. All template sections are properly filled.
Linked Issues check ✅ Passed The code changes directly address issue #6814 by checking if any segment needs minAngle adjustment before applying redistribution, preventing unnecessary angle shifts.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the minAngle issue. The Pie component modification implements the conditional logic, and the test validates the expected behavior.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/polar/Pie.tsx (1)

755-770: Please add a regression test for paddingAngle + conditional minAngle behavior.

This change is important and subtle; add a focused case where percent * absDeltaAngle >= minAngle but percent * (absDeltaAngle - totalPaddingAngle) < minAngle to protect against future regressions.

As per coding guidelines "src/**/*.{ts,tsx}: Aim for 100% unit test code coverage when writing new code".

Also applies to: 795-795

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/polar/Pie.tsx` around lines 755 - 770, Add a regression unit test that
verifies paddingAngle + the conditional minAngle logic in Pie.tsx: create
displayedData with an entry whose percent satisfies percent * absDeltaAngle >=
minAngle but percent * (absDeltaAngle - totalPaddingAngle) < minAngle, then
assert that needsMinAngleAdjustment (the minAngle decision using displayedData,
getValueByDataKey, dataKey, absDeltaAngle, totalPaddingAngle) is true and that
effectiveMinAngle is applied only when appropriate so sectors layout uses the
adjusted realTotalAngle; place the test alongside other Pie tests to ensure this
edge case (paddingAngle reducing available angle below minAngle threshold)
cannot regress.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/polar/Pie.tsx`:
- Around line 759-766: The min-angle trigger uses percent * absDeltaAngle but
must use the angle budget after padding; inside the needsMinAngleAdjustment
predicate (the displayedData.some callback that calls getValueByDataKey with
dataKey), compute an effectiveAngle = Math.max(0, absDeltaAngle - (paddingAngle
|| 0) * displayedData.length) (or subtract per-sector padding if a different
convention is used) and replace percent * absDeltaAngle with percent *
effectiveAngle so the check accounts for paddingAngle when deciding
redistribution.

---

Nitpick comments:
In `@src/polar/Pie.tsx`:
- Around line 755-770: Add a regression unit test that verifies paddingAngle +
the conditional minAngle logic in Pie.tsx: create displayedData with an entry
whose percent satisfies percent * absDeltaAngle >= minAngle but percent *
(absDeltaAngle - totalPaddingAngle) < minAngle, then assert that
needsMinAngleAdjustment (the minAngle decision using displayedData,
getValueByDataKey, dataKey, absDeltaAngle, totalPaddingAngle) is true and that
effectiveMinAngle is applied only when appropriate so sectors layout uses the
adjusted realTotalAngle; place the test alongside other Pie tests to ensure this
edge case (paddingAngle reducing available angle below minAngle threshold)
cannot regress.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 01bc0a64-91c6-4170-8b51-a6269c925e8a

📥 Commits

Reviewing files that changed from the base of the PR and between 1c71ab6 and e1b42af.

📒 Files selected for processing (1)
  • src/polar/Pie.tsx

Comment on lines +759 to +766
const needsMinAngleAdjustment =
minAngle > 0 &&
sum > 0 &&
displayedData.some(entry => {
const val = getValueByDataKey(entry, dataKey, 0);
const percent = (isNumber(val) ? val : 0) / sum;
return val !== 0 && percent * absDeltaAngle < minAngle;
});
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 | 🟠 Major

Use post-padding natural angle in the minAngle trigger check.

On Line 764-Line 765, the check uses percent * absDeltaAngle, but actual sector allocation is based on angle budget after padding. With non-zero paddingAngle, this can incorrectly skip redistribution even when a sector ends up below minAngle.

Suggested fix
   const needsMinAngleAdjustment =
     minAngle > 0 &&
     sum > 0 &&
     displayedData.some(entry => {
       const val = getValueByDataKey(entry, dataKey, 0);
-      const percent = (isNumber(val) ? val : 0) / sum;
-      return val !== 0 && percent * absDeltaAngle < minAngle;
+      const numericVal = isNumber(val) ? val : 0;
+      const percent = numericVal / sum;
+      const naturalAngle = percent * (absDeltaAngle - totalPaddingAngle);
+      return numericVal !== 0 && naturalAngle < minAngle;
     });
📝 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
const needsMinAngleAdjustment =
minAngle > 0 &&
sum > 0 &&
displayedData.some(entry => {
const val = getValueByDataKey(entry, dataKey, 0);
const percent = (isNumber(val) ? val : 0) / sum;
return val !== 0 && percent * absDeltaAngle < minAngle;
});
const needsMinAngleAdjustment =
minAngle > 0 &&
sum > 0 &&
displayedData.some(entry => {
const val = getValueByDataKey(entry, dataKey, 0);
const numericVal = isNumber(val) ? val : 0;
const percent = numericVal / sum;
const naturalAngle = percent * (absDeltaAngle - totalPaddingAngle);
return numericVal !== 0 && naturalAngle < minAngle;
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/polar/Pie.tsx` around lines 759 - 766, The min-angle trigger uses percent
* absDeltaAngle but must use the angle budget after padding; inside the
needsMinAngleAdjustment predicate (the displayedData.some callback that calls
getValueByDataKey with dataKey), compute an effectiveAngle = Math.max(0,
absDeltaAngle - (paddingAngle || 0) * displayedData.length) (or subtract
per-sector padding if a different convention is used) and replace percent *
absDeltaAngle with percent * effectiveAngle so the check accounts for
paddingAngle when deciding redistribution.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.61%. Comparing base (1c71ab6) to head (93d8105).
⚠️ Report is 14 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7097      +/-   ##
==========================================
+ Coverage   89.58%   89.61%   +0.03%     
==========================================
  Files         535      534       -1     
  Lines       40188    40294     +106     
  Branches     5464     5490      +26     
==========================================
+ Hits        36001    36109     +108     
+ Misses       4178     4177       -1     
+ Partials        9        8       -1     

☔ 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.

@PavelVanecek
Copy link
Copy Markdown
Collaborator

We're going to need a test for this

…ve threshold

Covers the case from recharts#6814 where all segments naturally have angles
above minAngle, so redistribution should not happen.
@Harikrushn9118
Copy link
Copy Markdown
Contributor Author

Harikrushn9118 commented Mar 7, 2026

Done @PavelVanecek , I added a regression test in the latest commit.

@PavelVanecek PavelVanecek merged commit f67fbdd into recharts:main Mar 8, 2026
41 checks passed
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.

minAngle affects segments even if all are above threshold

2 participants