From 9095a686e9020d69d69352b27f413994588c6714 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Wed, 26 Jun 2019 09:43:49 -0700 Subject: [PATCH 1/4] Add helpers.math._factorize --- src/helpers/helpers.math.js | 34 ++++++++++++++++++++++++++++++++ src/helpers/index.js | 1 + src/scales/scale.time.js | 17 ++++++++-------- test/specs/helpers.math.tests.js | 14 +++++++++++++ 4 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 src/helpers/helpers.math.js create mode 100644 test/specs/helpers.math.tests.js diff --git a/src/helpers/helpers.math.js b/src/helpers/helpers.math.js new file mode 100644 index 00000000000..9ed8114eab9 --- /dev/null +++ b/src/helpers/helpers.math.js @@ -0,0 +1,34 @@ +'use strict'; + +/** + * @alias Chart.helpers.math + * @namespace + */ +var exports = { + /** + * Returns an array of factors sorted from 1 to sqrt(value) + * @private + */ + _factorize: function(value) { + var result = []; + var sqrt = Math.sqrt(value); + var i; + + for (i = 1; i < sqrt; i++) { + if (value % i === 0) { + result.push(i); + result.push(value / i); + } + } + if (sqrt === (sqrt | 0)) { // if value is a square number + result.push(sqrt); + } + + result.sort(function(a, b) { + return a - b; + }).pop(); + return result; + } +}; + +module.exports = exports; diff --git a/src/helpers/index.js b/src/helpers/index.js index 60c199cad55..ef510076090 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -4,3 +4,4 @@ module.exports = require('./helpers.core'); module.exports.easing = require('./helpers.easing'); module.exports.canvas = require('./helpers.canvas'); module.exports.options = require('./helpers.options'); +module.exports.math = require('./helpers.math'); diff --git a/src/scales/scale.time.js b/src/scales/scale.time.js index 0f6348bc433..88ccdf7a271 100644 --- a/src/scales/scale.time.js +++ b/src/scales/scale.time.js @@ -6,6 +6,7 @@ var helpers = require('../helpers/index'); var Scale = require('../core/core.scale'); var valueOrDefault = helpers.valueOrDefault; +var factorize = helpers.math._factorize; // Integer constants are from the ES6 spec. var MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991; @@ -15,42 +16,42 @@ var INTERVALS = { millisecond: { common: true, size: 1, - steps: [1, 2, 5, 10, 20, 50, 100, 250, 500] + steps: factorize(1000) }, second: { common: true, size: 1000, - steps: [1, 2, 5, 10, 15, 30] + steps: factorize(60) }, minute: { common: true, size: 60000, - steps: [1, 2, 5, 10, 15, 30] + steps: factorize(60) }, hour: { common: true, size: 3600000, - steps: [1, 2, 3, 6, 12] + steps: factorize(24) }, day: { common: true, size: 86400000, - steps: [1, 2, 5] + steps: factorize(10) }, week: { common: false, size: 604800000, - steps: [1, 2, 3, 4] + steps: factorize(4) }, month: { common: true, size: 2.628e9, - steps: [1, 2, 3] + steps: factorize(12) }, quarter: { common: false, size: 7.884e9, - steps: [1, 2, 3, 4] + steps: factorize(4) }, year: { common: true, diff --git a/test/specs/helpers.math.tests.js b/test/specs/helpers.math.tests.js new file mode 100644 index 00000000000..aa29a5588e8 --- /dev/null +++ b/test/specs/helpers.math.tests.js @@ -0,0 +1,14 @@ +'use strict'; + +describe('Chart.helpers.math', function() { + var factorize = Chart.helpers.math._factorize; + + it('should factorize', function() { + expect(factorize(1000)).toEqual([1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, 125, 200, 250, 500]); + expect(factorize(60)).toEqual([1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30]); + expect(factorize(30)).toEqual([1, 2, 3, 5, 6, 10, 15]); + expect(factorize(24)).toEqual([1, 2, 3, 4, 6, 8, 12]); + expect(factorize(12)).toEqual([1, 2, 3, 4, 6]); + expect(factorize(4)).toEqual([1, 2]); + }); +}); From 3722785680292af39d34d51dac2a7b46f8f6285d Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 27 Jun 2019 07:38:17 -0700 Subject: [PATCH 2/4] Input validation --- src/helpers/helpers.math.js | 4 ++++ test/specs/helpers.math.tests.js | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/helpers/helpers.math.js b/src/helpers/helpers.math.js index 9ed8114eab9..fcd6d4db055 100644 --- a/src/helpers/helpers.math.js +++ b/src/helpers/helpers.math.js @@ -14,6 +14,10 @@ var exports = { var sqrt = Math.sqrt(value); var i; + if (!Number.isInteger(value) || value <= 0) { + throw new Error('_factorize expects a positive integer, but received ' + value); + } + for (i = 1; i < sqrt; i++) { if (value % i === 0) { result.push(i); diff --git a/test/specs/helpers.math.tests.js b/test/specs/helpers.math.tests.js index aa29a5588e8..e1699ce2fd8 100644 --- a/test/specs/helpers.math.tests.js +++ b/test/specs/helpers.math.tests.js @@ -10,5 +10,11 @@ describe('Chart.helpers.math', function() { expect(factorize(24)).toEqual([1, 2, 3, 4, 6, 8, 12]); expect(factorize(12)).toEqual([1, 2, 3, 4, 6]); expect(factorize(4)).toEqual([1, 2]); + expect(function() { + factorize(-1); + }).toThrow(new Error('_factorize expects a positive integer, but received -1')); + expect(function() { + factorize(2.76); + }).toThrow(new Error('_factorize expects a positive integer, but received 2.76')); }); }); From f25b47e1f52bef578fc8f4876dd2926d55ccb49d Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 27 Jun 2019 14:05:42 -0700 Subject: [PATCH 3/4] Don't throw Error --- src/helpers/helpers.math.js | 4 ---- test/specs/helpers.math.tests.js | 9 +++------ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/helpers/helpers.math.js b/src/helpers/helpers.math.js index fcd6d4db055..9ed8114eab9 100644 --- a/src/helpers/helpers.math.js +++ b/src/helpers/helpers.math.js @@ -14,10 +14,6 @@ var exports = { var sqrt = Math.sqrt(value); var i; - if (!Number.isInteger(value) || value <= 0) { - throw new Error('_factorize expects a positive integer, but received ' + value); - } - for (i = 1; i < sqrt; i++) { if (value % i === 0) { result.push(i); diff --git a/test/specs/helpers.math.tests.js b/test/specs/helpers.math.tests.js index e1699ce2fd8..e67c48ba0ef 100644 --- a/test/specs/helpers.math.tests.js +++ b/test/specs/helpers.math.tests.js @@ -10,11 +10,8 @@ describe('Chart.helpers.math', function() { expect(factorize(24)).toEqual([1, 2, 3, 4, 6, 8, 12]); expect(factorize(12)).toEqual([1, 2, 3, 4, 6]); expect(factorize(4)).toEqual([1, 2]); - expect(function() { - factorize(-1); - }).toThrow(new Error('_factorize expects a positive integer, but received -1')); - expect(function() { - factorize(2.76); - }).toThrow(new Error('_factorize expects a positive integer, but received 2.76')); + expect(factorize(4)).toEqual([1, 2]); + expect(factorize(-1)).toEqual([]); + expect(factorize(2.76)).toEqual([]); }); }); From 92c2f61665f0e3131af117075a7696835e938c6d Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 27 Jun 2019 21:42:46 -0700 Subject: [PATCH 4/4] Remove duplicate test statement --- test/specs/helpers.math.tests.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/specs/helpers.math.tests.js b/test/specs/helpers.math.tests.js index e67c48ba0ef..c26435f65a1 100644 --- a/test/specs/helpers.math.tests.js +++ b/test/specs/helpers.math.tests.js @@ -10,7 +10,6 @@ describe('Chart.helpers.math', function() { expect(factorize(24)).toEqual([1, 2, 3, 4, 6, 8, 12]); expect(factorize(12)).toEqual([1, 2, 3, 4, 6]); expect(factorize(4)).toEqual([1, 2]); - expect(factorize(4)).toEqual([1, 2]); expect(factorize(-1)).toEqual([]); expect(factorize(2.76)).toEqual([]); });