From 777b6aafed9cc49a85db59bf8e4da0ec372cee61 Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Thu, 4 Mar 2021 23:52:36 +0200 Subject: [PATCH] Linear: Skip ticks that would overlap with min/max --- 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 fe439156850..6d8f1e1a31c 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 00000000000..03fee6f9358 --- /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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