From: Jukka Kurkela Date: Wed, 28 Apr 2021 20:41:57 +0000 (+0300) Subject: Improve linear tick generators collision estimation (#8983) X-Git-Tag: v3.2.1~6 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=44e62e77ca264119c4565829fd8895431be29ff5;p=thirdparty%2FChart.js.git Improve linear tick generators collision estimation (#8983) * Increase distance to min/max tick to 1/3 space * Better estimation on linear tick collision * Lint fix * Remove unused change --- diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 5b793a6f3..f5feb9fff 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -1658,4 +1658,13 @@ export default class Scale extends Element { const opts = this.options.ticks.setContext(this.getContext(index)); return toFont(opts.font); } + + /** + * @protected + */ + _maxDigits() { + const me = this; + const fontSize = me._resolveTickFontOptions(0).lineHeight; + return me.isHorizontal() ? me.width / fontSize / 0.7 : me.height / fontSize; + } } diff --git a/src/scales/scale.linearbase.js b/src/scales/scale.linearbase.js index 9eda15c33..de1dbe967 100644 --- a/src/scales/scale.linearbase.js +++ b/src/scales/scale.linearbase.js @@ -29,13 +29,14 @@ function generateTicks(generationOptions, dataRange) { // for details. const MIN_SPACING = 1e-14; - const {step, min, max, precision, count, maxTicks} = generationOptions; + const {step, min, max, precision, count, maxTicks, maxDigits, horizontal} = generationOptions; const unit = step || 1; const maxSpaces = maxTicks - 1; const {min: rmin, max: rmax} = dataRange; const minDefined = !isNullOrUndef(min); const maxDefined = !isNullOrUndef(max); const countDefined = !isNullOrUndef(count); + const minSpacing = (rmax - rmin) / maxDigits; let spacing = niceNum((rmax - rmin) / maxSpaces / unit) * unit; let factor, niceMin, niceMax, numSpaces; @@ -102,7 +103,7 @@ function generateTicks(generationOptions, dataRange) { j++; } // If the next nice tick is close to min, skip that too - if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, spacing / 10)) { + if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, minSpacing * (horizontal ? ('' + min).length : 1))) { j++; } } @@ -113,7 +114,7 @@ function generateTicks(generationOptions, dataRange) { if (maxDefined) { // If the previous tick is close to max, replace it with max, else add max - if (almostEquals(ticks[ticks.length - 1].value, max, spacing / 10)) { + if (almostEquals(ticks[ticks.length - 1].value, max, minSpacing * (horizontal ? ('' + max).length : 1))) { ticks[ticks.length - 1].value = max; } else { ticks.push({value: max}); @@ -230,6 +231,8 @@ export default class LinearScaleBase extends Scale { precision: tickOpts.precision, step: tickOpts.stepSize, count: tickOpts.count, + maxDigits: me._maxDigits(), + horizontal: me.isHorizontal() }; const dataRange = me._range || me; const ticks = generateTicks(numericGeneratorOptions, dataRange); diff --git a/test/fixtures/scale.linear/min-max-skip-edge-case-1.js b/test/fixtures/scale.linear/min-max-skip-edge-case-1.js new file mode 100644 index 000000000..89a6dd883 --- /dev/null +++ b/test/fixtures/scale.linear/min-max-skip-edge-case-1.js @@ -0,0 +1,31 @@ +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/8982', + config: { + type: 'scatter', + options: { + scales: { + y: { + max: 1069, + min: 230, + ticks: { + autoSkip: false + } + }, + x: { + max: 1069, + min: 230, + ticks: { + autoSkip: false + } + } + } + } + }, + options: { + spriteText: true, + canvas: { + height: 211, + width: 408 + } + } +}; diff --git a/test/fixtures/scale.linear/min-max-skip-edge-case-1.png b/test/fixtures/scale.linear/min-max-skip-edge-case-1.png new file mode 100644 index 000000000..9401c0eb4 Binary files /dev/null and b/test/fixtures/scale.linear/min-max-skip-edge-case-1.png differ diff --git a/test/fixtures/scale.linear/min-max-skip-edge-case-2.js b/test/fixtures/scale.linear/min-max-skip-edge-case-2.js new file mode 100644 index 000000000..8325a4d68 --- /dev/null +++ b/test/fixtures/scale.linear/min-max-skip-edge-case-2.js @@ -0,0 +1,31 @@ +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/8982', + config: { + type: 'scatter', + options: { + scales: { + y: { + max: 1069, + min: 230, + ticks: { + autoSkip: false + } + }, + x: { + max: 1069, + min: 230, + ticks: { + autoSkip: false + } + } + } + } + }, + options: { + spriteText: true, + canvas: { + height: 212, + width: 409 + } + } +}; diff --git a/test/fixtures/scale.linear/min-max-skip-edge-case-2.png b/test/fixtures/scale.linear/min-max-skip-edge-case-2.png new file mode 100644 index 000000000..f2f878f89 Binary files /dev/null and b/test/fixtures/scale.linear/min-max-skip-edge-case-2.png differ diff --git a/test/fixtures/scale.linear/min-max-skip-edge-case-3.js b/test/fixtures/scale.linear/min-max-skip-edge-case-3.js new file mode 100644 index 000000000..eca5a110f --- /dev/null +++ b/test/fixtures/scale.linear/min-max-skip-edge-case-3.js @@ -0,0 +1,31 @@ +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/8982', + config: { + type: 'scatter', + options: { + scales: { + y: { + max: 1069, + min: 230, + ticks: { + autoSkip: false + } + }, + x: { + max: 1069, + min: 230, + ticks: { + autoSkip: false + } + } + } + } + }, + options: { + spriteText: true, + canvas: { + height: 213, + width: 536 + } + } +}; diff --git a/test/fixtures/scale.linear/min-max-skip-edge-case-3.png b/test/fixtures/scale.linear/min-max-skip-edge-case-3.png new file mode 100644 index 000000000..55cc3cbdb Binary files /dev/null and b/test/fixtures/scale.linear/min-max-skip-edge-case-3.png differ diff --git a/test/fixtures/scale.linear/min-max-skip-edge-case-4.js b/test/fixtures/scale.linear/min-max-skip-edge-case-4.js new file mode 100644 index 000000000..3993e3798 --- /dev/null +++ b/test/fixtures/scale.linear/min-max-skip-edge-case-4.js @@ -0,0 +1,31 @@ +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/8982', + config: { + type: 'scatter', + options: { + scales: { + y: { + max: 1069, + min: 230, + ticks: { + autoSkip: false + } + }, + x: { + max: 1069, + min: 230, + ticks: { + autoSkip: false + } + } + } + } + }, + options: { + spriteText: true, + canvas: { + height: 214, + width: 537 + } + } +}; diff --git a/test/fixtures/scale.linear/min-max-skip-edge-case-4.png b/test/fixtures/scale.linear/min-max-skip-edge-case-4.png new file mode 100644 index 000000000..2f7f6276b Binary files /dev/null and b/test/fixtures/scale.linear/min-max-skip-edge-case-4.png differ