From 71e61eecc60661f7c47a18ec009f135b854b68a3 Mon Sep 17 00:00:00 2001 From: jcopperfield <33193571+jcopperfield@users.noreply.github.com> Date: Sat, 2 Dec 2017 15:24:57 +0100 Subject: [PATCH] Fix issue #4928: linear tick generator doesn't round values to needed precision. (#4943) * Fix issue 4928 - linear tick generator doesn't round values to needed precision. * Improve: replace toPrecision() in toString() to improve readability. * Fix: logarithmic tick generator doesn't round values to needed precision. * Fix: rounding tick values didn't work for negative values. * Add: Core ticks tests --- src/core/core.ticks.js | 13 +++-- test/specs/core.ticks.tests.js | 87 ++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 test/specs/core.ticks.tests.js diff --git a/src/core/core.ticks.js b/src/core/core.ticks.js index 2dbc27474d4..655369a17c8 100644 --- a/src/core/core.ticks.js +++ b/src/core/core.ticks.js @@ -80,10 +80,15 @@ module.exports = { numSpaces = Math.ceil(numSpaces); } - // Put the values into the ticks array + var precision = 1; + if (spacing < 1) { + precision = Math.pow(10, spacing.toString().length - 2); + niceMin = Math.round(niceMin * precision) / precision; + niceMax = Math.round(niceMax * precision) / precision; + } ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin); for (var j = 1; j < numSpaces; ++j) { - ticks.push(niceMin + (j * spacing)); + ticks.push(Math.round((niceMin + j * spacing) * precision) / precision); } ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax); @@ -121,6 +126,7 @@ module.exports = { exp = Math.floor(helpers.log10(tickVal)); significand = Math.floor(tickVal / Math.pow(10, exp)); } + var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1; do { ticks.push(tickVal); @@ -129,9 +135,10 @@ module.exports = { if (significand === 10) { significand = 1; ++exp; + precision = exp >= 0 ? 1 : precision; } - tickVal = significand * Math.pow(10, exp); + tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision; } while (exp < endExp || (exp === endExp && significand < endSignificand)); var lastTick = valueOrDefault(generationOptions.max, tickVal); diff --git a/test/specs/core.ticks.tests.js b/test/specs/core.ticks.tests.js new file mode 100644 index 00000000000..6d7c2b3c111 --- /dev/null +++ b/test/specs/core.ticks.tests.js @@ -0,0 +1,87 @@ +describe('Test tick generators', function() { + it('Should generate linear spaced ticks with correct precision', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + data: [] + }], + }, + options: { + legend: { + display: false, + }, + scales: { + xAxes: [{ + type: 'linear', + position: 'bottom', + ticks: { + callback: function(value) { + return value.toString(); + } + } + }], + yAxes: [{ + type: 'linear', + ticks: { + callback: function(value) { + return value.toString(); + } + } + }] + } + } + }); + + var xAxis = chart.scales['x-axis-0']; + var yAxis = chart.scales['y-axis-0']; + + expect(xAxis.ticks).toEqual(['-1', '-0.8', '-0.6', '-0.4', '-0.2', '0', '0.2', '0.4', '0.6', '0.8', '1']); + expect(yAxis.ticks).toEqual(['1', '0.8', '0.6', '0.4', '0.2', '0', '-0.2', '-0.4', '-0.6', '-0.8', '-1']); + }); + + it('Should generate logarithmic spaced ticks with correct precision', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + data: [] + }], + }, + options: { + legend: { + display: false, + }, + scales: { + xAxes: [{ + type: 'logarithmic', + position: 'bottom', + ticks: { + min: 0.1, + max: 1, + callback: function(value) { + return value.toString(); + } + } + }], + yAxes: [{ + type: 'logarithmic', + ticks: { + min: 0.1, + max: 1, + callback: function(value) { + return value.toString(); + } + } + }] + } + } + }); + + var xAxis = chart.scales['x-axis-0']; + var yAxis = chart.scales['y-axis-0']; + + expect(xAxis.ticks).toEqual(['0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']); + expect(yAxis.ticks).toEqual(['1', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1']); + }); +});