From ee6d7d86d176e7726251132e94ab222ca21756c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 17 Jan 2017 16:13:00 -0500 Subject: [PATCH 1/3] rm useless Fx.supplyDefaults call in doModeBar subroutine - as the full Plots.supplyDefaults is called before the doModeBar subroutine. --- src/plot_api/subroutines.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plot_api/subroutines.js b/src/plot_api/subroutines.js index 587e014dc60..ca59c157ccf 100644 --- a/src/plot_api/subroutines.js +++ b/src/plot_api/subroutines.js @@ -295,7 +295,6 @@ exports.doModeBar = function(gd) { var subplotIds, i; ModeBar.manage(gd); - Plotly.Fx.supplyLayoutDefaults(gd.layout, gd._fullLayout, gd._fullData); Plotly.Fx.init(gd); subplotIds = Plots.getSubplotIds(fullLayout, 'gl3d'); From ce1cc44e905a8e467c404906247e2ec063d66daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 17 Jan 2017 16:15:21 -0500 Subject: [PATCH 2/3] replace scene2d.updateFx with scene2d.updateRefs - scene2d.updateRefs is now called on scene2d.plot and during Plots.supplyDefaults, ensuring that scene2d.fullLayout is up-to-date with gd._fullLayout. --- src/plot_api/subroutines.js | 7 ++----- src/plots/gl2d/scene2d.js | 23 +++++++---------------- src/plots/plots.js | 4 ++++ 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/plot_api/subroutines.js b/src/plot_api/subroutines.js index ca59c157ccf..64b82fa349e 100644 --- a/src/plot_api/subroutines.js +++ b/src/plot_api/subroutines.js @@ -303,11 +303,8 @@ exports.doModeBar = function(gd) { scene.updateFx(fullLayout.dragmode, fullLayout.hovermode); } - subplotIds = Plots.getSubplotIds(fullLayout, 'gl2d'); - for(i = 0; i < subplotIds.length; i++) { - var scene2d = fullLayout._plots[subplotIds[i]]._scene2d; - scene2d.updateFx(fullLayout); - } + // no need to do this for gl2d subplots, + // Plots.linkSubplots takes care of it all. subplotIds = Plots.getSubplotIds(fullLayout, 'geo'); for(i = 0; i < subplotIds.length; i++) { diff --git a/src/plots/gl2d/scene2d.js b/src/plots/gl2d/scene2d.js index f1207476d5c..3f57d66ea0a 100644 --- a/src/plots/gl2d/scene2d.js +++ b/src/plots/gl2d/scene2d.js @@ -34,9 +34,8 @@ function Scene2D(options, fullLayout) { this.id = options.id; this.staticPlot = !!options.staticPlot; - this.fullLayout = fullLayout; this.fullData = null; - this.updateAxes(fullLayout); + this.updateRefs(fullLayout); this.makeFramework(); @@ -278,22 +277,15 @@ function compareTicks(a, b) { return false; } -proto.updateAxes = function(options) { +proto.updateRefs = function(newFullLayout) { + this.fullLayout = newFullLayout; + var spmatch = Axes.subplotMatch, xaxisName = 'xaxis' + this.id.match(spmatch)[1], yaxisName = 'yaxis' + this.id.match(spmatch)[2]; - this.xaxis = options[xaxisName]; - this.yaxis = options[yaxisName]; -}; - -proto.updateFx = function(options) { - var fullLayout = this.fullLayout; - - fullLayout.dragmode = options.dragmode; - fullLayout.hovermode = options.hovermode; - - this.graphDiv._fullLayout = fullLayout; + this.xaxis = this.fullLayout[xaxisName]; + this.yaxis = this.fullLayout[yaxisName]; }; function relayoutCallback(scene) { @@ -374,8 +366,7 @@ proto.destroy = function() { proto.plot = function(fullData, calcData, fullLayout) { var glplot = this.glplot; - this.fullLayout = fullLayout; - this.updateAxes(fullLayout); + this.updateRefs(fullLayout); this.updateTraces(fullData, calcData); var width = fullLayout.width, diff --git a/src/plots/plots.js b/src/plots/plots.js index a1d853d40ef..149f6612199 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -630,6 +630,10 @@ plots.linkSubplots = function(newFullData, newFullLayout, oldFullData, oldFullLa if(oldSubplot) { plotinfo = newSubplots[id] = oldSubplot; + + if(plotinfo._scene2d) { + plotinfo._scene2d.updateRefs(newFullLayout); + } } else { plotinfo = newSubplots[id] = {}; From c8b53ddcbdbbc884d8896b7b9bbea7d1269f5811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 18 Jan 2017 15:59:16 -0500 Subject: [PATCH 3/3] attach scene2d relayoutCallback onto proto - call after each mouse-change / wheel-change, as opposed to each time the scene2d ticks changed (which didn't cover all the cases) - make sure gl2d pan test `mouseup` to trigger relayoutCallback --- src/plots/gl2d/camera.js | 7 +++++ src/plots/gl2d/scene2d.js | 33 +++++++++++---------- test/jasmine/tests/gl_plot_interact_test.js | 28 ++++++++--------- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/plots/gl2d/camera.js b/src/plots/gl2d/camera.js index eb9240529e2..405795b6b57 100644 --- a/src/plots/gl2d/camera.js +++ b/src/plots/gl2d/camera.js @@ -91,6 +91,7 @@ function createCamera(scene) { updateRange(1, result.boxStart[1], result.boxEnd[1]); unSetAutoRange(); result.boxEnabled = false; + scene.relayoutCallback(); } break; @@ -110,11 +111,16 @@ function createCamera(scene) { scene.setRanges(dataBox); + result.panning = true; result.lastInputTime = Date.now(); unSetAutoRange(); scene.cameraChanged(); scene.handleAnnotations(); } + else if(result.panning) { + result.panning = false; + scene.relayoutCallback(); + } break; } @@ -154,6 +160,7 @@ function createCamera(scene) { unSetAutoRange(); scene.cameraChanged(); scene.handleAnnotations(); + scene.relayoutCallback(); break; } diff --git a/src/plots/gl2d/scene2d.js b/src/plots/gl2d/scene2d.js index 3f57d66ea0a..d86303c29f9 100644 --- a/src/plots/gl2d/scene2d.js +++ b/src/plots/gl2d/scene2d.js @@ -288,27 +288,30 @@ proto.updateRefs = function(newFullLayout) { this.yaxis = this.fullLayout[yaxisName]; }; -function relayoutCallback(scene) { - var xrange = scene.xaxis.range, - yrange = scene.yaxis.range; +proto.relayoutCallback = function() { + var graphDiv = this.graphDiv, + xaxis = this.xaxis, + yaxis = this.yaxis, + layout = graphDiv.layout; - // Update the layout on the DIV - scene.graphDiv.layout.xaxis.autorange = scene.xaxis.autorange; - scene.graphDiv.layout.xaxis.range = xrange.slice(0); - scene.graphDiv.layout.yaxis.autorange = scene.yaxis.autorange; - scene.graphDiv.layout.yaxis.range = yrange.slice(0); + // update user layout + layout.xaxis.autorange = xaxis.autorange; + layout.xaxis.range = xaxis.range.slice(0); + layout.yaxis.autorange = yaxis.autorange; + layout.yaxis.range = yaxis.range.slice(0); - // Make a meaningful value to be passed on to the possible 'plotly_relayout' subscriber(s) + // make a meaningful value to be passed on to the possible 'plotly_relayout' subscriber(s) // scene.camera has no many useful projection or scale information // helps determine which one is the latest input (if async) var update = { - lastInputTime: scene.camera.lastInputTime + lastInputTime: this.camera.lastInputTime }; - update[scene.xaxis._name] = xrange.slice(); - update[scene.yaxis._name] = yrange.slice(); - scene.graphDiv.emit('plotly_relayout', update); -} + update[xaxis._name] = xaxis.range.slice(0); + update[yaxis._name] = yaxis.range.slice(0); + + graphDiv.emit('plotly_relayout', update); +}; proto.cameraChanged = function() { var camera = this.camera; @@ -323,8 +326,6 @@ proto.cameraChanged = function() { this.glplotOptions.dataBox = camera.dataBox; this.glplot.update(this.glplotOptions); this.handleAnnotations(); - - relayoutCallback(this); } }; diff --git a/test/jasmine/tests/gl_plot_interact_test.js b/test/jasmine/tests/gl_plot_interact_test.js index 379d8f5809c..f3fae5d0b6c 100644 --- a/test/jasmine/tests/gl_plot_interact_test.js +++ b/test/jasmine/tests/gl_plot_interact_test.js @@ -236,6 +236,13 @@ describe('Test gl plot interactions', function() { it('should respond to drag interactions', function(done) { + function mouseTo(p0, p1) { + mouseEvent('mousemove', p0[0], p0[1]); + mouseEvent('mousedown', p0[0], p0[1], { buttons: 1 }); + mouseEvent('mousemove', p1[0], p1[1], { buttons: 1 }); + mouseEvent('mouseup', p1[0], p1[1]); + } + jasmine.addMatchers(customMatchers); var precision = 5; @@ -263,14 +270,10 @@ describe('Test gl plot interactions', function() { expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision); setTimeout(function() { - - mouseEvent('mousemove', 200, 200); - relayoutCallback.calls.reset(); // Drag scene along the X axis - - mouseEvent('mousemove', 220, 200, {buttons: 1}); + mouseTo([200, 200], [220, 200]); expect(gd.layout.xaxis.autorange).toBe(false); expect(gd.layout.yaxis.autorange).toBe(false); @@ -279,36 +282,31 @@ describe('Test gl plot interactions', function() { expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision); // Drag scene back along the X axis - - mouseEvent('mousemove', 200, 200, {buttons: 1}); + mouseTo([220, 200], [200, 200]); expect(gd.layout.xaxis.range).toBeCloseToArray(originalX, precision); expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision); // Drag scene along the Y axis - - mouseEvent('mousemove', 200, 150, {buttons: 1}); + mouseTo([200, 200], [200, 150]); expect(gd.layout.xaxis.range).toBeCloseToArray(originalX, precision); expect(gd.layout.yaxis.range).toBeCloseToArray(newY, precision); // Drag scene back along the Y axis - - mouseEvent('mousemove', 200, 200, {buttons: 1}); + mouseTo([200, 150], [200, 200]); expect(gd.layout.xaxis.range).toBeCloseToArray(originalX, precision); expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision); // Drag scene along both the X and Y axis - - mouseEvent('mousemove', 220, 150, {buttons: 1}); + mouseTo([200, 200], [220, 150]); expect(gd.layout.xaxis.range).toBeCloseToArray(newX, precision); expect(gd.layout.yaxis.range).toBeCloseToArray(newY, precision); // Drag scene back along the X and Y axis - - mouseEvent('mousemove', 200, 200, {buttons: 1}); + mouseTo([220, 150], [200, 200]); expect(gd.layout.xaxis.range).toBeCloseToArray(originalX, precision); expect(gd.layout.yaxis.range).toBeCloseToArray(originalY, precision);