Skip to content

Commit e29aceb

Browse files
committed
preserve aspectratio & aspectmode changes by orthographic scroll zoom for restyle interactions
1 parent 9ba5c96 commit e29aceb

File tree

2 files changed

+95
-1
lines changed

2 files changed

+95
-1
lines changed

src/plots/gl3d/scene.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ proto.initializeGLPlot = function() {
246246
y: s * o.y,
247247
z: s * o.z
248248
});
249+
scene._aspectmode = 'manual';
249250
}
250251

251252
relayoutCallback(scene);
@@ -729,7 +730,7 @@ proto.plot = function(sceneData, fullLayout, layout) {
729730
* Dynamically set the aspect ratio depending on the users aspect settings
730731
*/
731732
var aspectRatio;
732-
var aspectmode = fullSceneLayout.aspectmode;
733+
var aspectmode = scene._aspectmode || fullSceneLayout.aspectmode;
733734
if(aspectmode === 'cube') {
734735
aspectRatio = [1, 1, 1];
735736
} else if(aspectmode === 'manual') {
@@ -762,6 +763,7 @@ proto.plot = function(sceneData, fullLayout, layout) {
762763
} else {
763764
throw new Error('scene.js aspectRatio was not one of the enumerated types');
764765
}
766+
scene._aspectmode = aspectmode;
765767

766768
/*
767769
* Write aspect Ratio back to user data and fullLayout so that it is modifies as user

test/jasmine/tests/gl3d_plot_interact_test.js

+92
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,98 @@ describe('Test gl3d drag and wheel interactions', function() {
13841384
.catch(failTest)
13851385
.then(done);
13861386
});
1387+
1388+
it('@gl should preserve aspectratio values when orthographic scroll zoom i.e. after restyle', function(done) {
1389+
var coords = {
1390+
x: [1, 2, 10, 4, 5],
1391+
y: [10, 2, 4, 4, 2],
1392+
z: [10, 2, 4, 8, 16],
1393+
};
1394+
1395+
var mock = {
1396+
data: [{
1397+
type: 'scatter3d',
1398+
x: coords.x,
1399+
y: coords.y,
1400+
z: coords.z,
1401+
mode: 'markers',
1402+
marker: {
1403+
color: 'red',
1404+
size: 16,
1405+
}
1406+
}, {
1407+
type: 'scatter3d',
1408+
x: [coords.x[0]],
1409+
y: [coords.y[0]],
1410+
z: [coords.z[0]],
1411+
mode: 'markers',
1412+
marker: {
1413+
color: 'blue',
1414+
size: 32,
1415+
}
1416+
}],
1417+
layout: {
1418+
width: 400,
1419+
height: 400,
1420+
scene: {
1421+
camera: {
1422+
projection: {
1423+
type: 'orthographic'
1424+
}
1425+
},
1426+
}
1427+
}
1428+
};
1429+
1430+
var sceneTarget;
1431+
var relayoutEvent;
1432+
var relayoutCnt = 0;
1433+
1434+
Plotly.plot(gd, mock)
1435+
.then(function() {
1436+
gd.on('plotly_relayout', function(e) {
1437+
relayoutCnt++;
1438+
relayoutEvent = e;
1439+
});
1440+
1441+
sceneTarget = gd.querySelector('.svg-container .gl-container #scene canvas');
1442+
})
1443+
.then(function() {
1444+
var aspectratio = gd._fullLayout.scene.aspectratio;
1445+
expect(aspectratio.x).toBeCloseTo(0.898, 3, 'aspectratio.x');
1446+
expect(aspectratio.y).toBeCloseTo(0.798, 3, 'aspectratio.y');
1447+
expect(aspectratio.z).toBeCloseTo(1.396, 3, 'aspectratio.z');
1448+
})
1449+
.then(function() {
1450+
return scroll(sceneTarget);
1451+
})
1452+
.then(function() {
1453+
expect(relayoutCnt).toEqual(1);
1454+
1455+
var aspectratio = relayoutEvent['scene.aspectratio'];
1456+
expect(aspectratio.x).toBeCloseTo(0.816, 3, 'aspectratio.x');
1457+
expect(aspectratio.y).toBeCloseTo(0.725, 3, 'aspectratio.y');
1458+
expect(aspectratio.z).toBeCloseTo(1.269, 3, 'aspectratio.z');
1459+
})
1460+
.then(function() {
1461+
// select a point
1462+
var i = 2;
1463+
1464+
return Plotly.restyle(gd, {
1465+
x: [[coords.x[i]]],
1466+
y: [[coords.y[i]]],
1467+
z: [[coords.z[i]]],
1468+
}, 1);
1469+
})
1470+
.then(function() {
1471+
var aspectratio = gd._fullLayout.scene.aspectratio;
1472+
expect(aspectratio.x).toBeCloseTo(0.816, 3, 'aspectratio.x');
1473+
expect(aspectratio.y).toBeCloseTo(0.725, 3, 'aspectratio.y');
1474+
expect(aspectratio.z).toBeCloseTo(1.269, 3, 'aspectratio.z');
1475+
})
1476+
.catch(failTest)
1477+
.then(done);
1478+
});
13871479
});
13881480

13891481
describe('Test gl3d relayout calls', function() {

0 commit comments

Comments
 (0)