From 775bb3dc6ea21ea006c5db7ac35ba55fa2cd2791 Mon Sep 17 00:00:00 2001 From: J Copperfield Date: Mon, 13 Nov 2017 20:41:56 +0100 Subject: [PATCH 1/5] Fix issue 4928 - linear tick generator doesn't round values to needed precision. --- src/core/core.ticks.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/core.ticks.js b/src/core/core.ticks.js index 2dbc27474d4..2924885c53f 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.toPrecision().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(niceMin + Math.round(j * spacing * precision) / precision); } ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax); From c3b8dd3f662e1133725cb32fc050840e07a0481a Mon Sep 17 00:00:00 2001 From: J Copperfield Date: Tue, 14 Nov 2017 07:28:46 +0100 Subject: [PATCH 2/5] Improve: replace toPrecision() in toString() to improve readability. --- src/core/core.ticks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.ticks.js b/src/core/core.ticks.js index 2924885c53f..0473af26675 100644 --- a/src/core/core.ticks.js +++ b/src/core/core.ticks.js @@ -82,7 +82,7 @@ module.exports = { var precision = 1; if (spacing < 1) { - precision = Math.pow(10, spacing.toPrecision().length - 2); + precision = Math.pow(10, spacing.toString().length - 2); niceMin = Math.round(niceMin * precision) / precision; niceMax = Math.round(niceMax * precision) / precision; } From ad984be0a71451e865e25397fcbb33e111203f28 Mon Sep 17 00:00:00 2001 From: J Copperfield Date: Tue, 14 Nov 2017 08:38:23 +0100 Subject: [PATCH 3/5] Fix: logarithmic tick generator doesn't round values to needed precision. --- src/core/core.ticks.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/core.ticks.js b/src/core/core.ticks.js index 0473af26675..370fe099f6d 100644 --- a/src/core/core.ticks.js +++ b/src/core/core.ticks.js @@ -126,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); @@ -134,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); From 37bfadbc0220c930c296b673b82783929e70b5f4 Mon Sep 17 00:00:00 2001 From: J Copperfield Date: Tue, 14 Nov 2017 09:53:25 +0100 Subject: [PATCH 4/5] Fix: rounding tick values didn't work for negative values. --- src/core/core.ticks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.ticks.js b/src/core/core.ticks.js index 370fe099f6d..655369a17c8 100644 --- a/src/core/core.ticks.js +++ b/src/core/core.ticks.js @@ -88,7 +88,7 @@ module.exports = { } ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin); for (var j = 1; j < numSpaces; ++j) { - ticks.push(niceMin + Math.round(j * spacing * precision) / precision); + ticks.push(Math.round((niceMin + j * spacing) * precision) / precision); } ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax); From 9466cb575dde3af170ec51ab611ce2e99f9c7be9 Mon Sep 17 00:00:00 2001 From: J Copperfield Date: Tue, 14 Nov 2017 16:45:39 +0100 Subject: [PATCH 5/5] Add: Core ticks tests --- test/specs/core.ticks.tests.js | 87 ++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 test/specs/core.ticks.tests.js 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']); + }); +});