From e951ab2b5055331f6212be7fccd6aabd32f7edb1 Mon Sep 17 00:00:00 2001 From: J Copperfield Date: Thu, 15 Feb 2018 13:14:33 +0100 Subject: [PATCH 1/2] Bugfix: Improve polyfill function of log10 to return whole powers of 10 as integer values, as it caused endless loop in IE11 in the tick creation loop. --- src/core/core.helpers.js | 8 +++++++- test/specs/core.helpers.tests.js | 8 ++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/core/core.helpers.js b/src/core/core.helpers.js index bdce895cf70..755b6d02648 100644 --- a/src/core/core.helpers.js +++ b/src/core/core.helpers.js @@ -159,7 +159,13 @@ module.exports = function(Chart) { return Math.log10(x); } : function(x) { - return Math.log(x) / Math.LN10; + var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10. + // Check for whole powers of 10, + // which due to floating point rounding error should be corrected. + var powerOf10 = Math.round(exponent); + var isPowerOf10 = (x / Math.pow(10, powerOf10)) === 1; + + return isPowerOf10 ? powerOf10 : exponent; }; helpers.toRadians = function(degrees) { return degrees * (Math.PI / 180); diff --git a/test/specs/core.helpers.tests.js b/test/specs/core.helpers.tests.js index 44446d38ab8..eb96ef8c745 100644 --- a/test/specs/core.helpers.tests.js +++ b/test/specs/core.helpers.tests.js @@ -194,8 +194,12 @@ describe('Core helper tests', function() { it('should do a log10 operation', function() { expect(helpers.log10(0)).toBe(-Infinity); - expect(helpers.log10(1)).toBe(0); - expect(helpers.log10(1000)).toBeCloseTo(3, 1e-9); + + // Check all allowed powers of 10, which should return integer values + var maxPowerOf10 = Math.floor(helpers.log10(Number.MAX_VALUE)); + for (var i = 0; i < maxPowerOf10; i += 1) { + expect(helpers.log10(Math.pow(10, i))).toBe(i); + } }); it('should correctly determine if two numbers are essentially equal', function() { From 48a9d9299c7e1c8e743f550cbb2c65d16cf6dc4b Mon Sep 17 00:00:00 2001 From: J Copperfield Date: Mon, 19 Feb 2018 11:31:15 +0100 Subject: [PATCH 2/2] Compare floating-point numbers directly instead of using unnecessary division. --- src/core/core.helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.helpers.js b/src/core/core.helpers.js index 755b6d02648..347fd958e83 100644 --- a/src/core/core.helpers.js +++ b/src/core/core.helpers.js @@ -163,7 +163,7 @@ module.exports = function(Chart) { // Check for whole powers of 10, // which due to floating point rounding error should be corrected. var powerOf10 = Math.round(exponent); - var isPowerOf10 = (x / Math.pow(10, powerOf10)) === 1; + var isPowerOf10 = x === Math.pow(10, powerOf10); return isPowerOf10 ? powerOf10 : exponent; };