Skip to content

Commit

Permalink
Improve linear tick min/max collision detection
Browse files Browse the repository at this point in the history
  • Loading branch information
kurkle committed May 5, 2021
1 parent 2165d22 commit 08f1fa8
Show file tree
Hide file tree
Showing 23 changed files with 194 additions and 7 deletions.
24 changes: 17 additions & 7 deletions src/scales/scale.linearbase.js
@@ -1,5 +1,5 @@
import {isNullOrUndef} from '../helpers/helpers.core';
import {almostEquals, almostWhole, niceNum, _decimalPlaces, _setMinAndMaxByKey, sign} from '../helpers/helpers.math';
import {almostEquals, almostWhole, niceNum, _decimalPlaces, _setMinAndMaxByKey, sign, toRadians} from '../helpers/helpers.math';
import Scale from '../core/core.scale';
import {formatNumber} from '../helpers/helpers.intl';

Expand Down Expand Up @@ -29,7 +29,7 @@ function generateTicks(generationOptions, dataRange) {
// for details.

const MIN_SPACING = 1e-14;
const {step, min, max, precision, count, maxTicks, maxDigits, horizontal, includeBounds} = generationOptions;
const {step, min, max, precision, count, maxTicks, maxDigits, includeBounds} = generationOptions;
const unit = step || 1;
const maxSpaces = maxTicks - 1;
const {min: rmin, max: rmax} = dataRange;
Expand Down Expand Up @@ -97,14 +97,14 @@ function generateTicks(generationOptions, dataRange) {

let j = 0;
if (minDefined) {
if (includeBounds) {
if (includeBounds && niceMin !== min) {
ticks.push({value: min});
// If the niceMin is smaller or equal to min, skip it
if (niceMin <= min) {
if (niceMin < min) {
j++;
}
// If the next nice tick is close to min, skip that too
if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, minSpacing * (horizontal ? ('' + min).length : 1))) {
if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, relativeLabelSize(min, minSpacing, generationOptions))) {
j++;
}
} else if (niceMin < min) {
Expand All @@ -116,9 +116,9 @@ function generateTicks(generationOptions, dataRange) {
ticks.push({value: Math.round((niceMin + j * spacing) * factor) / factor});
}

if (maxDefined && includeBounds) {
if (maxDefined && includeBounds && niceMax !== max) {
// If the previous tick is close to max, replace it with max, else add max
if (almostEquals(ticks[ticks.length - 1].value, max, minSpacing * (horizontal ? ('' + max).length : 1))) {
if (almostEquals(ticks[ticks.length - 1].value, max, relativeLabelSize(max, minSpacing, generationOptions))) {
ticks[ticks.length - 1].value = max;
} else {
ticks.push({value: max});
Expand All @@ -130,6 +130,15 @@ function generateTicks(generationOptions, dataRange) {
return ticks;
}

function relativeLabelSize(value, minSpacing, {horizontal, minRotation}) {
const rot = toRadians(minRotation);
const useLength = (horizontal && minRotation <= 45) || (!horizontal && minRotation >= 45);
const l = useLength ? minSpacing * ('' + value).length : 0;
const sin = Math.sin(rot);
const cos = Math.cos(rot);
return horizontal ? cos * l + sin * minSpacing : sin * l + cos * minSpacing;
}

export default class LinearScaleBase extends Scale {

constructor(cfg) {
Expand Down Expand Up @@ -237,6 +246,7 @@ export default class LinearScaleBase extends Scale {
count: tickOpts.count,
maxDigits: me._maxDigits(),
horizontal: me.isHorizontal(),
minRotation: tickOpts.minRotation || 0,
includeBounds: tickOpts.includeBounds !== false
};
const dataRange = me._range || me;
Expand Down
File renamed without changes.
File renamed without changes.
41 changes: 41 additions & 0 deletions test/fixtures/scale.linear/min-max-skip/no-collision.js
@@ -0,0 +1,41 @@
module.exports = {
description: 'https://github.com/chartjs/Chart.js/issues/9025',
threshold: 0.2,
config: {
type: 'line',
data: {
datasets: [{
data: [
{x: 10000000, y: 65},
{x: 20000000, y: 12},
{x: 30000000, y: 23},
{x: 40000000, y: 51},
{x: 50000000, y: 17},
{x: 60000000, y: 23}
]
}]
},
options: {
scales: {
x: {
type: 'linear',
min: 10000000,
max: 60000000,
ticks: {
minRotation: 45,
maxRotation: 45,
count: 6
}
}
}
}
},
options: {
canvas: {
width: 200,
height: 200
},
spriteText: true
}
};

Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions test/fixtures/scale.linear/min-max-skip/rotated-case-1.js
@@ -0,0 +1,34 @@
module.exports = {
description: 'https://github.com/chartjs/Chart.js/issues/9025',
threshold: 0.15,
config: {
type: 'scatter',
options: {
scales: {
y: {
max: 1069,
min: 230,
ticks: {
autoSkip: false,
minRotation: 22.5
}
},
x: {
max: 1069,
min: 230,
ticks: {
autoSkip: false,
minRotation: 35
}
}
}
}
},
options: {
spriteText: true,
canvas: {
height: 211,
width: 415
}
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions test/fixtures/scale.linear/min-max-skip/rotated-case-2.js
@@ -0,0 +1,34 @@
module.exports = {
description: 'https://github.com/chartjs/Chart.js/issues/9025',
threshold: 0.15,
config: {
type: 'scatter',
options: {
scales: {
y: {
max: 1069,
min: 230,
ticks: {
autoSkip: false,
minRotation: 22.5
}
},
x: {
max: 1069,
min: 230,
ticks: {
autoSkip: false,
minRotation: 35
}
}
}
}
},
options: {
spriteText: true,
canvas: {
height: 214,
width: 416
}
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions test/fixtures/scale.linear/min-max-skip/rotated-case-3.js
@@ -0,0 +1,34 @@
module.exports = {
description: 'https://github.com/chartjs/Chart.js/issues/9025',
threshold: 0.15,
config: {
type: 'scatter',
options: {
scales: {
y: {
max: 1069,
min: 230,
ticks: {
autoSkip: false,
minRotation: 22.5
}
},
x: {
max: 1069,
min: 230,
ticks: {
autoSkip: false,
minRotation: 35
}
}
}
}
},
options: {
spriteText: true,
canvas: {
height: 216,
width: 520
}
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions test/fixtures/scale.linear/min-max-skip/rotated-case-4.js
@@ -0,0 +1,34 @@
module.exports = {
description: 'https://github.com/chartjs/Chart.js/issues/9025',
threshold: 0.15,
config: {
type: 'scatter',
options: {
scales: {
y: {
max: 1069,
min: 230,
ticks: {
autoSkip: false,
minRotation: 22.5
}
},
x: {
max: 1069,
min: 230,
ticks: {
autoSkip: false,
minRotation: 35
}
}
}
}
},
options: {
spriteText: true,
canvas: {
height: 217,
width: 521
}
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 08f1fa8

Please sign in to comment.