From d7de2ae6b0d11fe0d47af7c6a08d028d72b761ab Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Thu, 17 Nov 2016 15:25:00 +0100 Subject: [PATCH 1/5] issue #1160 fix If we play with timestamps, we have to leave range bounds integers --- src/components/modebar/buttons.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index 7536885207f..e487098b1f6 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -205,8 +205,8 @@ function handleCartesian(gd, ev) { } else { var rangeNow = ax.range; - aobj[axName + '.range[0]'] = r0 * rangeNow[0] + r1 * rangeNow[1]; - aobj[axName + '.range[1]'] = r0 * rangeNow[1] + r1 * rangeNow[0]; + aobj[axName + '.range[0]'] = Math.floor(r0 * rangeNow[0] + r1 * rangeNow[1]); + aobj[axName + '.range[1]'] = Math.floor(r0 * rangeNow[1] + r1 * rangeNow[0]); } } } From 665e56c6ad865161ac5dcbce6f6742951fd100f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Thu, 17 Nov 2016 11:41:01 -0500 Subject: [PATCH 2/5] modebar: use axis r21 and l2r to compute zoom +/- ranges - so that zoomed ranges are computed consistently for all axis types --- src/components/modebar/buttons.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index e487098b1f6..064d02e9fe5 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -204,9 +204,18 @@ function handleCartesian(gd, ev) { } } else { - var rangeNow = ax.range; - aobj[axName + '.range[0]'] = Math.floor(r0 * rangeNow[0] + r1 * rangeNow[1]); - aobj[axName + '.range[1]'] = Math.floor(r0 * rangeNow[1] + r1 * rangeNow[0]); + var rangeNow = [ + ax.r2l(ax.range[0]), + ax.r2l(ax.range[1]), + ]; + + var rangeNew = [ + r0 * rangeNow[0] + r1 * rangeNow[1], + r0 * rangeNow[1] + r1 * rangeNow[0] + ]; + + aobj[axName + '.range[0]'] = ax.l2r(rangeNew[0]); + aobj[axName + '.range[1]'] = ax.l2r(rangeNew[1]); } } } From 8e9d4581bf24ec30d53fbc2ba44590d7e0d4fab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Thu, 17 Nov 2016 11:41:36 -0500 Subject: [PATCH 3/5] test: test all cartesian axis types in modebar click cases --- test/jasmine/tests/modebar_test.js | 66 ++++++++++++++++++------------ 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/test/jasmine/tests/modebar_test.js b/test/jasmine/tests/modebar_test.js index 047312179de..f4c2e82e605 100644 --- a/test/jasmine/tests/modebar_test.js +++ b/test/jasmine/tests/modebar_test.js @@ -1,7 +1,9 @@ var d3 = require('d3'); +var isNumeric = require('fast-isnumeric'); var createModeBar = require('@src/components/modebar/modebar'); var manageModeBar = require('@src/components/modebar/manage'); +var customMatchers = require('../assets/custom_matchers'); var Plotly = require('@lib/index'); var Plots = require('@src/plots/plots'); @@ -613,12 +615,21 @@ describe('ModeBar', function() { describe('modebar on clicks', function() { var gd, modeBar; + beforeAll(function() { + jasmine.addMatchers(customMatchers); + }); + afterEach(destroyGraphDiv); - function assertRange(actual, expected) { + function assertRange(axName, expected) { var PRECISION = 2; - expect(actual[0]).toBeCloseTo(expected[0], PRECISION); - expect(actual[1]).toBeCloseTo(expected[1], PRECISION); + + var actual = gd._fullLayout[axName].range; + + if(isNumeric(expected[0])) { + expect(actual).toBeCloseToArray(expected, PRECISION, axName); + } + else expect(actual).toEqual(expected, axName); } function assertActive(buttons, activeButton) { @@ -634,9 +645,11 @@ describe('ModeBar', function() { beforeEach(function(done) { var mockData = [{ type: 'scatter', - y: [2, 1, 2] + x: ['2016-01-01', '2016-02-01', '2016-03-01'], + y: [10, 100, 1000], }, { type: 'bar', + x: ['a', 'b', 'c'], y: [2, 1, 2], xaxis: 'x2', yaxis: 'y2' @@ -646,11 +659,12 @@ describe('ModeBar', function() { xaxis: { anchor: 'y', domain: [0, 0.5], - range: [0, 5] + range: ['2016-01-01', '2016-04-01'] }, yaxis: { anchor: 'x', - range: [0, 3] + type: 'log', + range: [1, 3] }, xaxis2: { anchor: 'y2', @@ -679,35 +693,35 @@ describe('ModeBar', function() { buttonAutoScale = selectButton(modeBar, 'autoScale2d'), buttonResetScale = selectButton(modeBar, 'resetScale2d'); - assertRange(gd._fullLayout.xaxis.range, [0, 5]); - assertRange(gd._fullLayout.yaxis.range, [0, 3]); - assertRange(gd._fullLayout.xaxis2.range, [-1, 4]); - assertRange(gd._fullLayout.yaxis2.range, [0, 4]); + assertRange('xaxis', ['2016-01-01', '2016-04-01']); + assertRange('yaxis', [1, 3]); + assertRange('xaxis2', [-1, 4]); + assertRange('yaxis2', [0, 4]); buttonZoomIn.click(); - assertRange(gd._fullLayout.xaxis.range, [1.25, 3.75]); - assertRange(gd._fullLayout.yaxis.range, [0.75, 2.25]); - assertRange(gd._fullLayout.xaxis2.range, [0.25, 2.75]); - assertRange(gd._fullLayout.yaxis2.range, [1, 3]); + assertRange('xaxis', ['2016-01-23 17:45', '2016-03-09 05:15']); + assertRange('yaxis', [1.5, 2.5]); + assertRange('xaxis2', [0.25, 2.75]); + assertRange('yaxis2', [1, 3]); buttonZoomOut.click(); - assertRange(gd._fullLayout.xaxis.range, [0, 5]); - assertRange(gd._fullLayout.yaxis.range, [0, 3]); - assertRange(gd._fullLayout.xaxis2.range, [-1, 4]); - assertRange(gd._fullLayout.yaxis2.range, [0, 4]); + assertRange('xaxis', ['2016-01-01', '2016-04-01']); + assertRange('yaxis', [1, 3]); + assertRange('xaxis2', [-1, 4]); + assertRange('yaxis2', [0, 4]); buttonZoomIn.click(); buttonAutoScale.click(); - assertRange(gd._fullLayout.xaxis.range, [-0.1584327, 2.1584327]); - assertRange(gd._fullLayout.yaxis.range, [0.92675159, 2.073248]); - assertRange(gd._fullLayout.xaxis2.range, [-0.5, 2.5]); - assertRange(gd._fullLayout.yaxis2.range, [0, 2.105263]); + assertRange('xaxis', ['2015-12-27 06:36:39.6661', '2016-03-05 17:23:20.3339']); + assertRange('yaxis', [0.8591, 3.1408]); + assertRange('xaxis2', [-0.5, 2.5]); + assertRange('yaxis2', [0, 2.105263]); buttonResetScale.click(); - assertRange(gd._fullLayout.xaxis.range, [0, 5]); - assertRange(gd._fullLayout.yaxis.range, [0, 3]); - assertRange(gd._fullLayout.xaxis2.range, [-1, 4]); - assertRange(gd._fullLayout.yaxis2.range, [0, 4]); + assertRange('xaxis', ['2016-01-01', '2016-04-01']); + assertRange('yaxis', [1, 3]); + assertRange('xaxis2', [-1, 4]); + assertRange('yaxis2', [0, 4]); }); }); From c45338dc12c6c6ac6a1ba32cc60cb7de7c4fb91d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Thu, 17 Nov 2016 12:07:42 -0500 Subject: [PATCH 4/5] test: use ax.r2l to assert range - so that date axis ranges can be tested with some tolerance --- test/jasmine/tests/modebar_test.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/jasmine/tests/modebar_test.js b/test/jasmine/tests/modebar_test.js index f4c2e82e605..92166b3a824 100644 --- a/test/jasmine/tests/modebar_test.js +++ b/test/jasmine/tests/modebar_test.js @@ -1,5 +1,4 @@ var d3 = require('d3'); -var isNumeric = require('fast-isnumeric'); var createModeBar = require('@src/components/modebar/modebar'); var manageModeBar = require('@src/components/modebar/manage'); @@ -624,12 +623,10 @@ describe('ModeBar', function() { function assertRange(axName, expected) { var PRECISION = 2; - var actual = gd._fullLayout[axName].range; + var ax = gd._fullLayout[axName]; + var actual = ax.range.map(ax.r2l); - if(isNumeric(expected[0])) { - expect(actual).toBeCloseToArray(expected, PRECISION, axName); - } - else expect(actual).toEqual(expected, axName); + expect(actual).toBeCloseToArray(expected.map(ax.r2l), PRECISION, axName); } function assertActive(buttons, activeButton) { From f1b686f7ebfc4a77121854f207fe26562b1b2bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Thu, 17 Nov 2016 14:58:35 -0500 Subject: [PATCH 5/5] test: assert up to yyyy-mm-dd for date ranges - looks like the CI machine has less precision than my laptop --- test/jasmine/tests/modebar_test.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/jasmine/tests/modebar_test.js b/test/jasmine/tests/modebar_test.js index 92166b3a824..b3be9a51b43 100644 --- a/test/jasmine/tests/modebar_test.js +++ b/test/jasmine/tests/modebar_test.js @@ -624,9 +624,15 @@ describe('ModeBar', function() { var PRECISION = 2; var ax = gd._fullLayout[axName]; - var actual = ax.range.map(ax.r2l); + var actual = ax.range; - expect(actual).toBeCloseToArray(expected.map(ax.r2l), PRECISION, axName); + if(ax.type === 'date') { + var truncate = function(v) { return v.substr(0, 10); }; + expect(actual.map(truncate)).toEqual(expected.map(truncate), axName); + } + else { + expect(actual).toBeCloseToArray(expected, PRECISION, axName); + } } function assertActive(buttons, activeButton) {