Skip to content

Commit 22ce90d

Browse files
authored
Merge pull request #2815 from plotly/scattergl-select-dblclick-pan-fix
Fix scattergl select -> dblclick -> pan bug
2 parents def6aa5 + b70ebcc commit 22ce90d

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed

Diff for: src/traces/scattergl/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,12 @@ function plot(gd, subplot, cdata) {
598598
}
599599
});
600600
}
601+
} else {
602+
if(scene.scatter2d) {
603+
// reset scatter2d opts to base opts,
604+
// thus unsetting markerUnselectedOptions from selection
605+
scene.scatter2d.update(scene.markerOptions);
606+
}
601607
}
602608

603609
// provide viewport and range

Diff for: test/jasmine/tests/gl2d_click_test.js

+171
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var assertHoverLabelContent = customAssertions.assertHoverLabelContent;
1414
// from the mousemove events and then simulate
1515
// a click event on mouseup
1616
var click = require('../assets/timed_click');
17+
var doubleClick = require('../assets/double_click');
1718
var hover = require('../assets/hover');
1819
var delay = require('../assets/delay');
1920
var mouseEvent = require('../assets/mouse_event');
@@ -963,4 +964,174 @@ describe('@noCI @gl Test gl2d lasso/select:', function() {
963964
.catch(failTest)
964965
.then(done);
965966
});
967+
968+
it('should behave correctly during select+doubleclick+pan scenarios', function(done) {
969+
gd = createGraphDiv();
970+
971+
// See https://github.com/plotly/plotly.js/issues/2767
972+
973+
function grabScene() {
974+
return gd.calcdata[0][0].t._scene;
975+
}
976+
977+
function _assert(msg, exp) {
978+
var scene = grabScene();
979+
var scatter2d = scene.scatter2d;
980+
981+
expect((scene.markerOptions || [])[0].opacity)
982+
.toBe(1, 'marker.opacity - ' + msg);
983+
expect((scene.markerSelectedOptions || [])[0].opacity)
984+
.toBe(1, 'selected.marker.opacity - ' + msg);
985+
expect((scene.markerUnselectedOptions || [])[0].opacity)
986+
.toBe(0.2, 'unselected.marker.opacity - ' + msg);
987+
988+
expect(scene.selectBatch).toEqual(exp.selectBatch);
989+
expect(scene.unselectBatch).toEqual(exp.unselectBatch);
990+
991+
var updateCalls = scatter2d.update.calls.all();
992+
var drawCalls = scatter2d.draw.calls.all();
993+
994+
expect(updateCalls.length).toBe(
995+
exp.updateArgs.length,
996+
'scatter2d.update has been called the correct number of times - ' + msg
997+
);
998+
updateCalls.forEach(function(d, i) {
999+
d.args.forEach(function(arg, j) {
1000+
if('range' in arg[0]) {
1001+
// no need to assert range value in detail
1002+
expect(exp.updateArgs[i][j]).toBe(
1003+
'range',
1004+
'scatter.update range update - ' + msg
1005+
);
1006+
} else {
1007+
expect(arg).toBe(
1008+
exp.updateArgs[i][j],
1009+
'scatter.update call' + i + ' arg' + j + ' - ' + msg
1010+
);
1011+
}
1012+
});
1013+
});
1014+
1015+
expect(drawCalls.length).toBe(
1016+
exp.drawArgs.length,
1017+
'scatter2d.draw has been called the correct number of times - ' + msg
1018+
);
1019+
drawCalls.forEach(function(d, i) {
1020+
d.args.forEach(function(arg, j) {
1021+
expect(arg).toBe(
1022+
exp.drawArgs[i][j],
1023+
'scatter.draw call' + i + ' arg' + j + ' - ' + msg
1024+
);
1025+
});
1026+
});
1027+
1028+
scene.scatter2d.update.calls.reset();
1029+
scene.scatter2d.draw.calls.reset();
1030+
}
1031+
1032+
var unselectBatchOld;
1033+
1034+
Plotly.newPlot('graph', [{
1035+
type: 'scattergl',
1036+
mode: 'markers',
1037+
y: [1, 2, 1],
1038+
marker: {size: 30}
1039+
}], {
1040+
dragmode: 'select',
1041+
margin: {t: 0, b: 0, l: 0, r: 0},
1042+
width: 500,
1043+
height: 500
1044+
})
1045+
.then(delay(100))
1046+
.then(function() {
1047+
var scene = grabScene();
1048+
spyOn(scene.scatter2d, 'update').and.callThrough();
1049+
spyOn(scene.scatter2d, 'draw').and.callThrough();
1050+
})
1051+
.then(function() {
1052+
_assert('base', {
1053+
selectBatch: [],
1054+
unselectBatch: [],
1055+
updateArgs: [],
1056+
drawArgs: []
1057+
});
1058+
})
1059+
.then(function() { return select([[20, 20], [480, 250]]); })
1060+
.then(function() {
1061+
var scene = grabScene();
1062+
_assert('after select', {
1063+
selectBatch: [[1]],
1064+
unselectBatch: [[0, 2]],
1065+
updateArgs: [
1066+
// N.B. scatter2d now draws unselected options
1067+
[scene.markerUnselectedOptions],
1068+
],
1069+
drawArgs: [
1070+
[scene.unselectBatch]
1071+
]
1072+
});
1073+
})
1074+
.then(function() { return doubleClick(250, 250); })
1075+
.then(function() {
1076+
var scene = grabScene();
1077+
_assert('after doubleclick', {
1078+
selectBatch: [null],
1079+
unselectBatch: [[0, 1, 2]],
1080+
updateArgs: [],
1081+
drawArgs: [
1082+
// call in no-selection loop (can we get rid of this?)
1083+
[0],
1084+
// call with unselectBatch
1085+
[scene.unselectBatch]
1086+
]
1087+
});
1088+
})
1089+
.then(function() { return Plotly.relayout(gd, 'dragmode', 'pan'); })
1090+
.then(function() {
1091+
_assert('after relayout to *pan*', {
1092+
selectBatch: [null],
1093+
unselectBatch: [[0, 1, 2]],
1094+
// nothing to do when relayouting to 'pan'
1095+
updateArgs: [],
1096+
drawArgs: []
1097+
});
1098+
1099+
// keep ref for next _assert()
1100+
var scene = grabScene();
1101+
unselectBatchOld = scene.unselectBatch;
1102+
})
1103+
.then(function() { return drag([[200, 200], [250, 250]]); })
1104+
.then(function() {
1105+
var scene = grabScene();
1106+
_assert('after pan', {
1107+
selectBatch: null,
1108+
unselectBatch: null,
1109+
// drag triggers:
1110+
// - 2 scene.update() calls, which each invoke
1111+
// + 1 scatter2d.update (updating viewport)
1112+
// + 2 scatter2d.draw (same as after double-click)
1113+
//
1114+
// replot on mouseup triggers:
1115+
// - 1 scatter2d.update updating viewport
1116+
// - 1 scatter2d.update resetting markerOptions
1117+
// - 1 (full) scene.draw()
1118+
updateArgs: [
1119+
['range'],
1120+
['range'],
1121+
// N.B. bring scatter2d back to 'base' marker options
1122+
[scene.markerOptions],
1123+
['range']
1124+
],
1125+
drawArgs: [
1126+
[0],
1127+
[unselectBatchOld],
1128+
[0],
1129+
[unselectBatchOld],
1130+
[0]
1131+
]
1132+
});
1133+
})
1134+
.catch(failTest)
1135+
.then(done);
1136+
});
9661137
});

0 commit comments

Comments
 (0)