Linear scale handle min === max when abs(max) > Number.MAX_SAFE_INTEGER (#9433)

This commit is contained in:
Evert Timberg 2021-07-18 11:14:33 -04:00 committed by GitHub
parent 259f8e8471
commit 991f151f51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 2 deletions

View File

@ -195,10 +195,20 @@ export default class LinearScaleBase extends Scale {
}
if (min === max) {
setMax(max + 1);
let offset = 1;
if (max >= Number.MAX_SAFE_INTEGER || min <= Number.MIN_SAFE_INTEGER) {
// In this case, the magnitude of the number is so large that
// max === max + 1 due to how IEEE754 doubles work. We need to increase
// the range by a larger number. Let's be safe and make this 5% of the number
//
// TODO - V4, make this the new default behaviour and eliminate +1 in other cases
offset = Math.abs(max * 0.05);
}
setMax(max + offset);
if (!beginAtZero) {
setMin(min - 1);
setMin(min - offset);
}
}
me.min = min;

View File

@ -482,6 +482,56 @@ describe('Linear Scale', function() {
expect(chart.scales.y.max).toBe(1);
});
it('Should ensure that the scale has a max and min that are not equal - large positive numbers', function() {
// https://github.com/chartjs/Chart.js/issues/9377
var chart = window.acquireChart({
type: 'line',
data: {
datasets: [{
// Value larger than Number.MAX_SAFE_INTEGER
data: [10000000000000000]
}],
labels: ['a']
},
options: {
scales: {
y: {
type: 'linear'
}
}
}
});
expect(chart.scales.y).not.toEqual(undefined); // must construct
expect(chart.scales.y.min).toBe(10000000000000000 * 0.95);
expect(chart.scales.y.max).toBe(10000000000000000 * 1.05);
});
it('Should ensure that the scale has a max and min that are not equal - large negative numbers', function() {
// https://github.com/chartjs/Chart.js/issues/9377
var chart = window.acquireChart({
type: 'line',
data: {
datasets: [{
// Value larger than Number.MAX_SAFE_INTEGER
data: [-10000000000000000]
}],
labels: ['a']
},
options: {
scales: {
y: {
type: 'linear'
}
}
}
});
expect(chart.scales.y).not.toEqual(undefined); // must construct
expect(chart.scales.y.max).toBe(-10000000000000000 * 0.95);
expect(chart.scales.y.min).toBe(-10000000000000000 * 1.05);
});
it('Should ensure that the scale has a max and min that are not equal when beginAtZero is set', function() {
var chart = window.acquireChart({
type: 'bar',