Skip to content

Commit 0f9ea7f

Browse files
committed
Merge pull request #458 from monfera/29-emit-relayout-events-on-3d-camera-reset
Trigger plotly_relayout event when camera is reset to default or saved (Solves #FI29)
2 parents 3180b12 + 57b2650 commit 0f9ea7f

File tree

2 files changed

+67
-14
lines changed

2 files changed

+67
-14
lines changed

src/plots/gl3d/scene.js

+22-13
Original file line numberDiff line numberDiff line change
@@ -559,11 +559,12 @@ proto.destroy = function() {
559559
// for reset camera button in mode bar
560560
proto.setCameraToDefault = function setCameraToDefault() {
561561
// as in Gl3d.layoutAttributes
562-
this.glplot.camera.lookAt(
563-
[1.25, 1.25, 1.25],
564-
[0, 0, 0],
565-
[0, 0, 1]
566-
);
562+
563+
this.setCamera({
564+
eye: { x: 1.25, y: 1.25, z: 1.25 },
565+
center: { x: 0, y: 0, z: 0 },
566+
up: { x: 0, y: 0, z: 1 }
567+
});
567568
};
568569

569570
// get camera position in plotly coords from 'orbit-camera' coords
@@ -583,14 +584,22 @@ proto.getCamera = function getCamera() {
583584

584585
// set camera position with a set of plotly coords
585586
proto.setCamera = function setCamera(cameraData) {
586-
var up = cameraData.up;
587-
var center = cameraData.center;
588-
var eye = cameraData.eye;
589-
this.glplot.camera.lookAt(
590-
[eye.x, eye.y, eye.z],
591-
[center.x, center.y, center.z],
592-
[up.x, up.y, up.z]
593-
);
587+
588+
// getOrbitCamera :: plotly_coords -> orbit_camera_coords
589+
function getOrbitCamera(camera) {
590+
return [
591+
[camera.eye.x, camera.eye.y, camera.eye.z],
592+
[camera.center.x, camera.center.y, camera.center.z],
593+
[camera.up.x, camera.up.y, camera.up.z]
594+
];
595+
}
596+
597+
var update = {};
598+
599+
update[this.id] = cameraData;
600+
601+
this.glplot.camera.lookAt.apply(this, getOrbitCamera(cameraData));
602+
this.graphDiv.emit('plotly_relayout', update);
594603
};
595604

596605
// save camera to user layout (i.e. gd.layout)

test/jasmine/tests/gl_plot_interact_test.js

+45-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ describe('Test gl plot interactions', function() {
229229
});
230230

231231
describe('gl3d modebar click handlers', function() {
232-
var modeBar;
232+
var modeBar, relayoutCallback;
233233

234234
beforeEach(function(done) {
235235
var mockData = [{
@@ -245,8 +245,13 @@ describe('Test gl plot interactions', function() {
245245

246246
gd = createGraphDiv();
247247
Plotly.plot(gd, mockData, mockLayout).then(function() {
248+
248249
modeBar = gd._fullLayout._modeBar;
249250

251+
relayoutCallback = jasmine.createSpy('relayoutCallback');
252+
253+
gd.on('plotly_relayout', relayoutCallback);
254+
250255
delay(done);
251256
});
252257
});
@@ -342,7 +347,26 @@ describe('Test gl plot interactions', function() {
342347
.toEqual({x: 2.5, y: 2.5, z: 2.5});
343348

344349
selectButton(modeBar, 'resetCameraDefault3d').click();
350+
345351
setTimeout(function() {
352+
353+
expect(relayoutCallback).toHaveBeenCalledTimes(2); // initiator: resetCameraDefault3d; 2 scenes
354+
expect(relayoutCallback).toHaveBeenCalledWith({
355+
scene: {
356+
eye: { x: 1.25, y: 1.25, z: 1.25 },
357+
center: { x: 0, y: 0, z: 0 },
358+
up: { x: 0, y: 0, z: 1 }
359+
}
360+
});
361+
expect(relayoutCallback).toHaveBeenCalledWith({
362+
scene2: {
363+
center: { x: 0, y: 0, z: 0 },
364+
eye: { x: 1.25, y: 1.25, z: 1.25 },
365+
up: { x: 0, y: 0, z: 1 }
366+
}
367+
});
368+
relayoutCallback.calls.reset();
369+
346370
expect(sceneLayout.camera.eye)
347371
.toEqual({x: 0.1, y: 0.1, z: 1}, 'does not change the layout objects');
348372
expect(scene.camera.eye)
@@ -353,7 +377,25 @@ describe('Test gl plot interactions', function() {
353377
.toBeCloseToArray([1.25, 1.25, 1.25], 4);
354378

355379
selectButton(modeBar, 'resetCameraLastSave3d').click();
380+
356381
setTimeout(function() {
382+
383+
expect(relayoutCallback).toHaveBeenCalledTimes(2); // initiator: resetCameraLastSave3d; 2 scenes
384+
expect(relayoutCallback).toHaveBeenCalledWith({
385+
scene: {
386+
center: { x: 0, y: 0, z: 0 },
387+
eye: { x: 0.1, y: 0.1, z: 1 },
388+
up: { x: 0, y: 0, z: 1 }
389+
}
390+
});
391+
expect(relayoutCallback).toHaveBeenCalledWith({
392+
scene2: {
393+
center: { x: 0, y: 0, z: 0 },
394+
eye: { x: 2.5, y: 2.5, z: 2.5 },
395+
up: { x: 0, y: 0, z: 1 }
396+
}
397+
});
398+
357399
expect(sceneLayout.camera.eye)
358400
.toEqual({x: 0.1, y: 0.1, z: 1}, 'does not change the layout objects');
359401
expect(scene.camera.eye)
@@ -364,7 +406,9 @@ describe('Test gl plot interactions', function() {
364406
.toBeCloseToArray([2.5, 2.5, 2.5], 4);
365407

366408
done();
409+
367410
}, MODEBAR_DELAY);
411+
368412
}, MODEBAR_DELAY);
369413
});
370414
});

0 commit comments

Comments
 (0)