Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f649320

Browse files
authored
Merge pull request plotly#6147 from jonfunkhouser/bug/5219
disable polar rotation drag when dragmode = false
2 parents 8c63407 + 70cb931 commit f649320

File tree

4 files changed

+297
-10
lines changed

4 files changed

+297
-10
lines changed

draftlogs/6147_fix.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Fix for disabling polar rotation when `dragmode` is set to false [[#6147](https://github.com/plotly/plotly.js/pull/6147)],
2+
with thanks to @jonfunkhouser for the contribution!

src/plot_api/plot_api.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2171,7 +2171,9 @@ function _relayout(gd, aobj) {
21712171
if(parentFull.autorange) flags.calc = true;
21722172
else flags.plot = true;
21732173
} else {
2174-
if((fullLayout._has('scatter-like') && fullLayout._has('regl')) &&
2174+
if(ai === 'dragmode' && ((vi === false && vOld !== false) || (vi !== false && vOld === false))) {
2175+
flags.plot = true;
2176+
} else if((fullLayout._has('scatter-like') && fullLayout._has('regl')) &&
21752177
(ai === 'dragmode' &&
21762178
(vi === 'lasso' || vi === 'select') &&
21772179
!(vOld === 'lasso' || vOld === 'select'))

src/plots/polar/polar.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ proto.updateHoverAndMainDrag = function(fullLayout) {
800800
var scaleX;
801801
var scaleY;
802802

803-
var mainDrag = dragBox.makeDragger(layers, 'path', 'maindrag', 'crosshair');
803+
var mainDrag = dragBox.makeDragger(layers, 'path', 'maindrag', fullLayout.dragmode === false ? 'none' : 'crosshair');
804804

805805
d3.select(mainDrag)
806806
.attr('d', _this.pathSubplot())
@@ -1150,6 +1150,9 @@ proto.updateRadialDrag = function(fullLayout, polarLayout, rngIndex) {
11501150

11511151
var radialDrag = dragBox.makeRectDragger(layers, className, 'crosshair', -bl2, -bl2, bl, bl);
11521152
var dragOpts = {element: radialDrag, gd: gd};
1153+
if(fullLayout.dragmode === false) {
1154+
dragOpts.dragmode = false;
1155+
}
11531156

11541157
updateElement(d3.select(radialDrag), radialAxis.visible && innerRadius < radius, {
11551158
transform: strTranslate(tx, ty)
@@ -1292,13 +1295,17 @@ proto.updateAngularDrag = function(fullLayout) {
12921295
var cyy = _this.cyy;
12931296
var dbs = constants.angularDragBoxSize;
12941297

1295-
var angularDrag = dragBox.makeDragger(layers, 'path', 'angulardrag', 'move');
1298+
var angularDrag = dragBox.makeDragger(layers, 'path', 'angulardrag', fullLayout.dragmode === false ? 'none' : 'move');
12961299
var dragOpts = {element: angularDrag, gd: gd};
12971300

1298-
d3.select(angularDrag)
1299-
.attr('d', _this.pathAnnulus(radius, radius + dbs))
1300-
.attr('transform', strTranslate(cx, cy))
1301-
.call(setCursor, 'move');
1301+
if(fullLayout.dragmode === false) {
1302+
dragOpts.dragmode = false;
1303+
} else {
1304+
d3.select(angularDrag)
1305+
.attr('d', _this.pathAnnulus(radius, radius + dbs))
1306+
.attr('transform', strTranslate(cx, cy))
1307+
.call(setCursor, 'move');
1308+
}
13021309

13031310
function xy2a(x, y) {
13041311
return Math.atan2(cyy + dbs - y, x - cxx - dbs);

test/jasmine/tests/polar_test.js

Lines changed: 279 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ describe('Test polar interactions:', function() {
961961
.then(done, done.fail);
962962
});
963963

964-
it('should response to drag interactions on radial drag area', function(done) {
964+
it('should respond to drag interactions on radial drag area', function(done) {
965965
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
966966

967967
// to avoid dragging on hover labels
@@ -1044,7 +1044,7 @@ describe('Test polar interactions:', function() {
10441044
.then(done, done.fail);
10451045
});
10461046

1047-
it('should response to drag interactions on inner radial drag area', function(done) {
1047+
it('should respond to drag interactions on inner radial drag area', function(done) {
10481048
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
10491049
fig.layout.polar.hole = 0.2;
10501050
// to avoid dragging on hover labels
@@ -1082,7 +1082,7 @@ describe('Test polar interactions:', function() {
10821082
.then(done, done.fail);
10831083
});
10841084

1085-
it('should response to drag interactions on angular drag area', function(done) {
1085+
it('should respond to drag interactions on angular drag area', function(done) {
10861086
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
10871087

10881088
// to avoid dragging on hover labels
@@ -1146,6 +1146,282 @@ describe('Test polar interactions:', function() {
11461146
.then(done, done.fail);
11471147
});
11481148

1149+
describe('dragmode === false', function() {
1150+
it('should not respond to drag interactions on plot area when dragmode === false', function(done) {
1151+
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
1152+
// adjust margins so that middle of plot area is at 300x300
1153+
// with its middle at [200,200]
1154+
fig.layout.width = 400;
1155+
fig.layout.height = 400;
1156+
fig.layout.margin = {l: 50, t: 50, b: 50, r: 50};
1157+
1158+
var mid = [200, 200];
1159+
var resetNumber = 0;
1160+
1161+
function _drag(p0, dp) {
1162+
var node = d3Select('.polar > .draglayer > .maindrag').node();
1163+
return drag({node: node, dpos: dp, pos0: p0});
1164+
}
1165+
1166+
function _assertRange(rng, msg) {
1167+
expect(gd._fullLayout.polar.radialaxis.range).toBeCloseToArray(rng, 1, msg);
1168+
}
1169+
1170+
function _assertBase(extra) {
1171+
var msg = 'base range' + (extra ? ' ' + extra : '');
1172+
_assertRange([0, 11.1], msg);
1173+
}
1174+
1175+
function _reset() {
1176+
resetNumber++;
1177+
1178+
var extra = '(reset ' + resetNumber + ')';
1179+
_assertBase(extra);
1180+
expect(eventCnts.plotly_doubleclick).toBe(0, 'doubleclick event #' + extra);
1181+
}
1182+
1183+
_plot(fig)
1184+
.then(_assertBase)
1185+
.then(function() { return Plotly.relayout(gd, 'dragmode', false); })
1186+
.then(function() { return _drag(mid, [50, 50]); })
1187+
.then(function() {
1188+
_assertBase('from center move toward bottom-right');
1189+
})
1190+
.then(delay(20))
1191+
.then(function() { return _doubleClick(mid); })
1192+
.then(delay(20))
1193+
.then(_reset)
1194+
.then(function() { return _drag(mid, [-50, -50]); })
1195+
.then(function() {
1196+
_assertBase('from center move toward top-left');
1197+
})
1198+
.then(delay(20))
1199+
.then(function() { return _doubleClick(mid); })
1200+
.then(delay(20))
1201+
.then(_reset)
1202+
.then(function() { return _drag([mid[0] + 30, mid[0] - 30], [50, -50]); })
1203+
.then(function() {
1204+
_assertBase('from quadrant #1 move top-right');
1205+
})
1206+
.then(delay(20))
1207+
.then(function() { return _doubleClick(mid); })
1208+
.then(delay(20))
1209+
.then(_reset)
1210+
.then(function() { return _drag([345, 200], [-50, 0]); })
1211+
.then(function() {
1212+
_assertBase('from right edge move left');
1213+
})
1214+
.then(delay(20))
1215+
.then(function() { return _doubleClick(mid); })
1216+
.then(delay(20))
1217+
.then(_reset)
1218+
.then(function() { return _drag(mid, [10, 10]);})
1219+
.then(function() { _assertBase('from center to not far enough'); })
1220+
.then(function() { return _drag([mid[0] + 30, mid[0] - 30], [-10, 0]);})
1221+
.then(function() { _assertBase('from quadrant #1 to not far enough'); })
1222+
.then(function() { return _drag([345, 200], [-10, 0]);})
1223+
.then(function() { _assertBase('from right edge to not far enough'); })
1224+
.then(function() {
1225+
expect(eventCnts.plotly_relayout)
1226+
.toBe(1, 'no new relayout events after *not far enough* cases');
1227+
})
1228+
.then(delay(20))
1229+
.then(function() { return _doubleClick(mid); })
1230+
.then(delay(20))
1231+
.then(_reset)
1232+
.then(function() { return Plotly.relayout(gd, 'polar.hole', 0.2); })
1233+
.then(function() { return _drag([mid[0] + 30, mid[0] - 30], [50, -50]); })
1234+
.then(function() {
1235+
_assertRange([0, 11.4], 'with polar.hole>0, from quadrant #1 move top-right');
1236+
})
1237+
.then(done, done.fail);
1238+
});
1239+
1240+
it('should not respond to drag interactions on radial drag area when dragmode === false', function(done) {
1241+
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
1242+
// adjust margins so that middle of plot area is at 300x300
1243+
// with its middle at [200,200]
1244+
fig.layout.width = 400;
1245+
fig.layout.height = 400;
1246+
fig.layout.margin = {l: 50, t: 50, b: 50, r: 50};
1247+
1248+
var dragPos0 = [375, 200];
1249+
var resetNumber = 0;
1250+
1251+
// use 'special' drag method - as we need two mousemove events
1252+
// to activate the radial drag mode
1253+
function _drag(p0, dp) {
1254+
var node = d3Select('.polar > .draglayer > .radialdrag').node();
1255+
return drag({node: node, dpos: dp, pos0: p0, nsteps: 2});
1256+
}
1257+
1258+
function _assert(rng, angle, evtRng1, evtAngle, msg) {
1259+
expect(gd._fullLayout.polar.radialaxis.range)
1260+
.toBeCloseToArray(rng, 1, msg + ' - range');
1261+
expect(gd._fullLayout.polar.radialaxis.angle)
1262+
.toBeCloseTo(angle, 1, msg + ' - angle');
1263+
1264+
if(evtRng1 !== null) {
1265+
expect(eventData['polar.radialaxis.range[1]'])
1266+
.toBeCloseTo(evtRng1, 1, msg + ' - range[1] event data');
1267+
}
1268+
if(evtAngle !== null) {
1269+
expect(eventData['polar.radialaxis.angle'])
1270+
.toBeCloseTo(evtAngle, 1, msg + ' - angle event data');
1271+
}
1272+
}
1273+
1274+
function _assertBase(extra) {
1275+
extra = extra ? ' ' + extra : '';
1276+
_assert([0, 11.1], 0, null, null, 'base' + extra);
1277+
}
1278+
1279+
function _reset() {
1280+
return delay(100)()
1281+
.then(function() { return _doubleClick([200, 200]); })
1282+
.then(function() {
1283+
resetNumber++;
1284+
1285+
var extra = '(reset ' + resetNumber + ')';
1286+
_assertBase(extra);
1287+
expect(eventCnts.plotly_doubleclick).toBe(0, 'doubleclick event #' + extra);
1288+
});
1289+
}
1290+
1291+
_plot(fig)
1292+
.then(_assertBase)
1293+
.then(function() { return Plotly.relayout(gd, 'dragmode', false); })
1294+
.then(function() { return _drag(dragPos0, [-50, 0]); })
1295+
.then(function() {
1296+
_assertBase('move inward');
1297+
})
1298+
.then(_reset)
1299+
.then(function() { return _drag(dragPos0, [50, 0]); })
1300+
.then(function() {
1301+
_assertBase('move outward');
1302+
})
1303+
.then(_reset)
1304+
.then(function() { return _drag(dragPos0, [0, -50]); })
1305+
.then(function() {
1306+
_assertBase('move counterclockwise');
1307+
})
1308+
.then(_reset)
1309+
.then(function() { return _drag(dragPos0, [0, 50]); })
1310+
.then(function() {
1311+
_assertBase('move clockwise');
1312+
})
1313+
.then(_reset)
1314+
.then(function() {
1315+
expect(eventCnts.plotly_relayout).toBe(1, 'total # of relayout events');
1316+
})
1317+
.then(done, done.fail);
1318+
});
1319+
1320+
it('should not respond to drag interactions on inner radial drag area when dragmode === false', function(done) {
1321+
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
1322+
fig.layout.polar.hole = 0.2;
1323+
// adjust margins so that middle of plot area is at 300x300
1324+
// with its middle at [200,200]
1325+
fig.layout.width = 400;
1326+
fig.layout.height = 400;
1327+
fig.layout.margin = {l: 50, t: 50, b: 50, r: 50};
1328+
1329+
var dragPos0 = [200, 200];
1330+
1331+
// use 'special' drag method - as we need two mousemove events
1332+
// to activate the radial drag mode
1333+
function _drag(p0, dp) {
1334+
var node = d3Select('.polar > .draglayer > .radialdrag-inner').node();
1335+
return drag({node: node, dpos: dp, pos0: p0, nsteps: 2});
1336+
}
1337+
1338+
function _assert(rng, msg) {
1339+
expect(gd._fullLayout.polar.radialaxis.range)
1340+
.toBeCloseToArray(rng, 1, msg + ' - range');
1341+
}
1342+
1343+
function _assertBase(extra) {
1344+
extra = extra ? ' ' + extra : '';
1345+
_assert([0, 11.4], 'base' + extra);
1346+
}
1347+
1348+
_plot(fig)
1349+
.then(_assertBase)
1350+
.then(function() { return Plotly.relayout(gd, 'dragmode', false); })
1351+
.then(function() { return _drag(dragPos0, [-50, 0]); })
1352+
.then(function() {
1353+
_assertBase('move inward');
1354+
})
1355+
.then(function() { return Plotly.relayout(gd, 'polar.radialaxis.autorange', true); })
1356+
.then(function() { return _drag(dragPos0, [50, 0]); })
1357+
.then(function() {
1358+
_assertBase('move outward');
1359+
})
1360+
.then(done, done.fail);
1361+
});
1362+
1363+
it('should not respond to drag interactions on angular drag area when dragmode === false', function(done) {
1364+
var fig = Lib.extendDeep({}, require('@mocks/polar_scatter.json'));
1365+
// adjust margins so that middle of plot area is at 300x300
1366+
// with its middle at [200,200]
1367+
fig.layout.width = 400;
1368+
fig.layout.height = 400;
1369+
fig.layout.margin = {l: 50, t: 50, b: 50, r: 50};
1370+
1371+
var dragPos0 = [350, 150];
1372+
var resetNumber = 0;
1373+
1374+
function _drag(p0, dp) {
1375+
var node = d3Select('.polar > .draglayer > .angulardrag').node();
1376+
return drag({node: node, dpos: dp, pos0: p0});
1377+
}
1378+
1379+
function _assert(rot, msg, noEvent) {
1380+
expect(gd._fullLayout.polar.angularaxis.rotation)
1381+
.toBeCloseTo(rot, 1, msg + ' - rotation');
1382+
if(!noEvent) {
1383+
expect(eventData['polar.angularaxis.rotation'])
1384+
.toBeCloseTo(rot, 1, msg + ' - rotation event data');
1385+
}
1386+
}
1387+
1388+
function _assertBase(extra) {
1389+
extra = extra ? ' ' + extra : '';
1390+
_assert(0, 'base' + extra, true);
1391+
}
1392+
1393+
function _reset() {
1394+
return delay(100)()
1395+
.then(function() { return _doubleClick([200, 200]); })
1396+
.then(function() {
1397+
resetNumber++;
1398+
1399+
var extra = '(reset ' + resetNumber + ')';
1400+
_assertBase(extra);
1401+
expect(eventCnts.plotly_doubleclick).toBe(0, 'doubleclick event #' + extra);
1402+
});
1403+
}
1404+
1405+
_plot(fig)
1406+
.then(_assertBase)
1407+
.then(function() { return Plotly.relayout(gd, 'dragmode', false); })
1408+
.then(function() { return _drag(dragPos0, [-20, -20]); })
1409+
.then(function() {
1410+
_assertBase('move counterclockwise');
1411+
})
1412+
.then(_reset)
1413+
.then(function() { return _drag(dragPos0, [20, 20]); })
1414+
.then(function() {
1415+
_assertBase('move clockwise');
1416+
})
1417+
.then(_reset)
1418+
.then(function() {
1419+
expect(eventCnts.plotly_relayout).toBe(1, 'total # of relayout events');
1420+
})
1421+
.then(done, done.fail);
1422+
});
1423+
});
1424+
11491425
describe('should update scene during drag interactions on radial and angular drag area', function() {
11501426
var objs = ['scatter2d', 'line2d'];
11511427
var scene, gl, nTraces;

0 commit comments

Comments
 (0)