]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Linear scale handle min === max when abs(max) > Number.MAX_SAFE_INTEGER (#9433)
authorEvert Timberg <evert.timberg+github@gmail.com>
Sun, 18 Jul 2021 15:14:33 +0000 (11:14 -0400)
committerGitHub <noreply@github.com>
Sun, 18 Jul 2021 15:14:33 +0000 (11:14 -0400)
src/scales/scale.linearbase.js
test/specs/scale.linear.tests.js

index cccfa46d4bf604e7a6a5e18643e83e031aac2938..f7a0d02c590cd71fb7747fb03c557a66a90e1113 100644 (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;
index 8591ceba69df5ef15c80f60010fbe0a4f04258e1..e2ad37e41a20d5948325ca8d38c89faad210b315 100644 (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',