Skip to content

Fix floating point drift in generated linear scale ticks - #12282

Open
UlikGames wants to merge 1 commit into
chartjs:masterfrom
UlikGames:fix/12281-tick-float-drift
Open

Fix floating point drift in generated linear scale ticks#12282
UlikGames wants to merge 1 commit into
chartjs:masterfrom
UlikGames:fix/12281-tick-float-drift

Conversation

@UlikGames

Copy link
Copy Markdown

Fixes #12281

Reproduction from the issue: https://codepen.io/lamasse/pen/MYJzVpz

generateTicks rounds every tick with Math.round(tickValue * factor) / factor so the values reaching ticks.callback come out clean. The factor comes from _decimalPlaces(niceMin), but with bounds: 'ticks' niceMin is itself Math.floor(rmin / spacing) * spacing. For min 49.894 / max 51.5264 that is 49.800000000000004 instead of 49.8, _decimalPlaces reports 16, the factor becomes 1e16, and rounding to the 16th decimal does nothing.

Before:
49.894, 50.00000000000001, 50.2, 50.400000000000006, 50.6, 50.800000000000004, 51.00000000000001, 51.2, 51.400000000000006, 51.5264

After:
49.894, 50, 50.2, 50.4, 50.6, 50.8, 51, 51.2, 51.4, 51.5264

The built-in formatter hides the drift, but a callback like value => Number.isInteger(value) ? value : '' labels nothing at all.

niceMin and niceMax are whole multiples of spacing, so they never need more decimals than spacing itself. Rounding them to that precision where they are computed is exact rather than a fudge, and it also covers the count branch below, which reuses the same value.

Note this does change tick values for charts with non-round bounds. The values move to what they were always meant to be, and every image-based test still matches pixel for pixel, but it is a visible change rather than a pure internal cleanup.

Added a regression spec; it fails on master with the "before" list above.

Verified locally: karma 1703/1703 in Chrome including the image tests, eslint on js and md, tsc declarations and test/types, and the node, node-commonjs and typescript-node integration tests.

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.

Ticks may carry floating point drift

1 participant