Skip to content

Commit fd032af

Browse files
authored
Merge pull request #1377 from plotly/scene-dragmode-false
Implement `scene.dragmode: false`
2 parents 09ff6d7 + 2e4f001 commit fd032af

File tree

6 files changed

+94
-41
lines changed

6 files changed

+94
-41
lines changed

src/plots/gl3d/camera.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,13 @@ function createCamera(element, options) {
181181

182182
var lastX = 0, lastY = 0;
183183
mouseChange(element, function(buttons, x, y, mods) {
184-
var rotate = camera.keyBindingMode === 'rotate';
185-
var pan = camera.keyBindingMode === 'pan';
186-
var zoom = camera.keyBindingMode === 'zoom';
184+
var keyBindingMode = camera.keyBindingMode;
185+
186+
if(keyBindingMode === false) return;
187+
188+
var rotate = keyBindingMode === 'rotate';
189+
var pan = keyBindingMode === 'pan';
190+
var zoom = keyBindingMode === 'zoom';
187191

188192
var ctrl = !!mods.control;
189193
var alt = !!mods.alt;
@@ -226,6 +230,8 @@ function createCamera(element, options) {
226230
});
227231

228232
mouseWheel(element, function(dx, dy) {
233+
if(camera.keyBindingMode === false) return;
234+
229235
var flipX = camera.flipX ? 1 : -1;
230236
var flipY = camera.flipY ? 1 : -1;
231237
var t = now();

src/plots/gl3d/layout/defaults.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
'use strict';
1111

12+
var Lib = require('../../../lib');
1213
var Color = require('../../../components/color');
1314

1415
var handleSubplotDefaults = require('../../subplot_defaults');
@@ -17,20 +18,14 @@ var supplyGl3dAxisLayoutDefaults = require('./axis_defaults');
1718

1819

1920
module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
20-
var hasNon3D = (
21-
layoutOut._has('cartesian') ||
22-
layoutOut._has('geo') ||
23-
layoutOut._has('gl2d') ||
24-
layoutOut._has('pie') ||
25-
layoutOut._has('ternary')
26-
);
21+
var hasNon3D = layoutOut._basePlotModules.length > 1;
2722

2823
// some layout-wide attribute are used in all scenes
2924
// if 3D is the only visible plot type
3025
function getDfltFromLayout(attr) {
3126
if(hasNon3D) return;
3227

33-
var isValid = layoutAttributes[attr].values.indexOf(layoutIn[attr]) !== -1;
28+
var isValid = Lib.validate(layoutIn[attr], layoutAttributes[attr]);
3429
if(isValid) return layoutIn[attr];
3530
}
3631

src/plots/gl3d/layout/layout_attributes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ module.exports = {
142142
dragmode: {
143143
valType: 'enumerated',
144144
role: 'info',
145-
values: ['orbit', 'turntable', 'zoom', 'pan'],
145+
values: ['orbit', 'turntable', 'zoom', 'pan', false],
146146
dflt: 'turntable',
147147
description: [
148148
'Determines the mode of drag interactions for this scene.'

src/plots/gl3d/scene.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ function initializeGLPlot(scene, fullLayout, canvas, gl) {
173173
}
174174

175175
var relayoutCallback = function(scene) {
176+
if(scene.fullSceneLayout.dragmode === false) return;
177+
176178
var update = {};
177179
update[scene.id] = getLayoutCamera(scene.camera);
178180
scene.saveCamera(scene.graphDiv.layout);

test/jasmine/tests/gl3dlayout_test.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
var Gl3d = require('@src/plots/gl3d');
2-
var Plots = require('@src/plots/plots');
32

43
var tinycolor = require('tinycolor2');
54
var Color = require('@src/components/color');
@@ -14,9 +13,7 @@ describe('Test Gl3d layout defaults', function() {
1413
var supplyLayoutDefaults = Gl3d.supplyLayoutDefaults;
1514

1615
beforeEach(function() {
17-
layoutOut = {
18-
_has: Plots._hasPlotType
19-
};
16+
layoutOut = { _basePlotModules: ['gl3d'] };
2017

2118
// needs a scene-ref in a trace in order to be detected
2219
fullData = [ { type: 'scatter3d', scene: 'scene' }];
@@ -174,8 +171,13 @@ describe('Test Gl3d layout defaults', function() {
174171
expect(layoutOut.scene.dragmode)
175172
.toBe('orbit', 'to user layout val if valid and 3d only');
176173

174+
layoutIn = { scene: {}, dragmode: 'invalid' };
175+
supplyLayoutDefaults(layoutIn, layoutOut, fullData);
176+
expect(layoutOut.scene.dragmode)
177+
.toBe('turntable', 'to turntable if invalid and 3d only');
178+
177179
layoutIn = { scene: {}, dragmode: 'orbit' };
178-
layoutOut._basePlotModules = [{ name: 'cartesian' }];
180+
layoutOut._basePlotModules.push({ name: 'cartesian' });
179181
supplyLayoutDefaults(layoutIn, layoutOut, fullData);
180182
expect(layoutOut.scene.dragmode)
181183
.toBe('turntable', 'to default if not 3d only');
@@ -202,8 +204,13 @@ describe('Test Gl3d layout defaults', function() {
202204
expect(layoutOut.scene.hovermode)
203205
.toBe(false, 'to user layout val if valid and 3d only');
204206

207+
layoutIn = { scene: {}, hovermode: 'invalid' };
208+
supplyLayoutDefaults(layoutIn, layoutOut, fullData);
209+
expect(layoutOut.scene.hovermode)
210+
.toBe('closest', 'to closest if invalid and 3d only');
211+
205212
layoutIn = { scene: {}, hovermode: false };
206-
layoutOut._basePlotModules = [{ name: 'cartesian' }];
213+
layoutOut._basePlotModules.push({ name: 'cartesian' });
207214
supplyLayoutDefaults(layoutIn, layoutOut, fullData);
208215
expect(layoutOut.scene.hovermode)
209216
.toBe('closest', 'to default if not 3d only');

test/jasmine/tests/gl_plot_interact_test.js

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,23 @@ describe('Test gl plot interactions', function() {
595595
});
596596

597597
describe('drag and wheel interactions', function() {
598+
599+
function scroll(target) {
600+
return new Promise(function(resolve) {
601+
target.dispatchEvent(new WheelEvent('wheel', {deltaY: 1}));
602+
setTimeout(resolve, 0);
603+
});
604+
}
605+
606+
function drag(target) {
607+
return new Promise(function(resolve) {
608+
target.dispatchEvent(new MouseEvent('mousedown', {x: 0, y: 0}));
609+
target.dispatchEvent(new MouseEvent('mousemove', { x: 100, y: 100}));
610+
target.dispatchEvent(new MouseEvent('mouseup', { x: 100, y: 100}));
611+
setTimeout(resolve, 0);
612+
});
613+
}
614+
598615
it('should update the scene camera', function(done) {
599616
var sceneLayout = gd._fullLayout.scene,
600617
sceneLayout2 = gd._fullLayout.scene2,
@@ -606,37 +623,63 @@ describe('Test gl plot interactions', function() {
606623
expect(sceneLayout2.camera.eye)
607624
.toEqual({x: 2.5, y: 2.5, z: 2.5});
608625

609-
// Wheel scene 1
610-
sceneTarget.dispatchEvent(new WheelEvent('wheel', {deltaY: 1}));
611-
612-
// Wheel scene 2
613-
sceneTarget2.dispatchEvent(new WheelEvent('wheel', {deltaY: 1}));
614-
615-
setTimeout(function() {
616-
617-
expect(relayoutCallback).toHaveBeenCalledTimes(2);
618-
626+
scroll(sceneTarget).then(function() {
627+
expect(relayoutCallback).toHaveBeenCalledTimes(1);
619628
relayoutCallback.calls.reset();
620629

621-
// Drag scene 1
622-
sceneTarget.dispatchEvent(new MouseEvent('mousedown', {x: 0, y: 0}));
623-
sceneTarget.dispatchEvent(new MouseEvent('mousemove', { x: 100, y: 100}));
624-
sceneTarget.dispatchEvent(new MouseEvent('mouseup', { x: 100, y: 100}));
630+
return scroll(sceneTarget2);
631+
})
632+
.then(function() {
633+
expect(relayoutCallback).toHaveBeenCalledTimes(1);
634+
relayoutCallback.calls.reset();
625635

626-
// Drag scene 2
627-
sceneTarget2.dispatchEvent(new MouseEvent('mousedown', {x: 0, y: 0 }));
628-
sceneTarget2.dispatchEvent(new MouseEvent('mousemove', {x: 100, y: 100}));
629-
sceneTarget2.dispatchEvent(new MouseEvent('mouseup', {x: 100, y: 100}));
636+
return drag(sceneTarget2);
637+
})
638+
.then(function() {
639+
expect(relayoutCallback).toHaveBeenCalledTimes(1);
640+
relayoutCallback.calls.reset();
630641

631-
setTimeout(function() {
642+
return drag(sceneTarget);
643+
})
644+
.then(function() {
645+
expect(relayoutCallback).toHaveBeenCalledTimes(1);
646+
relayoutCallback.calls.reset();
632647

633-
expect(relayoutCallback).toHaveBeenCalledTimes(2);
648+
return Plotly.relayout(gd, {
649+
'scene.dragmode': false,
650+
'scene2.dragmode': false
651+
});
652+
})
653+
.then(function() {
654+
expect(relayoutCallback).toHaveBeenCalledTimes(1);
655+
relayoutCallback.calls.reset();
634656

635-
done();
657+
return drag(sceneTarget);
658+
})
659+
.then(function() {
660+
return drag(sceneTarget2);
661+
})
662+
.then(function() {
663+
expect(relayoutCallback).toHaveBeenCalledTimes(0);
636664

637-
}, MODEBAR_DELAY);
665+
return Plotly.relayout(gd, {
666+
'scene.dragmode': 'orbit',
667+
'scene2.dragmode': 'turntable'
668+
});
669+
})
670+
.then(function() {
671+
expect(relayoutCallback).toHaveBeenCalledTimes(1);
672+
relayoutCallback.calls.reset();
638673

639-
}, MODEBAR_DELAY);
674+
return drag(sceneTarget);
675+
})
676+
.then(function() {
677+
return drag(sceneTarget2);
678+
})
679+
.then(function() {
680+
expect(relayoutCallback).toHaveBeenCalledTimes(2);
681+
})
682+
.then(done);
640683
});
641684
});
642685
});

0 commit comments

Comments
 (0)