Skip to content

Commit 52975c3

Browse files
authored
Merge pull request #7164 from plotly/alex/fake-selections
fix to allow you to add fake selections
2 parents 22efc2f + 51dcc24 commit 52975c3

File tree

3 files changed

+103
-1
lines changed

3 files changed

+103
-1
lines changed

draftlogs/7164_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Allow null or broken selection objects without throwing an error [[#7164](https://github.com/plotly/plotly.js/pull/7164)]

src/components/selections/select.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ function prepSelect(evt, startX, startY, dragOptions, mode) {
182182
for(var q = 0; q < selections.length; q++) {
183183
var s = fullLayout.selections[q];
184184
if(
185+
!s ||
185186
s.xref !== xRef ||
186187
s.yref !== yRef
187188
) {

test/jasmine/tests/select_test.js

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ function assertSelectionNodes(cornerCnt, outlineCnt, _msg) {
7575
}
7676

7777
var selectingCnt, selectingData, selectedCnt, selectedData, deselectCnt, doubleClickData;
78-
var selectedPromise, deselectPromise, clickedPromise;
78+
var selectedPromise, deselectPromise, clickedPromise, relayoutPromise;
7979

8080
function resetEvents(gd) {
8181
selectingCnt = 0;
@@ -125,6 +125,12 @@ function resetEvents(gd) {
125125
resolve();
126126
});
127127
});
128+
129+
relayoutPromise = new Promise(function(resolve) {
130+
gd.on('plotly_relayout', function() {
131+
resolve();
132+
});
133+
});
128134
}
129135

130136
function assertEventCounts(selecting, selected, deselect, msg) {
@@ -1035,6 +1041,100 @@ describe('Test select box and lasso in general:', function() {
10351041
});
10361042
});
10371043

1044+
describe('select / deselect with fake selections', function() {
1045+
var gd;
1046+
beforeEach(function(done) {
1047+
gd = createGraphDiv();
1048+
1049+
var mockCopy = Lib.extendDeep({}, mock);
1050+
mockCopy.layout.dragmode = 'select';
1051+
mockCopy.layout.hovermode = 'closest';
1052+
mockCopy.layout.selections = [null];
1053+
addInvisible(mockCopy);
1054+
1055+
_newPlot(gd, mockCopy.data, mockCopy.layout)
1056+
.then(done);
1057+
});
1058+
1059+
it('should trigger selecting/selected/deselect events', function(done) {
1060+
resetEvents(gd);
1061+
1062+
drag(selectPath);
1063+
1064+
selectedPromise.then(function() {
1065+
expect(selectedCnt).toBe(1, 'with the correct selected count');
1066+
assertEventData(selectedData.points, [{
1067+
curveNumber: 0,
1068+
pointNumber: 0,
1069+
pointIndex: 0,
1070+
x: 0.002,
1071+
y: 16.25
1072+
}, {
1073+
curveNumber: 0,
1074+
pointNumber: 1,
1075+
pointIndex: 1,
1076+
x: 0.004,
1077+
y: 12.5
1078+
}], 'with the correct selected points (2)');
1079+
assertRange(selectedData.range, {
1080+
x: [0.002000, 0.0046236],
1081+
y: [0.10209191961595454, 24.512223978291406]
1082+
}, 'with the correct selected range');
1083+
1084+
return doubleClick(250, 200);
1085+
})
1086+
.then(deselectPromise)
1087+
.then(function() {
1088+
expect(doubleClickData).toBe(null, 'with the correct deselect data');
1089+
})
1090+
.then(done, done.fail);
1091+
});
1092+
1093+
it('should handle add/sub selection', function(done) {
1094+
resetEvents(gd);
1095+
expect(gd.layout.selections.length).toBe(1);
1096+
1097+
drag([[193, 193], [213, 193]], {shiftKey: true})
1098+
1099+
selectedPromise.then(function() {
1100+
expect(selectedCnt).toBe(1, 'with the correct selected count');
1101+
assertEventData(selectedData.points, [{
1102+
curveNumber: 0,
1103+
pointNumber: 4,
1104+
pointIndex: 4,
1105+
x: 0.013,
1106+
y: 6.875
1107+
}], 'with the correct selected points (1)');
1108+
})
1109+
.then(function() {
1110+
// this is not working here, but it works in the test dashboard, not sure why
1111+
// but at least this test shows us that no errors are thrown.
1112+
// expect(gd.layout.selections.length).toBe(2, 'fake selection is still there');
1113+
1114+
resetEvents(gd);
1115+
1116+
return doubleClick(250, 200);
1117+
})
1118+
.then(relayoutPromise)
1119+
.then(function() {
1120+
expect(gd.layout.selections.length).toBe(0, 'fake selection is cleared');
1121+
expect(doubleClickData).toBe(null, 'with the correct deselect data');
1122+
})
1123+
.then(done, done.fail);
1124+
});
1125+
1126+
it('should clear fake selections on doubleclick', function(done) {
1127+
resetEvents(gd);
1128+
1129+
doubleClick(250, 200);
1130+
1131+
relayoutPromise.then(function() {
1132+
expect(gd.layout.selections.length).toBe(0, 'fake selections are cleared');
1133+
})
1134+
.then(done, done.fail);
1135+
});
1136+
});
1137+
10381138
describe('lasso events', function() {
10391139
var mockCopy = Lib.extendDeep({}, mock);
10401140
mockCopy.layout.dragmode = 'lasso';

0 commit comments

Comments
 (0)