From d6037c0f5fb576fbaff304927c96d7100227cdcf Mon Sep 17 00:00:00 2001 From: Robert Monfera Date: Thu, 21 Apr 2016 11:49:54 +0200 Subject: [PATCH 1/4] #29 add plotly_relayout event emission when camera is reset to default or saved --- src/plots/gl3d/scene.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index feaccfbdc56..21f9db4d474 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -559,11 +559,13 @@ proto.destroy = function() { // for reset camera button in mode bar proto.setCameraToDefault = function setCameraToDefault() { // as in Gl3d.layoutAttributes - this.glplot.camera.lookAt( + var lookAtInput = [ [1.25, 1.25, 1.25], [0, 0, 0], [0, 0, 1] - ); + ]; + this.glplot.camera.lookAt.apply(this, lookAtInput); + this.graphDiv.emit('plotly_relayout', lookAtInput); }; // get camera position in plotly coords from 'orbit-camera' coords @@ -586,11 +588,13 @@ proto.setCamera = function setCamera(cameraData) { var up = cameraData.up; var center = cameraData.center; var eye = cameraData.eye; - this.glplot.camera.lookAt( + var lookAtInput = [ [eye.x, eye.y, eye.z], [center.x, center.y, center.z], [up.x, up.y, up.z] - ); + ]; + this.glplot.camera.lookAt.apply(this, lookAtInput); + this.graphDiv.emit('plotly_relayout', lookAtInput); }; // save camera to user layout (i.e. gd.layout) From 8dedb6e58e3db51415b6537e0758c337052a61d2 Mon Sep 17 00:00:00 2001 From: Robert Monfera Date: Thu, 21 Apr 2016 16:17:57 +0200 Subject: [PATCH 2/4] #29 add test cases (they're in the CI excluded file but they pass fine locally with fdescribe) --- test/jasmine/tests/gl_plot_interact_test.js | 27 ++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/test/jasmine/tests/gl_plot_interact_test.js b/test/jasmine/tests/gl_plot_interact_test.js index d0fa3ddd278..a8a97524705 100644 --- a/test/jasmine/tests/gl_plot_interact_test.js +++ b/test/jasmine/tests/gl_plot_interact_test.js @@ -229,7 +229,7 @@ describe('Test gl plot interactions', function() { }); describe('gl3d modebar click handlers', function() { - var modeBar; + var modeBar, relayoutCallback; beforeEach(function(done) { var mockData = [{ @@ -245,8 +245,13 @@ describe('Test gl plot interactions', function() { gd = createGraphDiv(); Plotly.plot(gd, mockData, mockLayout).then(function() { + modeBar = gd._fullLayout._modeBar; + relayoutCallback = jasmine.createSpy('relayoutCallback'); + + gd.on('plotly_relayout', relayoutCallback); + delay(done); }); }); @@ -342,7 +347,16 @@ describe('Test gl plot interactions', function() { .toEqual({x: 2.5, y: 2.5, z: 2.5}); selectButton(modeBar, 'resetCameraDefault3d').click(); + setTimeout(function() { + + expect(relayoutCallback).toHaveBeenCalled(); // initiator: resetCameraDefault3d + expect(relayoutCallback).toHaveBeenCalledWith([ + [1.25, 1.25, 1.25], + [0, 0, 0], + [0, 0, 1] + ]); + expect(sceneLayout.camera.eye) .toEqual({x: 0.1, y: 0.1, z: 1}, 'does not change the layout objects'); expect(scene.camera.eye) @@ -353,7 +367,16 @@ describe('Test gl plot interactions', function() { .toBeCloseToArray([1.25, 1.25, 1.25], 4); selectButton(modeBar, 'resetCameraLastSave3d').click(); + setTimeout(function() { + + expect(relayoutCallback).toHaveBeenCalled(); // initiator: resetCameraLastSave3d + expect(relayoutCallback).toHaveBeenCalledWith([ + [1.25, 1.25, 1.25], + [0, 0, 0], + [0, 0, 1] + ]); // looks like there's no real saved data so it reverts to default + expect(sceneLayout.camera.eye) .toEqual({x: 0.1, y: 0.1, z: 1}, 'does not change the layout objects'); expect(scene.camera.eye) @@ -364,7 +387,9 @@ describe('Test gl plot interactions', function() { .toBeCloseToArray([2.5, 2.5, 2.5], 4); done(); + }, MODEBAR_DELAY); + }, MODEBAR_DELAY); }); }); From ff1d418a79737c2e94464f6d005fbd62a9108b58 Mon Sep 17 00:00:00 2001 From: Robert Monfera Date: Thu, 21 Apr 2016 17:51:17 +0200 Subject: [PATCH 3/4] #29 different camera format, and ensuing code unification --- src/plots/gl3d/scene.js | 39 ++++++++++++--------- test/jasmine/tests/gl_plot_interact_test.js | 24 +++++++------ 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 21f9db4d474..bf054ecefb9 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -559,13 +559,12 @@ proto.destroy = function() { // for reset camera button in mode bar proto.setCameraToDefault = function setCameraToDefault() { // as in Gl3d.layoutAttributes - var lookAtInput = [ - [1.25, 1.25, 1.25], - [0, 0, 0], - [0, 0, 1] - ]; - this.glplot.camera.lookAt.apply(this, lookAtInput); - this.graphDiv.emit('plotly_relayout', lookAtInput); + + this.setCamera({ + eye: { x: 1.25, y: 1.25, z: 1.25 }, + center: { x: 0, y: 0, z: 0 }, + up: { x: 0, y: 0, z: 1 } + }); }; // get camera position in plotly coords from 'orbit-camera' coords @@ -585,16 +584,22 @@ proto.getCamera = function getCamera() { // set camera position with a set of plotly coords proto.setCamera = function setCamera(cameraData) { - var up = cameraData.up; - var center = cameraData.center; - var eye = cameraData.eye; - var lookAtInput = [ - [eye.x, eye.y, eye.z], - [center.x, center.y, center.z], - [up.x, up.y, up.z] - ]; - this.glplot.camera.lookAt.apply(this, lookAtInput); - this.graphDiv.emit('plotly_relayout', lookAtInput); + + // getOrbitCamera :: plotly_coords -> orbit_camera_coords + function getOrbitCamera(camera) { + return [ + [camera.eye.x, camera.eye.y, camera.eye.z], + [camera.center.x, camera.center.y, camera.center.z], + [camera.up.x, camera.up.y, camera.up.z] + ]; + } + + var update = {}; + + update[this.id] = cameraData; + + this.glplot.camera.lookAt.apply(this, getOrbitCamera(cameraData)); + this.graphDiv.emit('plotly_relayout', update); }; // save camera to user layout (i.e. gd.layout) diff --git a/test/jasmine/tests/gl_plot_interact_test.js b/test/jasmine/tests/gl_plot_interact_test.js index a8a97524705..696ecaa5f66 100644 --- a/test/jasmine/tests/gl_plot_interact_test.js +++ b/test/jasmine/tests/gl_plot_interact_test.js @@ -351,11 +351,13 @@ describe('Test gl plot interactions', function() { setTimeout(function() { expect(relayoutCallback).toHaveBeenCalled(); // initiator: resetCameraDefault3d - expect(relayoutCallback).toHaveBeenCalledWith([ - [1.25, 1.25, 1.25], - [0, 0, 0], - [0, 0, 1] - ]); + expect(relayoutCallback).toHaveBeenCalledWith({ + scene: { + eye: { x: 1.25, y: 1.25, z: 1.25 }, + center: { x: 0, y: 0, z: 0 }, + up: { x: 0, y: 0, z: 1 } + } + }); expect(sceneLayout.camera.eye) .toEqual({x: 0.1, y: 0.1, z: 1}, 'does not change the layout objects'); @@ -371,11 +373,13 @@ describe('Test gl plot interactions', function() { setTimeout(function() { expect(relayoutCallback).toHaveBeenCalled(); // initiator: resetCameraLastSave3d - expect(relayoutCallback).toHaveBeenCalledWith([ - [1.25, 1.25, 1.25], - [0, 0, 0], - [0, 0, 1] - ]); // looks like there's no real saved data so it reverts to default + expect(relayoutCallback).toHaveBeenCalledWith({ + scene: { + eye: { x: 1.25, y: 1.25, z: 1.25 }, + center: { x: 0, y: 0, z: 0 }, + up: { x: 0, y: 0, z: 1 } + } + }); // looks like there's no real saved data so it reverts to default expect(sceneLayout.camera.eye) .toEqual({x: 0.1, y: 0.1, z: 1}, 'does not change the layout objects'); From 57b26504d8801332c2563762a7b9ca5bad619339 Mon Sep 17 00:00:00 2001 From: Robert Monfera Date: Thu, 21 Apr 2016 22:01:17 +0200 Subject: [PATCH 4/4] #29 ensure one call per scene, checking against correct callback argument values --- test/jasmine/tests/gl_plot_interact_test.js | 23 +++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/test/jasmine/tests/gl_plot_interact_test.js b/test/jasmine/tests/gl_plot_interact_test.js index 696ecaa5f66..f59a84f3875 100644 --- a/test/jasmine/tests/gl_plot_interact_test.js +++ b/test/jasmine/tests/gl_plot_interact_test.js @@ -350,7 +350,7 @@ describe('Test gl plot interactions', function() { setTimeout(function() { - expect(relayoutCallback).toHaveBeenCalled(); // initiator: resetCameraDefault3d + expect(relayoutCallback).toHaveBeenCalledTimes(2); // initiator: resetCameraDefault3d; 2 scenes expect(relayoutCallback).toHaveBeenCalledWith({ scene: { eye: { x: 1.25, y: 1.25, z: 1.25 }, @@ -358,6 +358,14 @@ describe('Test gl plot interactions', function() { up: { x: 0, y: 0, z: 1 } } }); + expect(relayoutCallback).toHaveBeenCalledWith({ + scene2: { + center: { x: 0, y: 0, z: 0 }, + eye: { x: 1.25, y: 1.25, z: 1.25 }, + up: { x: 0, y: 0, z: 1 } + } + }); + relayoutCallback.calls.reset(); expect(sceneLayout.camera.eye) .toEqual({x: 0.1, y: 0.1, z: 1}, 'does not change the layout objects'); @@ -372,14 +380,21 @@ describe('Test gl plot interactions', function() { setTimeout(function() { - expect(relayoutCallback).toHaveBeenCalled(); // initiator: resetCameraLastSave3d + expect(relayoutCallback).toHaveBeenCalledTimes(2); // initiator: resetCameraLastSave3d; 2 scenes expect(relayoutCallback).toHaveBeenCalledWith({ scene: { - eye: { x: 1.25, y: 1.25, z: 1.25 }, center: { x: 0, y: 0, z: 0 }, + eye: { x: 0.1, y: 0.1, z: 1 }, + up: { x: 0, y: 0, z: 1 } + } + }); + expect(relayoutCallback).toHaveBeenCalledWith({ + scene2: { + center: { x: 0, y: 0, z: 0 }, + eye: { x: 2.5, y: 2.5, z: 2.5 }, up: { x: 0, y: 0, z: 1 } } - }); // looks like there's no real saved data so it reverts to default + }); expect(sceneLayout.camera.eye) .toEqual({x: 0.1, y: 0.1, z: 1}, 'does not change the layout objects');