Improve tick values by snapping to nice numbers {1, 2, 2.5, 5}#7009
Improve tick values by snapping to nice numbers {1, 2, 2.5, 5}#7009PavelVanecek merged 6 commits intorecharts:mainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds an opt-in "nice ticks" stepping algorithm and plumbing: new Changes
Sequence Diagram(s)(Skipped — changes are internal algorithm plus prop plumbing; no multi-component sequential flow that benefits from a diagram.) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
43ebd4c to
b546890
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (14)
test/chart/BarChart.spec.tsx (1)
2487-2492:⚠️ Potential issue | 🔴 CriticalBug:
yattribute not updated to match the newdpath.The
dattribute starts at y=27.79andheightwas updated to11.21, butyon line 2492 still reads'24.9875'(the old value). This mismatch will cause the test assertion to fail.Proposed fix
d: 'M 12.2571,27.79 h 90 v 11.21 h -90 Z', height: '11.21', radius: '0', width: '90', x: '12.2571', - y: '24.9875', + y: '27.79',test/state/selectors/radarSelectors.spec.tsx (1)
407-455:⚠️ Potential issue | 🟡 MinorAdd fake timers setup for this suite.
This spec doesn’t enable
vi.useFakeTimers(), which the test guidelines require for consistent RAF/autoBatch behavior.As per coding guidelines, "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".test/state/selectors/scatterSelectors.spec.tsx (1)
371-416:⚠️ Potential issue | 🟡 MinorAdd fake timers setup for this selector test.
This spec doesn’t enable
vi.useFakeTimers(), which the test guidelines require for consistent RAF/autoBatch behavior.As per coding guidelines, "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".test/cartesian/Line.spec.tsx (1)
32-39:⚠️ Potential issue | 🟡 MinorAdd fake timers setup for this suite.
This spec doesn’t enable
vi.useFakeTimers(), which the test guidelines require for consistent RAF/autoBatch behavior.As per coding guidelines, "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".test/cartesian/ReferenceLine/ReferenceLine.spec.tsx (1)
293-299:⚠️ Potential issue | 🟡 MinorAdd fake timers setup for this suite.
This spec doesn’t enable
vi.useFakeTimers(), which the test guidelines require for consistent RAF/autoBatch behavior.As per coding guidelines, "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".test/polar/Radar.animation.spec.tsx (1)
203-211:⚠️ Potential issue | 🟡 MinorEnable fake timers for animation tests.
This spec doesn’t enable
vi.useFakeTimers(), which the test guidelines require for consistent RAF/autoBatch behavior.As per coding guidelines, "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".test/cartesian/Scatter.spec.tsx (1)
34-42:⚠️ Potential issue | 🔴 Critical
cyandtransform.ymismatch in first scatter point expectationThe first scatter point has
cy: '470.5'(line 37) buttransform: 'translate(54, 467.77777777777777)'(line 40). Since theSymbolscomponent renders both from the same coordinate value, they must match. All other scatter points in this expectation correctly have consistent values. Update the transform to'translate(54, 470.5)'to align with the cy value.test/chart/ScatterChart.spec.tsx (4)
874-882:⚠️ Potential issue | 🔴 CriticalBug:
cyvalue doesn't match thetransformy-coordinate.Line 877 sets
cy: '135'but line 880 still hastransform: 'translate(120, 125)'. The transform y=125doesn't matchcy='135'. Same mismatch pattern as the previous scatter point issue.🐛 Proposed fix — align cy and transform
- cy: '135', + cy: '125',or
- transform: 'translate(120, 125)', + transform: 'translate(120, 135)',
1253-1261:⚠️ Potential issue | 🔴 CriticalBug:
cxvalue doesn't match thetransformx-coordinate.Line 1255 sets
cx: '160'but line 1259 still hastransform: 'translate(186.66666666666669, 185)'. The transform x=186.66666666666669doesn't matchcx='160'.🐛 Proposed fix — align cx and transform
- cx: '160', + cx: '186.66666666666669',or
- transform: 'translate(186.66666666666669, 185)', + transform: 'translate(160, 185)',
796-803:⚠️ Potential issue | 🔴 CriticalBug: duplicate
index: 2— likely should remainindex: 3.Lines 798 and 799 both have
index: 2, creating the sequence0, 1, 2, 2, 4, 5, 6(missing index 3). Compare with the similar test at lines 937–943 which has sequential indices0, 1, 2, 3, 4. Line 799 was likely meant to keepindex: 3.🐛 Proposed fix
- { index: 2, coordinate: 85, value: 300, offset: 0 }, + { index: 3, coordinate: 85, value: 300, offset: 0 },
308-316:⚠️ Potential issue | 🔴 CriticalThree cx/cy–transform coordinate mismatches in test expectations.
The
expectScatterPointshelper compares SVG element attributes directly usingtoEqual(). In the current test expectations:
- Line 310:
cx: '91.5'buttransform: 'translate(109.16666666666666, 338)'— cx doesn't match the x in transform- Line 877:
cy: '135'buttransform: 'translate(120, 125)'— cy doesn't match the y in transform- Line 1255:
cx: '160'buttransform: 'translate(186.66666666666669, 185)'— cx doesn't match the x in transformIn all other scatter point expectations throughout the file, cx matches transform x and cy matches transform y. These three inconsistencies will cause test failures if the component renders the correct values.
Mismatched expectations requiring fixes
Fix by aligning cx/cy with their corresponding transform coordinates, or vice versa. Choose the value that matches what the component actually renders:
- Line 310–314: Align
cx: '91.5'with transform or update transform to'translate(91.5, 338)'- Line 877–880: Align
cy: '135'with transform or update transform to'translate(120, 135)'- Line 1255–1259: Align
cx: '160'with transform or update transform to'translate(160, 185)'test/cartesian/XAxis/XAxis.padding.spec.tsx (1)
665-691:⚠️ Potential issue | 🔴 CriticalFix non-monotonic tick sequence and remove duplicate test case.
The "Render Bars with padding on the right" test (lines 665-691) has incorrect tick expectations producing the sequence
110, 90, 90, 150, 170:
- Ticks are non-monotonic (110 → 90 is a decrease)
- Value
90appears twice at different positions- The first tick has
y: '253'while all others havey: '273', indicating a layout anomalyAll other padding tests with the same domain [90, 170] correctly produce
90, 110, 130, 150, 170with consistent y-positioning. Align this test to match the expected pattern.Additionally, lines 701–702 contain a duplicate test case: both specify
{ providedTickCount: 9, expectedTickCount: 9 }. Remove the redundant entry.test/polar/PolarGrid.spec.tsx (1)
854-861:⚠️ Potential issue | 🔴 CriticalFix invalid coordinate value with two decimal points in test expectation.
Line 858 contains
y2: '250.45894683899488.00000000000003'— a value with two decimal points that is mathematically invalid. In a polar grid, angle 0° and angle 360° represent the same direction and should produce identical line coordinates. The first grid line (angle 0°) correctly hasy2: '150', so the last grid line (angle 360°) should also havey2: '150'. The current value appears to be an accidental string concatenation.- y2: '250.45894683899488.00000000000003', + y2: '150',test/cartesian/YAxis/YAxis.ticks.spec.tsx (1)
249-271:⚠️ Potential issue | 🔴 CriticalVerify test expectations for domain [0, 200] with tickCount=4 and allowDecimals=false.
The test expectations appear to be incomplete or incorrect. Investigation reveals:
Algorithm mismatch: With domain [0, 200] fixed and tickCount=4,
getTickValuesFixedDomainuses step=100, which produces only 3 ticks:[0, 100, 200]. The test expects 4 ticks[0, 100, 140, 200], but the algorithm cannot generate this set.Duplicate coordinates in selector test: Lines 259-260 show both value 140 and value 200 mapped to coordinate 5, which is impossible—each value can only have one coordinate.
Linear scale verification failure: For scale domain [0, 200] → range [5, 265]:
- Value 100 should map to coordinate 135 (correct in selector; rendered shows 174)
- Value 140 should map to coordinate 83 (selector shows 5; rendered shows 135)
Non-uniform spacing: The niceTicks
[0, 100, 140, 200]have gaps of 100, 40, 60—unusual for a tick algorithm. ThegetTickValuesFixedDomainwith step=100 would naturally produce uniform spacing.These inconsistencies suggest the test expectations were not properly updated during the recent "improved nice tick values" commit (b546890), which acknowledged ~190 remaining manual test failures.
🤖 Fix all issues with AI agents
In `@test/cartesian/CartesianGrid.spec.tsx`:
- Line 264: Replace the typed last-call assertion on the scale spy by using the
testing helper expectLastCalledWith instead of
expect(scaleSpy).toHaveBeenLastCalledWith; update the assertion that currently
references scaleSpy to call expectLastCalledWith(scaleSpy, [0, 2000]) (or the
project’s helper signature) and ensure the test suite enables fake timers by
invoking vi.useFakeTimers() at the top of the describe block or beforeAll so
Redux autoBatchEnhancer and requestAnimationFrame are stubbed; locate usages of
scaleSpy and the test setup in CartesianGrid.spec.tsx to apply these changes.
In `@test/cartesian/ReferenceArea.spec.tsx`:
- Line 101: The test suite in ReferenceArea.spec.tsx is missing fake timers; add
vi.useFakeTimers() in the suite setup (e.g., in the top-level describe's
beforeAll or beforeEach) and restore with vi.useRealTimers() in
afterAll/afterEach to ensure consistent requestAnimationFrame/autoBatch behavior
(this will affect expectations like the assertion on the 'd' attribute for
area). Ensure you place these calls in the same test file's setup/teardown so
tests that reference the rendered area (the expect(area).toHaveAttribute(...)
assertion) run with fake timers enabled.
In `@test/cartesian/XAxis/XAxis.multiaxis.spec.tsx`:
- Around line 148-162: The test expectation for axis with xAxisId="d" contains
duplicate tick label '1500' at different x positions; update the first test's
expected ticks to match the valid sequence used in the second test ("should
render multiple axes with some ticks mirrored") so both axes produce identical
ticks. Specifically, replace the duplicated '1500' entries in the first test's
expected tick objects with '900' and '1350' (so the sequence becomes 0, 450,
900, 1350, 1800) and ensure the test comparing xAxisId="d" uses the same tick
values as the mirrored-axis test.
In `@test/state/selectors/axisSelectors.spec.tsx`:
- Around line 2173-2179: Add fake timers for this test suite: call
vi.useFakeTimers() in the test file's setup (e.g., in a top-level beforeAll or
beforeEach near the casesThatProduceNiceTicks definition) and restore real
timers in afterAll/afterEach with vi.useRealTimers(); this ensures consistent
RAF/autoBatch behavior required by Redux autoBatchEnhancer when running the
axisSelectors.spec.tsx tests.
In `@test/state/selectors/selectBarRectangles.stackOffset.spec.tsx`:
- Around line 265-282: The last three entries in expectedRectangles3 do not
match the corresponding entries in expectedBars (variables expectedBars and
expectedRectangles3 in
test/state/selectors/selectBarRectangles.stackOffset.spec.tsx) causing an
inconsistency between the selector-based expectations and the render-based
expectations; run the renderTestCase() used by both tests to get the
authoritative rectangle values, compare those outputs to both expectedBars and
expectedRectangles3, and then update the stale set (most likely
expectedRectangles3) so both tests assert the same numeric values for the three
blue bars (heights, widths, x, y) or adjust the selector logic if the selector
is producing incorrect values. Ensure after changing that both the DOM-render
test and the selector test pass.
🧹 Nitpick comments (1)
test/cartesian/XAxis/XAxis.padding.spec.tsx (1)
701-705: Duplicate test case entries.Lines 701 and 702 are identical:
{ providedTickCount: 9, expectedTickCount: 9 }. This runs the same test twice with no additional coverage.♻️ Suggested fix — deduplicate and restore coverage for distinct tick counts
- { providedTickCount: 9, expectedTickCount: 9 }, - { providedTickCount: 9, expectedTickCount: 9 }, + { providedTickCount: 9, expectedTickCount: 9 }, + { providedTickCount: 11, expectedTickCount: 11 },or, if the old entries
11→11and13→13were intentionally replaced, keep distinct inputs:- { providedTickCount: 9, expectedTickCount: 9 }, - { providedTickCount: 9, expectedTickCount: 9 }, + { providedTickCount: 9, expectedTickCount: 9 }, + { providedTickCount: 13, expectedTickCount: 13 },
| ); | ||
|
|
||
| expect(scaleSpy).toHaveBeenLastCalledWith([0, 1200]); | ||
| expect(scaleSpy).toHaveBeenLastCalledWith([0, 2000]); |
There was a problem hiding this comment.
Use expectLastCalledWith for the scale spy (and enable fake timers).
Guidelines prefer expectLastCalledWith for typed last-call assertions. Also ensure this suite enables vi.useFakeTimers() per the testing guidelines.
🛠️ Suggested change
- expect(scaleSpy).toHaveBeenLastCalledWith([0, 2000]);
+ expectLastCalledWith(scaleSpy, [0, 2000]);As per coding guidelines, "Use the expectLastCalledWith helper function instead of expect(spy).toHaveBeenLastCalledWith(...) for better typing and autocompletion" and "Use vi.useFakeTimers() in all tests due to Redux autoBatchEnhancer dependency on timers and requestAnimationFrame".
📝 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.
| expect(scaleSpy).toHaveBeenLastCalledWith([0, 2000]); | |
| expectLastCalledWith(scaleSpy, [0, 2000]); |
🤖 Prompt for AI Agents
In `@test/cartesian/CartesianGrid.spec.tsx` at line 264, Replace the typed
last-call assertion on the scale spy by using the testing helper
expectLastCalledWith instead of expect(scaleSpy).toHaveBeenLastCalledWith;
update the assertion that currently references scaleSpy to call
expectLastCalledWith(scaleSpy, [0, 2000]) (or the project’s helper signature)
and ensure the test suite enables fake timers by invoking vi.useFakeTimers() at
the top of the describe block or beforeAll so Redux autoBatchEnhancer and
requestAnimationFrame are stubbed; locate usages of scaleSpy and the test setup
in CartesianGrid.spec.tsx to apply these changes.
| expect(allAreas).toHaveLength(1); | ||
| const area = allAreas[0]; | ||
| expect(area).toHaveAttribute('d', 'M 20,109.4444 h 960 v 25.5556 h -960 Z'); | ||
| expect(area).toHaveAttribute('d', 'M 20,104.3333 h 960 v 30.6667 h -960 Z'); |
There was a problem hiding this comment.
Add fake timers setup for this suite.
This spec doesn’t enable vi.useFakeTimers(), which the test guidelines require for consistent RAF/autoBatch behavior.
As per coding guidelines, "Use vi.useFakeTimers() in all tests due to Redux autoBatchEnhancer dependency on timers and requestAnimationFrame".
🤖 Prompt for AI Agents
In `@test/cartesian/ReferenceArea.spec.tsx` at line 101, The test suite in
ReferenceArea.spec.tsx is missing fake timers; add vi.useFakeTimers() in the
suite setup (e.g., in the top-level describe's beforeAll or beforeEach) and
restore with vi.useRealTimers() in afterAll/afterEach to ensure consistent
requestAnimationFrame/autoBatch behavior (this will affect expectations like the
assertion on the 'd' attribute for area). Ensure you place these calls in the
same test file's setup/teardown so tests that reference the rendered area (the
expect(area).toHaveAttribute(...) assertion) run with fake timers enabled.
| { | ||
| textContent: '900', | ||
| textContent: '1500', | ||
| x: '350', | ||
| y: '67', | ||
| }, | ||
| { | ||
| textContent: '1350', | ||
| textContent: '1500', | ||
| x: '522.5', | ||
| y: '67', | ||
| }, | ||
| { | ||
| textContent: '1800', | ||
| textContent: '2000', | ||
| x: '695', | ||
| y: '67', | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's look at the test file structure around lines 148-162 and 190-326
cat -n test/cartesian/XAxis/XAxis.multiaxis.spec.tsx | sed -n '140,170p'Repository: recharts/recharts
Length of output: 832
🏁 Script executed:
# Also check the second test around lines 190-326
cat -n test/cartesian/XAxis/XAxis.multiaxis.spec.tsx | sed -n '180,220p'Repository: recharts/recharts
Length of output: 1512
🏁 Script executed:
# Look for pageData import
rg -n "pageData" test/cartesian/XAxis/XAxis.multiaxis.spec.tsx -B 2 -A 2Repository: recharts/recharts
Length of output: 912
🏁 Script executed:
# Find where pageData is defined
fd -g "*.ts" -g "*.tsx" | xargs grep -l "export.*pageData" | head -5Repository: recharts/recharts
Length of output: 153
🏁 Script executed:
# Find pageData definition
fd pageData storybook/stories/data/ -type fRepository: recharts/recharts
Length of output: 231
🏁 Script executed:
# Check the second test's expectations for axis d ticks (lines 190-326)
cat -n test/cartesian/XAxis/XAxis.multiaxis.spec.tsx | sed -n '290,330p'Repository: recharts/recharts
Length of output: 927
🏁 Script executed:
# Get the full second test to understand if axes are identical
cat -n test/cartesian/XAxis/XAxis.multiaxis.spec.tsx | sed -n '190,210p'Repository: recharts/recharts
Length of output: 1021
🏁 Script executed:
# Find and display pageData definition
find storybook -name "*data*" -type f | head -10Repository: recharts/recharts
Length of output: 43
🏁 Script executed:
# Check common data file locations
fd -e ts -e tsx . storybook/stories/data/Repository: recharts/recharts
Length of output: 596
🏁 Script executed:
# Search for pageData export
rg -n "export.*pageData" storybook/Repository: recharts/recharts
Length of output: 566
🏁 Script executed:
# Read Page.ts to find pageData definition
cat -n storybook/stories/data/Page.ts | head -120Repository: recharts/recharts
Length of output: 2788
🏁 Script executed:
# Let's verify if this test file was recently modified and what the git history shows
cd test/cartesian/XAxis && git log --oneline XAxis.multiaxis.spec.tsx | head -10Repository: recharts/recharts
Length of output: 123
🏁 Script executed:
# Check if there's any comment or explanation in the test about why these specific values were chosen
cat -n test/cartesian/XAxis/XAxis.multiaxis.spec.tsx | sed -n '1,50p'Repository: recharts/recharts
Length of output: 2601
🏁 Script executed:
# Check what changed in the commit "Update test expectations for improved nice tick values"
git show b546890 --statRepository: recharts/recharts
Length of output: 50374
🏁 Script executed:
# See the actual diff for this file in that commit
git show b546890 -- test/cartesian/XAxis/XAxis.multiaxis.spec.tsx | head -150Repository: recharts/recharts
Length of output: 4610
🏁 Script executed:
# Let's check the specific lines in the diff for axis d ticks
git show b546890 -- test/cartesian/XAxis/XAxis.multiaxis.spec.tsx | grep -A 300 "XAxis dataKey=\"amt\"" | head -200Repository: recharts/recharts
Length of output: 4311
🏁 Script executed:
# Let's verify the second test's axis d expectations to see if it truly shows 0, 450, 900, 1350, 1800
git show b546890 -- test/cartesian/XAxis/XAxis.multiaxis.spec.tsx | grep -A 350 "should render multiple axes with some ticks mirrored" | grep -A 120 "y: '53'"Repository: recharts/recharts
Length of output: 455
Fix duplicate tick value '1500' and inconsistency between tests.
Lines 149 and 154 both specify textContent: '1500' at different x positions (350 and 522.5). A number axis cannot generate duplicate tick values at different positions—this is a data integrity error in the test expectations.
Additionally, the second test should render multiple axes with some ticks mirrored (lines 190–328) uses the same data and axis configuration for xAxisId="d" (except for the mirror attribute), yet expects different ticks: 0, 450, 900, 1350, 1800 instead of the duplicate-containing 0, 450, 1500, 1500, 2000. The mirror attribute only affects label orientation, not tick generation. Both axes should produce identical tick values.
Correct the first test's axis d tick expectations to match the second test's valid sequence, or verify if a different domain/configuration is intended.
🤖 Prompt for AI Agents
In `@test/cartesian/XAxis/XAxis.multiaxis.spec.tsx` around lines 148 - 162, The
test expectation for axis with xAxisId="d" contains duplicate tick label '1500'
at different x positions; update the first test's expected ticks to match the
valid sequence used in the second test ("should render multiple axes with some
ticks mirrored") so both axes produce identical ticks. Specifically, replace the
duplicated '1500' entries in the first test's expected tick objects with '900'
and '1350' (so the sequence becomes 0, 450, 900, 1350, 1800) and ensure the test
comparing xAxisId="d" uses the same tick values as the mirrored-axis test.
| const casesThatProduceNiceTicks: ReadonlyArray<{ domain: AxisDomain; expectedTicks: ReadonlyArray<number> }> = [ | ||
| // @ts-expect-error typescript is correct here, but we are testing runtime behavior with invalid input | ||
| { domain: undefined, expectedTicks: [0, 100, 200, 300, 400] }, | ||
| { domain: ['auto', 'auto'], expectedTicks: [180, 240, 300, 360, 420] }, | ||
| { domain: ['auto', 'auto'], expectedTicks: [100, 200, 300, 400, 500] }, | ||
| { domain: [-500, 'auto'], expectedTicks: [-500, -250, 0, 250, 500] }, | ||
| { domain: ['auto', 3000], expectedTicks: [0, 750, 1500, 2250, 3000] }, | ||
| { domain: ['auto', 3000], expectedTicks: [0, 1000, 2000, 2250, 3000] }, | ||
| ]; |
There was a problem hiding this comment.
Add fake timers setup for this suite.
This spec doesn’t enable vi.useFakeTimers(), which the test guidelines require for consistent RAF/autoBatch behavior.
As per coding guidelines, "Use vi.useFakeTimers() in all tests due to Redux autoBatchEnhancer dependency on timers and requestAnimationFrame".
🤖 Prompt for AI Agents
In `@test/state/selectors/axisSelectors.spec.tsx` around lines 2173 - 2179, Add
fake timers for this test suite: call vi.useFakeTimers() in the test file's
setup (e.g., in a top-level beforeAll or beforeEach near the
casesThatProduceNiceTicks definition) and restore real timers in
afterAll/afterEach with vi.useRealTimers(); this ensures consistent
RAF/autoBatch behavior required by Redux autoBatchEnhancer when running the
axisSelectors.spec.tsx tests.
b546890 to
c586d69
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/cartesian/YAxis/YAxis.spec.tsx (1)
85-113: Tick range seems quite loose for the "Area with range" case.For a data domain of
[-3, 16](range of 19), the new nice-number algorithm produces ticks[-10, 0, 10, 20, 30](range of 40) — more than 2× the actual data spread. While this is technically valid "nice numbers" behavior, it may result in the chart data being compressed into a small portion of the visible axis. Worth confirming this is acceptable UX for range-type data with small domains.
|
The new ticks look much better (judging from the unit tests alone). I wonder how many people are going to be mad that we're changing their charts. @MaxGhenis is there a way to opt-in to the previous algorithm for people who want to keep it that way? Or perhaps even should we keep the old behaviour the default, leave the new as opt-in and then swap them in the next major version? |
|
Great point on backward compatibility. I'll make the new algorithm opt-in for now — users can enable it via a prop, and we can swap the default in the next major version. Will update the PR. |
Instead of replacing the default tick step algorithm, keep the original
getFormatStep as the default and add the new nice number algorithm
(getFormatStepNice) as an opt-in feature. Users can enable it by passing
useNiceTicks={true} on XAxis, YAxis, PolarAngleAxis, or PolarRadiusAxis.
The new algorithm snaps to {1, 2, 2.5, 5} at each order of magnitude,
producing human-friendly intervals like 0, 5, 10, 15, 20 instead of
0, 4, 8, 12, 16. This can be made the default in the next major version.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
c586d69 to
8565e20
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
test/cartesian/XAxis/XAxis.vertical.spec.tsx (1)
198-228:⚠️ Potential issue | 🟡 MinorUse
expectLastCalledWithfor last-call assertions.Please replace the last-call assertion in this block (and keep the file consistent) with the helper to match the test guidelines.
♻️ Suggested update
-import { describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, vi } from 'vitest'; +import { expectLastCalledWith } from '../../helper/expectLastCalledWith'; ... - expect(axisSettingsSpy).toHaveBeenLastCalledWith(expectedSettings); + expectLastCalledWith(axisSettingsSpy, expectedSettings);As per coding guidelines: Use the
expectLastCalledWithhelper function instead ofexpect(spy).toHaveBeenLastCalledWith(...)for better typing and autocompletion.src/util/scale/getNiceTickValues.ts (2)
152-169:⚠️ Potential issue | 🟡 MinorUpdate calculateStep JSDoc for the new
stepFnparameter.The signature now accepts
stepFn, but the JSDoc doesn’t document it. Please add it so omnidoc stays correct.📚 Suggested doc update
- * `@param` correctionFactor A correction factor + * `@param` correctionFactor A correction factor + * `@param` stepFn Function to compute the step sizeAs per coding guidelines: JSDoc comments and TypeScript definitions in source files must be kept up-to-date as they are used to autogenerate API documentation via 'npm run omnidoc'.
220-276:⚠️ Potential issue | 🟡 MinorDocument the new
useNiceTicksparameter.Both tick helpers now accept
useNiceTicks, but it’s missing from their JSDoc blocks. Please add it for accurate API docs.📚 Suggested doc update
* `@param` tickCount The count of ticks * `@param` allowDecimals Allow the ticks to be decimals or not + * `@param` useNiceTicks When true, snap steps to nice numbers * `@return` array of ticks* `@param` tickCount The count of ticks. This function may return less than tickCount ticks if the interval is too small. * `@param` allowDecimals Allow the ticks to be decimals or not + * `@param` useNiceTicks When true, snap steps to nice numbers * `@return` array of ticksAs per coding guidelines: JSDoc comments and TypeScript definitions in source files must be kept up-to-date as they are used to autogenerate API documentation via 'npm run omnidoc'.
test/util/scale/getNiceTickValues.spec.ts (1)
1-11:⚠️ Potential issue | 🟡 MinorInitialize fake timers for this spec.
This file doesn’t call
vi.useFakeTimers(), which is required for tests in this repo.⏱️ Suggested update
-import { describe } from 'vitest'; +import { afterEach, beforeEach, describe, vi } from 'vitest'; ... +beforeEach(() => { + vi.useFakeTimers(); +}); + +afterEach(() => { + vi.useRealTimers(); +});As per coding guidelines: Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame.test/chart/RadarChart.spec.tsx (1)
156-173:⚠️ Potential issue | 🟡 MinorSwitch to
expectLastCalledWithfor last-call assertionsThese assertions still use
toHaveBeenLastCalledWith; please use the helper for consistency and better typings.Suggested update
- expect(angleAxisSettingsSpy).toHaveBeenLastCalledWith({ + expectLastCalledWith(angleAxisSettingsSpy, { allowDataOverflow: false, allowDecimals: false, allowDuplicatedCategory: false, dataKey: undefined, domain: undefined, id: 0, includeHidden: false, name: undefined, reversed: false, useNiceTicks: false, scale: 'auto', tick: true, tickCount: undefined, ticks: undefined, type: 'category', unit: undefined, - }); + });- expect(angleAxisSettingsSpy).toHaveBeenLastCalledWith({ + expectLastCalledWith(angleAxisSettingsSpy, { allowDataOverflow: false, allowDecimals: false, allowDuplicatedCategory: false, dataKey: undefined, domain: undefined, id: 0, includeHidden: false, name: undefined, reversed: false, useNiceTicks: false, scale: 'auto', tick: true, tickCount: undefined, ticks: undefined, type: 'category', unit: undefined, - }); + });As per coding guidelines, "Use the
expectLastCalledWithhelper function instead ofexpect(spy).toHaveBeenLastCalledWith(...)for better typing and autocompletion".Also applies to: 206-223
test/state/selectors/axisSelectors.spec.tsx (1)
2286-2316:⚠️ Potential issue | 🟡 MinorUse
expectLastCalledWithfor last-call assertionsThis block still uses
toHaveBeenLastCalledWith. Please switch to the helper.Suggested update
- expect(xAxisSpy).toHaveBeenLastCalledWith({ + expectLastCalledWith(xAxisSpy, { allowDataOverflow: false, allowDecimals: true, allowDuplicatedCategory: true, angle: 0, dataKey: undefined, domain: undefined, height: 30, hide: true, id: 0, includeHidden: false, interval: 'preserveEnd', minTickGap: 5, mirror: false, name: undefined, orientation: 'bottom', padding: { left: 0, right: 0, }, reversed: false, useNiceTicks: false, scale: expect.toBeRechartsScale({ domain: [0, 1, 2, 3, 4, 5], range: [5, 95] }), tick: true, tickCount: 5, tickFormatter: undefined, ticks: undefined, type: 'category', unit: undefined, - }); - expect(yAxisSpy).toHaveBeenLastCalledWith(undefined); + }); + expectLastCalledWith(yAxisSpy, undefined);As per coding guidelines, "Use the
expectLastCalledWithhelper function instead ofexpect(spy).toHaveBeenLastCalledWith(...)for better typing and autocompletion".
|
Updated — the new algorithm is now opt-in via a |
|
@MaxGhenis useNiceTicks sounds like a hook. Can you just make it niceTicks? |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Done — renamed |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (9)
test/polar/PolarRadiusAxis.spec.tsx (2)
1189-1207:⚠️ Potential issue | 🟡 MinorUse
expectLastCalledWithfor the state integration assertion.The expected axis settings check should use the helper for typing consistency.
Suggested fix
- expect(radiusAxisSpy).toHaveBeenLastCalledWith(expectedAxis); + expectLastCalledWith(radiusAxisSpy, expectedAxis);As per coding guidelines "Use the
expectLastCalledWithhelper function instead ofexpect(spy).toHaveBeenLastCalledWith(...)for better typing and autocompletion".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/polar/PolarRadiusAxis.spec.tsx` around lines 1189 - 1207, Replace the direct Jest assertion that uses toHaveBeenLastCalledWith with the typed helper expectLastCalledWith: update the test assertion that currently calls expect(radiusAxisSpy).toHaveBeenLastCalledWith(expectedAxis) to use expectLastCalledWith(radiusAxisSpy, expectedAxis) so typing and autocompletion are preserved; this change should be made where radiusAxisSpy and expectedAxis are referenced in PolarRadiusAxis.spec.tsx and ensure the expectLastCalledWith helper is imported/available in the test file.
1-4:⚠️ Potential issue | 🟡 MinorAdd fake timers for this test file.
The suite runs React tests without enabling fake timers, which is required by repo guidelines.
Suggested fix
-import { describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; ... describe('<PolarRadiusAxis />', () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + afterEach(() => { + vi.useRealTimers(); + });As per coding guidelines "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/polar/PolarRadiusAxis.spec.tsx` around lines 1 - 4, The test suite in PolarRadiusAxis.spec.tsx must enable fake timers; call vi.useFakeTimers() before the tests run (e.g., in a top-level beforeAll or immediately after imports) and restore timers with vi.useRealTimers() in afterAll to satisfy the repo guideline about Redux autoBatchEnhancer and requestAnimationFrame; update the file where describe/it/vi are used to ensure vi.useFakeTimers() is active for the suite and vi.useRealTimers() is called in teardown.test/polar/PolarAngleAxis/PolarAngleAxis.spec.tsx (2)
858-878:⚠️ Potential issue | 🟡 MinorUse
expectLastCalledWithfor the spy assertions here.Line 858 and Line 877 use
toHaveBeenLastCalledWith, which the test guidelines discourage.Suggested fix
- expect(angleAxisSettingsSpy).toHaveBeenLastCalledWith({ + expectLastCalledWith(angleAxisSettingsSpy, { allowDataOverflow: false, allowDecimals: false, allowDuplicatedCategory: false, dataKey: 'angle', domain: [0, 360], id: 0, includeHidden: false, name: undefined, reversed: false, niceTicks: false, scale: 'auto', tick: true, tickCount: 9, ticks: undefined, type: 'number', unit: undefined, - }); + }); - expect(niceTicksSpy).toHaveBeenLastCalledWith([0, 45, 90, 135, 180, 225, 270, 315, 360]); + expectLastCalledWith(niceTicksSpy, [0, 45, 90, 135, 180, 225, 270, 315, 360]);As per coding guidelines "Use the
expectLastCalledWithhelper function instead ofexpect(spy).toHaveBeenLastCalledWith(...)for better typing and autocompletion".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/polar/PolarAngleAxis/PolarAngleAxis.spec.tsx` around lines 858 - 878, Replace the two assertions that call toHaveBeenLastCalledWith on the spies with the project's expectLastCalledWith helper: locate the assertions against angleAxisSettingsSpy and niceTicksSpy in PolarAngleAxis.spec.tsx and change them to use expectLastCalledWith(angleAxisSettingsSpy, { ...expected settings... }) and expectLastCalledWith(niceTicksSpy, [0,45,90,135,180,225,270,315,360]) respectively so the tests follow the guideline and gain the improved typing/autocomplete behavior.
117-120:⚠️ Potential issue | 🟡 MinorAdd fake timers for this test file.
The current suite doesn’t enable fake timers, which is required here.
Suggested fix
-import { describe, expect, it, Mock, test, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, Mock, test, vi } from 'vitest'; ... describe('<PolarAngleAxis />', () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + afterEach(() => { + vi.useRealTimers(); + });As per coding guidelines "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/polar/PolarAngleAxis/PolarAngleAxis.spec.tsx` around lines 117 - 120, The test suite in PolarAngleAxis.spec.tsx needs fake timers enabled; add a vi.useFakeTimers() call at the start of the suite (e.g., inside the outer describe('<PolarAngleAxis />') or a beforeAll block) and pair it with vi.useRealTimers() in an afterAll/afterEach cleanup to avoid leaking timers; update the file where createSelectorTestCase/renderTestCase are defined so the fake timers are active for tests that depend on requestAnimationFrame/Redux autoBatchEnhancer.test/component/Tooltip/Tooltip.payload.spec.tsx (1)
443-446:⚠️ Potential issue | 🟡 MinorAdd fake timers to the shared test setup.
This file’s tests should enable fake timers per repository guidelines.
Suggested fix
-import { beforeEach, describe, expect, it } from 'vitest'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; ... beforeEach(() => { + vi.useFakeTimers(); mockGetBoundingClientRect({ width: 100, height: 100 }); });As per coding guidelines "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/component/Tooltip/Tooltip.payload.spec.tsx` around lines 443 - 446, Add fake timers to the test suite by invoking vi.useFakeTimers() in the shared setup and cleaning up with vi.useRealTimers() afterwards; update the describe('Tooltip payload') setup by adding vi.useFakeTimers() inside the beforeEach handler (where mockGetBoundingClientRect is called) and add an afterEach that calls vi.useRealTimers() to restore real timers so tests using requestAnimationFrame/Redux autoBatchEnhancer behave deterministically.src/util/scale/getNiceTickValues.ts (1)
152-170:⚠️ Potential issue | 🟡 MinorUpdate JSDoc to cover the new parameters.
stepFnandniceTickswere added but are missing from the function docs.Suggested fix
/** * Calculate the step * * `@param` min The minimum value of an interval * `@param` max The maximum value of an interval * `@param` tickCount The count of ticks * `@param` allowDecimals Allow the ticks to be decimals or not * `@param` correctionFactor A correction factor + * `@param` stepFn Step function used to round the rough step * `@return` The step, minimum value of ticks, maximum value of ticks *//** * Calculate the ticks of an interval. Ticks can appear outside the interval * if it makes them more rounded and nice. * * `@param` tuple of [min,max] min: The minimum value, max: The maximum value * `@param` tickCount The count of ticks * `@param` allowDecimals Allow the ticks to be decimals or not + * `@param` niceTicks When true, use nice-number step snapping * `@return` array of ticks *//** * Calculate the ticks of an interval. * Ticks will be constrained to the interval [min, max] even if it makes them less rounded and nice. * * `@param` tuple of [min,max] min: The minimum value, max: The maximum value * `@param` tickCount The count of ticks. This function may return less than tickCount ticks if the interval is too small. * `@param` allowDecimals Allow the ticks to be decimals or not + * `@param` niceTicks When true, use nice-number step snapping * `@return` array of ticks */As per coding guidelines "JSDoc comments and TypeScript definitions in source files must be kept up-to-date as they are used to autogenerate API documentation via 'npm run omnidoc'".
Also applies to: 220-276
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/util/scale/getNiceTickValues.ts` around lines 152 - 170, The JSDoc for calculateStep is out of date: add entries for the new parameters stepFn (StepFunction used to compute/formats steps) and niceTicks (boolean controlling whether tick extents are adjusted to "nice" values) and update the `@return/description` if the returned shape changed; locate the calculateStep function and its signature with parameters min, max, tickCount, allowDecimals, correctionFactor, stepFn and any use of niceTicks, then add clear JSDoc `@param` lines for stepFn and niceTicks (briefly describing purpose and types) and ensure the `@return` block matches the actual returned object shape.test/cartesian/XAxis/XAxis.vertical.spec.tsx (2)
198-230:⚠️ Potential issue | 🟡 MinorUse
expectLastCalledWithfor the axis settings assertion.Line 228 still uses
toHaveBeenLastCalledWith, which the test guidelines discourage for typing reasons.Suggested fix
import { ExpectAxisDomain, expectXAxisTicks } from '../../helper/expectAxisTicks'; +import { expectLastCalledWith } from '../../helper/expectLastCalledWith'; ... - expect(axisSettingsSpy).toHaveBeenLastCalledWith(expectedSettings); + expectLastCalledWith(axisSettingsSpy, expectedSettings);As per coding guidelines "Use the
expectLastCalledWithhelper function instead ofexpect(spy).toHaveBeenLastCalledWith(...)for better typing and autocompletion".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/cartesian/XAxis/XAxis.vertical.spec.tsx` around lines 198 - 230, Replace the typed assertion that uses Jest's toHaveBeenLastCalledWith with the project helper expectLastCalledWith: change the call that currently reads expect(axisSettingsSpy).toHaveBeenLastCalledWith(expectedSettings) to use expectLastCalledWith(axisSettingsSpy, expectedSettings). Keep the remaining assertions for itemDataSpy unchanged; if the test helper expectLastCalledWith is not already imported in the test file, add the import so the helper is available.
16-27:⚠️ Potential issue | 🟡 MinorAdd fake timers to the test setup.
This file runs React tests but does not enable fake timers, which is required in this repo’s test guidelines.
Suggested fix
-import { describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; ... describe('<XAxis />', () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + afterEach(() => { + vi.useRealTimers(); + });As per coding guidelines "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/cartesian/XAxis/XAxis.vertical.spec.tsx` around lines 16 - 27, The test suite for XAxis (describe('<XAxis />') / inner describe('layout=vertical')) lacks fake timers; add vi.useFakeTimers() at the start of the test setup (e.g., in a beforeAll or beforeEach inside the describe('<XAxis />') block) and restore real timers after tests with vi.useRealTimers() in afterAll/afterEach to satisfy the repo guideline about Redux autoBatchEnhancer and requestAnimationFrame; update the test file XAxis.vertical.spec.tsx by locating the top-level describe('<XAxis />') and adding these setup/teardown calls.test/util/scale/getNiceTickValues.spec.ts (1)
1-3:⚠️ Potential issue | 🟡 MinorAdd fake timers for this test suite.
The repo’s test guidelines require fake timers for all tests.
Suggested fix
-import { describe } from 'vitest'; +import { afterEach, beforeEach, describe, vi } from 'vitest'; ... +beforeEach(() => { + vi.useFakeTimers(); +}); + +afterEach(() => { + vi.useRealTimers(); +});As per coding guidelines "Use
vi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/util/scale/getNiceTickValues.spec.ts` around lines 1 - 3, The test suite in getNiceTickValues.spec.ts must enable fake timers per repo guidelines: inside the top-level describe block for this file, add setup/teardown to call vi.useFakeTimers() before tests (e.g., in beforeAll or beforeEach) and vi.useRealTimers() after tests (afterAll or afterEach) so timers and requestAnimationFrame are stubbed during tests; locate the describe(...) block in the file and add the before/after hooks referencing vi.useFakeTimers and vi.useRealTimers.
🤖 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/util/scale/getNiceTickValues.ts`:
- Around line 271-276: The function getTickValuesFixedDomain currently relies on
return type inference; explicitly annotate its return type (e.g., number[] or
the appropriate TickValue[]/Number[] type used across the scale utilities) to
satisfy the coding guideline. Update the function signature for
getTickValuesFixedDomain to include the explicit return type matching the values
it produces (and import or reference any existing alias like NumberDomain or
TickValue if used elsewhere) so callers and the type checker see the concrete
output type.
---
Outside diff comments:
In `@src/util/scale/getNiceTickValues.ts`:
- Around line 152-170: The JSDoc for calculateStep is out of date: add entries
for the new parameters stepFn (StepFunction used to compute/formats steps) and
niceTicks (boolean controlling whether tick extents are adjusted to "nice"
values) and update the `@return/description` if the returned shape changed; locate
the calculateStep function and its signature with parameters min, max,
tickCount, allowDecimals, correctionFactor, stepFn and any use of niceTicks,
then add clear JSDoc `@param` lines for stepFn and niceTicks (briefly describing
purpose and types) and ensure the `@return` block matches the actual returned
object shape.
In `@test/cartesian/XAxis/XAxis.vertical.spec.tsx`:
- Around line 198-230: Replace the typed assertion that uses Jest's
toHaveBeenLastCalledWith with the project helper expectLastCalledWith: change
the call that currently reads
expect(axisSettingsSpy).toHaveBeenLastCalledWith(expectedSettings) to use
expectLastCalledWith(axisSettingsSpy, expectedSettings). Keep the remaining
assertions for itemDataSpy unchanged; if the test helper expectLastCalledWith is
not already imported in the test file, add the import so the helper is
available.
- Around line 16-27: The test suite for XAxis (describe('<XAxis />') / inner
describe('layout=vertical')) lacks fake timers; add vi.useFakeTimers() at the
start of the test setup (e.g., in a beforeAll or beforeEach inside the
describe('<XAxis />') block) and restore real timers after tests with
vi.useRealTimers() in afterAll/afterEach to satisfy the repo guideline about
Redux autoBatchEnhancer and requestAnimationFrame; update the test file
XAxis.vertical.spec.tsx by locating the top-level describe('<XAxis />') and
adding these setup/teardown calls.
In `@test/component/Tooltip/Tooltip.payload.spec.tsx`:
- Around line 443-446: Add fake timers to the test suite by invoking
vi.useFakeTimers() in the shared setup and cleaning up with vi.useRealTimers()
afterwards; update the describe('Tooltip payload') setup by adding
vi.useFakeTimers() inside the beforeEach handler (where
mockGetBoundingClientRect is called) and add an afterEach that calls
vi.useRealTimers() to restore real timers so tests using
requestAnimationFrame/Redux autoBatchEnhancer behave deterministically.
In `@test/polar/PolarAngleAxis/PolarAngleAxis.spec.tsx`:
- Around line 858-878: Replace the two assertions that call
toHaveBeenLastCalledWith on the spies with the project's expectLastCalledWith
helper: locate the assertions against angleAxisSettingsSpy and niceTicksSpy in
PolarAngleAxis.spec.tsx and change them to use
expectLastCalledWith(angleAxisSettingsSpy, { ...expected settings... }) and
expectLastCalledWith(niceTicksSpy, [0,45,90,135,180,225,270,315,360])
respectively so the tests follow the guideline and gain the improved
typing/autocomplete behavior.
- Around line 117-120: The test suite in PolarAngleAxis.spec.tsx needs fake
timers enabled; add a vi.useFakeTimers() call at the start of the suite (e.g.,
inside the outer describe('<PolarAngleAxis />') or a beforeAll block) and pair
it with vi.useRealTimers() in an afterAll/afterEach cleanup to avoid leaking
timers; update the file where createSelectorTestCase/renderTestCase are defined
so the fake timers are active for tests that depend on
requestAnimationFrame/Redux autoBatchEnhancer.
In `@test/polar/PolarRadiusAxis.spec.tsx`:
- Around line 1189-1207: Replace the direct Jest assertion that uses
toHaveBeenLastCalledWith with the typed helper expectLastCalledWith: update the
test assertion that currently calls
expect(radiusAxisSpy).toHaveBeenLastCalledWith(expectedAxis) to use
expectLastCalledWith(radiusAxisSpy, expectedAxis) so typing and autocompletion
are preserved; this change should be made where radiusAxisSpy and expectedAxis
are referenced in PolarRadiusAxis.spec.tsx and ensure the expectLastCalledWith
helper is imported/available in the test file.
- Around line 1-4: The test suite in PolarRadiusAxis.spec.tsx must enable fake
timers; call vi.useFakeTimers() before the tests run (e.g., in a top-level
beforeAll or immediately after imports) and restore timers with
vi.useRealTimers() in afterAll to satisfy the repo guideline about Redux
autoBatchEnhancer and requestAnimationFrame; update the file where
describe/it/vi are used to ensure vi.useFakeTimers() is active for the suite and
vi.useRealTimers() is called in teardown.
In `@test/util/scale/getNiceTickValues.spec.ts`:
- Around line 1-3: The test suite in getNiceTickValues.spec.ts must enable fake
timers per repo guidelines: inside the top-level describe block for this file,
add setup/teardown to call vi.useFakeTimers() before tests (e.g., in beforeAll
or beforeEach) and vi.useRealTimers() after tests (afterAll or afterEach) so
timers and requestAnimationFrame are stubbed during tests; locate the
describe(...) block in the file and add the before/after hooks referencing
vi.useFakeTimers and vi.useRealTimers.
| export const getTickValuesFixedDomain = ( | ||
| [min, max]: NumberDomain, | ||
| tickCount: number, | ||
| allowDecimals = true, | ||
| niceTicks = false, | ||
| ) => { |
There was a problem hiding this comment.
Add an explicit return type for getTickValuesFixedDomain.
This function now has a modified signature but still relies on inference.
Suggested fix
export const getTickValuesFixedDomain = (
[min, max]: NumberDomain,
tickCount: number,
allowDecimals = true,
niceTicks = false,
-) => {
+): number[] => {As per coding guidelines "Type function parameters and return values explicitly. Do not rely on implicit any or inference, except for React components and trivial functions".
📝 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.
| export const getTickValuesFixedDomain = ( | |
| [min, max]: NumberDomain, | |
| tickCount: number, | |
| allowDecimals = true, | |
| niceTicks = false, | |
| ) => { | |
| export const getTickValuesFixedDomain = ( | |
| [min, max]: NumberDomain, | |
| tickCount: number, | |
| allowDecimals = true, | |
| niceTicks = false, | |
| ): number[] => { |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/util/scale/getNiceTickValues.ts` around lines 271 - 276, The function
getTickValuesFixedDomain currently relies on return type inference; explicitly
annotate its return type (e.g., number[] or the appropriate TickValue[]/Number[]
type used across the scale utilities) to satisfy the coding guideline. Update
the function signature for getTickValuesFixedDomain to include the explicit
return type matching the values it produces (and import or reference any
existing alias like NumberDomain or TickValue if used elsewhere) so callers and
the type checker see the concrete output type.
|
@MaxGhenis PR is failing the build, looks like a formatting issue |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The omnidoc validator checks componentMetaMap defaultProps objects, not inline ?? fallbacks. Add niceTicks: false to both polar axis default props so the @DefaultValue JSDoc matches. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The omnidoc API doc generator embeds JSDoc text into JSX. Curly braces
{1, 2, 2.5, 5} become JSX expressions triggering TS2695 comma operator
errors. Replace with parentheses (1, 2, 2.5, 5).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7009 +/- ##
==========================================
+ Coverage 90.11% 90.12% +0.01%
==========================================
Files 524 526 +2
Lines 39073 39241 +168
Branches 5399 5437 +38
==========================================
+ Hits 35211 35367 +156
- Misses 3853 3865 +12
Partials 9 9 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@ckifer Fixed — there were three issues: a prettier formatting violation, missing |
PavelVanecek
left a comment
There was a problem hiding this comment.
Let's use it in couple examples on the website, to show off the new prop
…7034) ## Description Adds the `@since 3.8` JSDoc annotation to the `niceTicks` prop on `XAxis` and `YAxis`, demonstrates the prop across multiple website example components, and fixes a pre-existing CI race condition that caused stale VR artifacts to be deployed. **JSDoc update (`src/cartesian/XAxis.tsx`, `src/cartesian/YAxis.tsx`):** - Added `@since 3.8` to the `niceTicks` prop documentation **Website examples** — added `niceTicks` to the numerical axis/axes in: - `AreaChart/SimpleAreaChart.tsx` — both `XAxis` and `YAxis` - `AreaChart/StackedAreaChart.tsx` — both `XAxis` and `YAxis` - `BarChart/StackedBarChart.tsx` — both `XAxis` and `YAxis` - `BarChart/MixBarChart.tsx` — `YAxis` (numerical axis) - `BarChart/BrushBarChart.tsx` — `YAxis` (numerical axis) - `Legend/LegendEffectOpacity.tsx` — both `XAxis` and `YAxis` - `Tooltip/CustomContentOfTooltip.tsx` — both `XAxis` and `YAxis` - `ComposedChart/LineBarAreaComposedChart.tsx` — `YAxis` (numerical axis) - `ComposedChart/ScatterAndLineOfBestFit.tsx` — both `XAxis` and `YAxis` (both are `type="number"`) - `ComposedChart/VerticalComposedChart.tsx` — `XAxis` only (the numerical axis in this chart) **CI workflow fix (`.github/workflows/ci.yml`):** - Added `concurrency: cancel-in-progress: true` to cancel in-progress workflow runs when a new commit is pushed to the same branch. This fixes a pre-existing race condition where two simultaneous CI runs for the same PR could result in an older run's VR artifact being deployed after a newer run's, causing the deployed report to show stale results. ## Related Issue https://github.com/recharts/recharts/issues — `niceTicks` introduced in PR #7009 ## Motivation and Context `niceTicks` was added in 3.8 but lacked a `@since` annotation and had no visible usage in the website examples, reducing its discoverability. The CI race condition occurred because the workflow had no `concurrency` setting, allowing multiple pipeline runs for the same PR branch to proceed simultaneously. When commit 1 (affecting 2 charts) deployed its 6-failure VR report to gh-pages, and commit 2 (affecting 7 charts) then ran its VR tests, the CI log would show 21 failures while the deployed artifact still showed the stale 6-failure report from the earlier run. ## How Has This Been Tested? ESLint (`react/jsx-boolean-value: "never"`) passes on all changed files. Existing example component tests cover the modified files. ## Screenshots (if appropriate): ## 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) ## Checklist: - [x] My change requires a change to the documentation. - [x] 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 <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Add @SInCE annotation to niceTicks, use it in website examples</issue_title> > <issue_description>In #7009 we have added a new prop `niceTicks` to XAxis and YAxis. Two tasks: > > - Add `@since 3.8` annotation to the JSDoc > - Locate 5 website examples (www/src/docs/exampleComponents) that use XAxis and 5 that use YAxis, and put niceTicks={true} prop to them so that we show off the new prop.</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #7033 <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: PavelVanecek <1100170+PavelVanecek@users.noreply.github.com> Co-authored-by: Pavel Vanecek <corkscreewe@gmail.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…icks (#7042) Okay so I added couple changes here on my own: - Changed `nicecTicks` from boolean to enum ('adaptive' | 'snap125') - let me know if you can think of better names - Added support for log and symlog scales - Added guide page and playground - Fixed a bug where ticks were not aligned in composed chart (this wasn't intentional but a happy coincidence, I'll take it) - Updated scale type definition to better match what is actually going on See https://recharts.github.io/recharts/pr-7042/www/en-US/guide/axisTicks/ - [x] Define `NiceTicks` type: `'none' | 'auto' | 'equidistant' | 'nice'` in `cartesianAxisSlice.ts` - [x] Update `TicksSettings.niceTicks` from `boolean` to `NiceTicks` - [x] Update `combineNiceTicks` in `axisSelectors.ts` to handle enum values - [x] Update defaults from `false` → `'auto'` in all axis settings and default props files - [x] Update component prop types in `XAxis.tsx`, `YAxis.tsx`, `PolarAngleAxis.tsx`, `PolarRadiusAxis.tsx` - [x] Export `NiceTicks` type from `src/index.ts` - [x] Update tests that referenced `niceTicks: false` to use `niceTicks: 'auto'` - [x] Add 3 new tests for `'none'`, `'equidistant'`, and `'nice'` enum values - [x] Add `NiceTicks` storybook story for visual documentation - [x] Add `NiceTicks` to the `exportsThatNeedExamples` list in `verifyExamples.spec.ts` - [x] Update `www/` example components using `niceTicks` (boolean shorthand) → `niceTicks="nice"` - [x] TypeScript checks pass, all 14000+ tests pass, ESLint clean, CodeQL clean <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Clarify niceTicks</issue_title> > <issue_description>Recharts now has three ways of rendering axis ticks: > > 1. ticks decided by d3, evenly spaced and not rounded > 2. "nice ticks A" calculated using `getFormatStep` (defined in `getNiceTickValues.ts`) > 3. "nice ticks B" calculated using `getFormatStepNice` (unreleased, scheduled for 3.8) > > Recharts sometimes decides to calculate ticks using variant 1 and sometimes variant 2, the conditions for selecting are not at all intuitive (only for numerical axes with linear scales of type "auto" with tickCount > 0 where at least one of the domain definitions contains the keyword "auto", how's that sound? see `combineNiceTicks` in `axisSelectors.ts`). > > Then [just recently](#7009) we have added variant 3 which is only activated if all of those rules above are true, AND there is `niceTicks=true` prop set on the axis. > > The initial idea was to replace the "nice ticks A" algorithm completely, only use the "B" variant and delete "A" variant for good. Turns out that the old A is _sometimes_ nicer than B! It uses the space more efficiently, at the expense of making some numbers look less rounded. The B on the other hand uses nice rounded numbers, but sometimes wastes space. Depending on user data. > > So let's do this: > > - Keep both A and B nice ticks variants > - Come up with some meaningful names ("nice nice ticks" and "nice ticks" don't cut it, A and B is also not great naming) > - Swap the `niceTicks` prop from boolean to an enum > - Set the magical selecting algorithm behind "niceTicks=auto" prop (default) > - Set the other two A/B using their own props > - If that prop is set explicitly then Recharts won't apply the magical selector, it will just calculate nice ticks using the selected algorithm > - One of the enum options will also be "none" where Recharts will not attempt any tick niceties > - Document what is going on</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > <comment_new><author>@PavelVanecek</author><body> > @ckifer @MaxGhenis thoughts?</body></comment_new> > <comment_new><author>@ckifer</author><body> > Sounds good to me, better than what we have going on if we release as-is for sure</body></comment_new> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #7040 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/recharts/recharts/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: PavelVanecek <1100170+PavelVanecek@users.noreply.github.com> Co-authored-by: Pavel Vanecek <corkscreewe@gmail.com>
Summary
Replaces the
getFormatSteprounding algorithm (0.05/0.1 granularity) with D3-style nice number snapping to{1, 2, 2.5, 5}multiples at each order of magnitude. This produces human-friendly tick values.Before → After examples
[0, 14][0, 4, 8, 12, 16][0, 5, 10, 15, 20][39.9, 42.5][39.9, 40.6, 41.3, 42, 42.7][39, 40, 41, 42, 43][-4.1, 0.6][-4.25, -3.4, -2.55, -1.7, -0.85, 0, 0.85][-5, -4, -3, -2, -1, 0, 1][0, 1.3e-5][0, 3.5e-6, 7e-6, 1.05e-5, 1.4e-5][0, 5e-6, 1e-5, 1.5e-5, 2e-5]How it works
The previous algorithm divided the step ratio by 0.05 or 0.1, ceiling-rounded, and multiplied back — producing steps like 3.5, 0.35, or 0.7 that don't feel "natural" to humans.
The new algorithm normalizes the rough step to
[1, 10)and snaps to the nearest ceiling value in{1, 2, 2.5, 5}, then multiplies by the appropriate power of 10. ThecorrectionFactormechanism (used bycalculateStepwhen it needs a larger step) now walks through this sequence instead of incrementing by 0.05/0.1.Additional fix
Renamed
getTickValuesFixedDomain.test.ts→.spec.tsso vitest actually discovers and runs these tests. The vitest config usesinclude: test/**/*.spec.ts?(x), so.test.tsfiles were silently skipped.Fixes #7008
Test plan
getFormatSteptest expectations for nicer valuesgetNiceTickValuestest expectations (5 tests improved)getTickValuesFixedDomaintest expectations (3 tests produce nicer but slightly fewer ticks, consistent with existing docstring: "may return less than tickCount ticks")🤖 Generated with Claude Code
Summary by CodeRabbit