Skip to content

Commit 15d75db

Browse files
authored
Merge pull request #4579 from plotly/include-aspectmode-in-relayout
Include gl3d scene.aspectmode changes in relayout updates
2 parents 0e444b6 + c730f12 commit 15d75db

File tree

3 files changed

+71
-8
lines changed

3 files changed

+71
-8
lines changed

src/components/modebar/buttons.js

+2
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ function handleCamera3d(gd, ev) {
346346
var sceneId = sceneIds[i];
347347
var camera = sceneId + '.camera';
348348
var aspectratio = sceneId + '.aspectratio';
349+
var aspectmode = sceneId + '.aspectmode';
349350
var scene = fullLayout[sceneId]._scene;
350351
var didUpdate;
351352

@@ -365,6 +366,7 @@ function handleCamera3d(gd, ev) {
365366
aobj[aspectratio + '.x'] = scene.viewInitial.aspectratio.x;
366367
aobj[aspectratio + '.y'] = scene.viewInitial.aspectratio.y;
367368
aobj[aspectratio + '.z'] = scene.viewInitial.aspectratio.z;
369+
aobj[aspectmode] = scene.viewInitial.aspectmode;
368370
}
369371
}
370372

src/plots/gl3d/scene.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ proto.tryCreatePlot = function() {
155155
'webgl setup failed possibly due to',
156156
isMobile ? 'disabling' : 'enabling',
157157
'preserveDrawingBuffer config.',
158-
'The device may not be supported by isMobile module!',
158+
'The device may not be supported by is-mobile module!',
159159
'Inverting preserveDrawingBuffer option in second attempt to create webgl scene.'
160160
].join(' '));
161161
isMobile = opts.glOptions.preserveDrawingBuffer = !opts.glOptions.preserveDrawingBuffer;
@@ -219,6 +219,12 @@ proto.initializeGLPlot = function() {
219219
if(scene.isAspectChanged(layout)) {
220220
// scene updates
221221
update[scene.id + '.aspectratio'] = scene.glplot.getAspectratio();
222+
223+
if(layout[scene.id].aspectmode !== 'manual') {
224+
scene.fullSceneLayout.aspectmode =
225+
layout[scene.id].aspectmode =
226+
update[scene.id + '.aspectmode'] = 'manual';
227+
}
222228
}
223229

224230
return update;
@@ -246,7 +252,6 @@ proto.initializeGLPlot = function() {
246252
y: s * o.y,
247253
z: s * o.z
248254
});
249-
scene.fullSceneLayout.aspectmode = layout[scene.id].aspectmode = 'manual';
250255
}
251256

252257
relayoutCallback(scene);
@@ -778,14 +783,17 @@ proto.plot = function(sceneData, fullLayout, layout) {
778783
*/
779784
scene.glplot.setAspectratio(fullSceneLayout.aspectratio);
780785

781-
// save 'initial' camera view settings for modebar button
786+
// save 'initial' aspectratio & aspectmode view settings for modebar buttons
782787
if(!scene.viewInitial.aspectratio) {
783788
scene.viewInitial.aspectratio = {
784789
x: fullSceneLayout.aspectratio.x,
785790
y: fullSceneLayout.aspectratio.y,
786791
z: fullSceneLayout.aspectratio.z
787792
};
788793
}
794+
if(!scene.viewInitial.aspectmode) {
795+
scene.viewInitial.aspectmode = fullSceneLayout.aspectmode;
796+
}
789797

790798
// Update frame position for multi plots
791799
var domain = fullSceneLayout.domain || null;

test/jasmine/tests/gl3d_plot_interact_test.js

+58-5
Original file line numberDiff line numberDiff line change
@@ -575,13 +575,19 @@ describe('Test gl3d modebar handlers - perspective case', function() {
575575
buttonDefault.click();
576576
});
577577

578-
it('@gl button resetCameraDefault3d should reset to initial aspectratios', function(done) {
578+
it('@gl button resetCameraDefault3d should reset to initial aspectmode & aspectratios', function(done) {
579579
var buttonDefault = selectButton(modeBar, 'resetCameraDefault3d');
580580

581+
expect(gd._fullLayout.scene._scene.viewInitial.aspectmode).toEqual('auto');
582+
expect(gd._fullLayout.scene2._scene.viewInitial.aspectmode).toEqual('manual');
583+
581584
expect(gd._fullLayout.scene._scene.viewInitial.aspectratio).toEqual({ x: 1, y: 1, z: 1 });
582585
expect(gd._fullLayout.scene2._scene.viewInitial.aspectratio).toEqual({ x: 3, y: 2, z: 1 });
583586

584587
gd.once('plotly_relayout', function() {
588+
expect(gd._fullLayout.scene._scene.fullSceneLayout.aspectmode).toBe('auto');
589+
expect(gd._fullLayout.scene2._scene.fullSceneLayout.aspectmode).toBe('manual');
590+
585591
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().x).toBeCloseTo(1);
586592
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().y).toBeCloseTo(1);
587593
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().z).toBeCloseTo(1);
@@ -595,9 +601,12 @@ describe('Test gl3d modebar handlers - perspective case', function() {
595601
buttonDefault.click();
596602
});
597603

598-
it('@gl button resetCameraLastSave3d should reset to initial aspectratios', function(done) {
604+
it('@gl button resetCameraLastSave3d should reset to initial aspectmode & aspectratios', function(done) {
599605
var buttonDefault = selectButton(modeBar, 'resetCameraDefault3d');
600606

607+
expect(gd._fullLayout.scene._scene.viewInitial.aspectmode).toEqual('auto');
608+
expect(gd._fullLayout.scene2._scene.viewInitial.aspectmode).toEqual('manual');
609+
601610
expect(gd._fullLayout.scene._scene.viewInitial.aspectratio).toEqual({ x: 1, y: 1, z: 1 });
602611
expect(gd._fullLayout.scene2._scene.viewInitial.aspectratio).toEqual({ x: 3, y: 2, z: 1 });
603612

@@ -771,13 +780,19 @@ describe('Test gl3d modebar handlers - orthographic case', function() {
771780
buttonDefault.click();
772781
});
773782

774-
it('@gl button resetCameraDefault3d should reset to initial aspectratios', function(done) {
783+
it('@gl button resetCameraDefault3d should reset to initial aspectmode & aspectratios', function(done) {
775784
var buttonDefault = selectButton(modeBar, 'resetCameraDefault3d');
776785

786+
expect(gd._fullLayout.scene._scene.viewInitial.aspectmode).toEqual('auto');
787+
expect(gd._fullLayout.scene2._scene.viewInitial.aspectmode).toEqual('manual');
788+
777789
expect(gd._fullLayout.scene._scene.viewInitial.aspectratio).toEqual({ x: 1, y: 1, z: 1 });
778790
expect(gd._fullLayout.scene2._scene.viewInitial.aspectratio).toEqual({ x: 3, y: 2, z: 1 });
779791

780792
gd.once('plotly_relayout', function() {
793+
expect(gd._fullLayout.scene._scene.aspectmode).toEqual(undefined);
794+
expect(gd._fullLayout.scene2._scene.aspectmode).toEqual(undefined);
795+
781796
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().x).toBeCloseTo(1);
782797
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().y).toBeCloseTo(1);
783798
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().z).toBeCloseTo(1);
@@ -791,13 +806,19 @@ describe('Test gl3d modebar handlers - orthographic case', function() {
791806
buttonDefault.click();
792807
});
793808

794-
it('@gl button resetCameraLastSave3d should reset to initial aspectratios', function(done) {
809+
it('@gl button resetCameraLastSave3d should reset to initial aspectmode & aspectratios', function(done) {
795810
var buttonDefault = selectButton(modeBar, 'resetCameraDefault3d');
796811

812+
expect(gd._fullLayout.scene._scene.viewInitial.aspectmode).toEqual('auto');
813+
expect(gd._fullLayout.scene2._scene.viewInitial.aspectmode).toEqual('manual');
814+
797815
expect(gd._fullLayout.scene._scene.viewInitial.aspectratio).toEqual({ x: 1, y: 1, z: 1 });
798816
expect(gd._fullLayout.scene2._scene.viewInitial.aspectratio).toEqual({ x: 3, y: 2, z: 1 });
799817

800818
gd.once('plotly_relayout', function() {
819+
expect(gd._fullLayout.scene._scene.fullSceneLayout.aspectmode).toBe('auto');
820+
expect(gd._fullLayout.scene2._scene.fullSceneLayout.aspectmode).toBe('manual');
821+
801822
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().x).toBeCloseTo(1);
802823
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().y).toBeCloseTo(1);
803824
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().z).toBeCloseTo(1);
@@ -1175,7 +1196,7 @@ describe('Test gl3d drag and wheel interactions', function() {
11751196
.then(done);
11761197
});
11771198

1178-
it('@gl should update the scene aspectratio when zooming with scroll wheel i.e. orthographic case', function(done) {
1199+
it('@gl should update the scene aspectmode & aspectratio when zooming with scroll wheel i.e. orthographic case', function(done) {
11791200
var sceneLayout, sceneLayout2, sceneTarget, sceneTarget2;
11801201

11811202
var mock = {
@@ -1192,8 +1213,13 @@ describe('Test gl3d drag and wheel interactions', function() {
11921213
var aspectratio;
11931214
var relayoutEvent;
11941215
var relayoutCnt = 0;
1216+
var modeBar;
11951217

11961218
Plotly.plot(gd, mock)
1219+
.then(delay(20))
1220+
.then(function() {
1221+
modeBar = gd._fullLayout._modeBar;
1222+
})
11971223
.then(function() {
11981224
gd.on('plotly_relayout', function(e) {
11991225
relayoutCnt++;
@@ -1218,6 +1244,9 @@ describe('Test gl3d drag and wheel interactions', function() {
12181244
expect(aspectratio.x).toBeCloseTo(0.909, 3, 'aspectratio.x');
12191245
expect(aspectratio.y).toBeCloseTo(0.909, 3, 'aspectratio.y');
12201246
expect(aspectratio.z).toBeCloseTo(0.909, 3, 'aspectratio.z');
1247+
1248+
expect(relayoutEvent['scene.aspectmode']).toBe('manual');
1249+
expect(gd._fullLayout.scene._scene.fullSceneLayout.aspectmode).toBe('manual');
12211250
})
12221251
.then(function() {
12231252
return scroll(sceneTarget2);
@@ -1229,6 +1258,25 @@ describe('Test gl3d drag and wheel interactions', function() {
12291258
expect(aspectratio.x).toBeCloseTo(2.727, 3, 'aspectratio.x');
12301259
expect(aspectratio.y).toBeCloseTo(1.818, 3, 'aspectratio.y');
12311260
expect(aspectratio.z).toBeCloseTo(0.909, 3, 'aspectratio.z');
1261+
1262+
expect(relayoutEvent['scene2.aspectmode']).toBe('manual');
1263+
expect(gd._fullLayout.scene2._scene.fullSceneLayout.aspectmode).toBe('manual');
1264+
})
1265+
.then(function() {
1266+
var buttonDefault = selectButton(modeBar, 'resetCameraDefault3d');
1267+
1268+
buttonDefault.click();
1269+
})
1270+
.then(function() {
1271+
expect(gd._fullLayout.scene._scene.aspectmode).toEqual(undefined);
1272+
expect(gd._fullLayout.scene2._scene.aspectmode).toEqual(undefined);
1273+
1274+
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().x).toBeCloseTo(1);
1275+
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().y).toBeCloseTo(1);
1276+
expect(gd._fullLayout.scene._scene.glplot.getAspectratio().z).toBeCloseTo(1);
1277+
expect(gd._fullLayout.scene2._scene.glplot.getAspectratio().x).toBeCloseTo(3);
1278+
expect(gd._fullLayout.scene2._scene.glplot.getAspectratio().y).toBeCloseTo(2);
1279+
expect(gd._fullLayout.scene2._scene.glplot.getAspectratio().z).toBeCloseTo(1);
12321280
})
12331281
.catch(failTest)
12341282
.then(done);
@@ -1279,6 +1327,7 @@ describe('Test gl3d drag and wheel interactions', function() {
12791327
Object.keys(relayoutEvent).sort().forEach(function(key) {
12801328
expect(Object.keys(events[0])).toContain(key);
12811329
expect(key).not.toBe('scene.aspectratio');
1330+
expect(key).not.toBe('scene.aspectmode');
12821331
});
12831332
})
12841333
.catch(failTest)
@@ -1329,6 +1378,7 @@ describe('Test gl3d drag and wheel interactions', function() {
13291378
Object.keys(relayoutEvent).sort().forEach(function(key) {
13301379
expect(Object.keys(events[0])).toContain(key);
13311380
expect(key).not.toBe('scene.aspectratio');
1381+
expect(key).not.toBe('scene.aspectmode');
13321382
});
13331383
})
13341384
.catch(failTest)
@@ -1456,6 +1506,9 @@ describe('Test gl3d drag and wheel interactions', function() {
14561506
expect(aspectratio.x).toBeCloseTo(0.816, 3, 'aspectratio.x');
14571507
expect(aspectratio.y).toBeCloseTo(0.725, 3, 'aspectratio.y');
14581508
expect(aspectratio.z).toBeCloseTo(1.269, 3, 'aspectratio.z');
1509+
1510+
expect(relayoutEvent['scene.aspectmode']).toBe('manual');
1511+
expect(gd._fullLayout.scene._scene.fullSceneLayout.aspectmode).toBe('manual');
14591512
})
14601513
.then(function() {
14611514
// select a point

0 commit comments

Comments
 (0)