diff --git a/src/core/core.helpers.js b/src/core/core.helpers.js index 65bdd1304..d61b9bc82 100644 --- a/src/core/core.helpers.js +++ b/src/core/core.helpers.js @@ -264,6 +264,9 @@ helpers.isNumber = function(n) { return !isNaN(parseFloat(n)) && isFinite(n); }; + helpers.almostEquals = function(x, y, epsilon) { + return Math.abs(x - y) < epsilon; + }; helpers.max = function(array) { return array.reduce(function(max, value) { if (!isNaN(value)) { diff --git a/src/scales/scale.linear.js b/src/scales/scale.linear.js index 334e999eb..e934f3c83 100644 --- a/src/scales/scale.linear.js +++ b/src/scales/scale.linear.js @@ -183,7 +183,13 @@ var niceMin = Math.floor(this.min / spacing) * spacing; var niceMax = Math.ceil(this.max / spacing) * spacing; - var numSpaces = Math.ceil((niceMax - niceMin) / spacing); + var numSpaces = (niceMax - niceMin) / spacing; + // If very close to our rounded value, use it. + if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) { + numSpaces = Math.round(numSpaces); + } else { + numSpaces = Math.ceil(numSpaces); + } // Put the values into the ticks array this.ticks.push(this.options.ticks.min !== undefined ? this.options.ticks.min : niceMin); diff --git a/test/core.helpers.tests.js b/test/core.helpers.tests.js index 224cc83f2..2d03289ff 100644 --- a/test/core.helpers.tests.js +++ b/test/core.helpers.tests.js @@ -329,6 +329,13 @@ describe('Core helper tests', function() { expect(helpers.log10(1000)).toBeCloseTo(3, 1e-9); }); + it('should correctly determine if two numbers are essentially equal', function() { + expect(helpers.almostEquals(0, Number.EPSILON, 2 * Number.EPSILON)).toBe(true); + expect(helpers.almostEquals(1, 1.1, 0.0001)).toBe(false); + expect(helpers.almostEquals(1e30, 1e30 + Number.EPSILON, 0)).toBe(false); + expect(helpers.almostEquals(1e30, 1e30 + Number.EPSILON, 2 * Number.EPSILON)).toBe(true); + }); + it('Should generate ids', function() { expect(helpers.uid()).toBe('chart-0'); expect(helpers.uid()).toBe('chart-1');