From 24b14193b362c59b4d4f809031a5164e34606067 Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Fri, 5 Mar 2021 02:37:46 +0200 Subject: [PATCH] Linear: Skip ticks that would overlap with min/max (#8569) --- src/scales/scale.linearbase.js | 35 +++++++++++++++++--- test/fixtures/scale.linear/min-max-skip.js | 20 +++++++++++ test/fixtures/scale.linear/min-max-skip.png | Bin 0 -> 12610 bytes test/specs/scale.radialLinear.tests.js | 2 +- 4 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 test/fixtures/scale.linear/min-max-skip.js create mode 100644 test/fixtures/scale.linear/min-max-skip.png diff --git a/src/scales/scale.linearbase.js b/src/scales/scale.linearbase.js index fe4391568..6d8f1e1a3 100644 --- a/src/scales/scale.linearbase.js +++ b/src/scales/scale.linearbase.js @@ -42,12 +42,14 @@ function generateTicks(generationOptions, dataRange) { const unit = stepSize || 1; const maxNumSpaces = generationOptions.maxTicks - 1; const {min: rmin, max: rmax} = dataRange; + const minDefined = !isNullOrUndef(min); + const maxDefined = !isNullOrUndef(max); let spacing = niceNum((rmax - rmin) / maxNumSpaces / unit) * unit; let factor, niceMin, niceMax, numSpaces; // Beyond MIN_SPACING floating point numbers being to lose precision // such that we can't do the math necessary to generate ticks - if (spacing < MIN_SPACING && isNullOrUndef(min) && isNullOrUndef(max)) { + if (spacing < MIN_SPACING && !minDefined && !maxDefined) { return [{value: rmin}, {value: rmax}]; } @@ -70,7 +72,7 @@ function generateTicks(generationOptions, dataRange) { niceMax = Math.ceil(rmax / spacing) * spacing; // If min, max and stepSize is set and they make an evenly spaced scale use it. - if (stepSize && !isNullOrUndef(min) && !isNullOrUndef(max)) { + if (stepSize && minDefined && maxDefined) { // If very close to our whole number, use it. if (almostWhole((max - min) / stepSize, spacing / 1000)) { niceMin = min; @@ -88,11 +90,34 @@ function generateTicks(generationOptions, dataRange) { niceMin = Math.round(niceMin * factor) / factor; niceMax = Math.round(niceMax * factor) / factor; - ticks.push({value: isNullOrUndef(min) ? niceMin : min}); - for (let j = 1; j < numSpaces; ++j) { + + let j = 0; + if (minDefined) { + ticks.push({value: min}); + // If the niceMin is smaller than min, skip it + if (niceMin < min) { + j++; + } + // If the next nice tick is close to min, skip that too + if (almostWhole(Math.round((niceMin + j * spacing) * factor) / factor / min, spacing / 1000)) { + j++; + } + } + + for (; j < numSpaces; ++j) { ticks.push({value: Math.round((niceMin + j * spacing) * factor) / factor}); } - ticks.push({value: isNullOrUndef(max) ? niceMax : max}); + + if (maxDefined) { + // If the previous tick is close to max, replace it with max, else add max + if (almostWhole(ticks[ticks.length - 1].value / max, spacing / 1000)) { + ticks[ticks.length - 1].value = max; + } else { + ticks.push({value: max}); + } + } else { + ticks.push({value: niceMax}); + } return ticks; } diff --git a/test/fixtures/scale.linear/min-max-skip.js b/test/fixtures/scale.linear/min-max-skip.js new file mode 100644 index 000000000..03fee6f93 --- /dev/null +++ b/test/fixtures/scale.linear/min-max-skip.js @@ -0,0 +1,20 @@ +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/7734', + config: { + type: 'line', + options: { + scales: { + y: { + max: 1225.2, + min: 369.5, + }, + x: { + display: false + } + } + } + }, + options: { + spriteText: true + } +}; diff --git a/test/fixtures/scale.linear/min-max-skip.png b/test/fixtures/scale.linear/min-max-skip.png new file mode 100644 index 0000000000000000000000000000000000000000..9141f8d20de76413bc9ead7019ed8ef063d0715e GIT binary patch literal 12610 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 SXMupfgZr(_UhQ?h^uGX4-!r}d literal 0 Hc-jL100001 diff --git a/test/specs/scale.radialLinear.tests.js b/test/specs/scale.radialLinear.tests.js index 745e95d1a..e70fb9494 100644 --- a/test/specs/scale.radialLinear.tests.js +++ b/test/specs/scale.radialLinear.tests.js @@ -200,7 +200,7 @@ describe('Test the radial linear scale', function() { expect(chart.scales.r.min).toBe(-1010); expect(chart.scales.r.max).toBe(1010); - expect(getLabels(chart.scales.r)).toEqual(['-1,010', '-1,000', '-500', '0', '500', '1,000', '1,010']); + expect(getLabels(chart.scales.r)).toEqual(['-1,010', '-500', '0', '500', '1,010']); }); it('should forcibly include 0 in the range if the beginAtZero option is used', function() { -- 2.47.3