Skip to content

Commit ab5f6f0

Browse files
committed
Make selection per-trace instead of per-plot
1 parent 4e66ff5 commit ab5f6f0

File tree

1 file changed

+55
-75
lines changed

1 file changed

+55
-75
lines changed

src/traces/scattergl/index.js

+55-75
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,9 @@ function sceneOptions(container, subplot, trace, positions) {
396396
function makeSelectedOptions(selected, markerOpts) {
397397
var options = {};
398398

399-
if(selected.marker.symbol) {
399+
if(!selected) return options;
400+
401+
if(selected.marker && selected.marker.symbol) {
400402
options = makeMarkerOptions(extend({}, markerOpts, selected.marker));
401403
}
402404

@@ -599,13 +601,15 @@ function sceneUpdate(container, subplot) {
599601
scene.error2d.draw(i);
600602
scene.error2d.draw(i + scene.count);
601603
}
602-
603-
if(scene.scatter2d && !scene.selectBatch) {
604-
scene.scatter2d.draw(i);
604+
if(scene.scatter2d) {
605+
// traces in no-selection mode
606+
if(!scene.selectBatch || !scene.selectBatch[i]) {
607+
scene.scatter2d.draw(i);
608+
}
605609
}
606610
}
607611

608-
// persistent selection draw
612+
// draw traces in selection mode
609613
if(scene.select2d && scene.selectBatch) {
610614
scene.select2d.draw(scene.selectBatch);
611615
scene.scatter2d.draw(scene.unselectBatch);
@@ -742,7 +746,6 @@ function plot(container, subplot, cdata) {
742746

743747
var layout = container._fullLayout;
744748
var scene = cdata[0][0].t.scene;
745-
var i;
746749
var dragmode = layout.dragmode;
747750

748751
// we may have more subplots than initialized data due to Axes.getSubplots method
@@ -883,83 +886,17 @@ function plot(container, subplot, cdata) {
883886

884887
scene.fill2d.update(scene.fillOptions);
885888
}
886-
887-
888-
// update selection
889-
var hasSelectedPoints = false;
890-
for(i = 0; i < cdata.length; i++) {
891-
if(cdata[i][0].trace.selectedpoints) {
892-
hasSelectedPoints = true;
893-
break;
894-
}
895-
}
896-
897-
if(scene.selectBatch || dragmode === 'lasso' || dragmode === 'select' || hasSelectedPoints) {
898-
var newSelectBatch, newUnselectBatch;
899-
900-
// create select2d
901-
if(!scene.select2d) {
902-
// create scatter instance by cloning scatter2d
903-
scene.select2d = createScatter(layout._glcanvas.data()[1].regl, {clone: scene.scatter2d});
904-
}
905-
906-
// regenerate scene batch, if traces number changed during selection
907-
if(scene.selectBatch || hasSelectedPoints) {
908-
if(!scene.selectBatch) scene.selectBatch = [];
909-
if(!scene.unselectBatch) scene.unselectBatch = [];
910-
911-
newSelectBatch = Array(scene.count);
912-
newUnselectBatch = Array(scene.count);
913-
914-
for(var j = 0; j < newSelectBatch.length; j++) {
915-
var trace = cdata[j][0].trace;
916-
var stash = cdata[j][0].t;
917-
var id = stash.index;
918-
919-
// form unselected batch
920-
if(!scene.unselectBatch[id]) {
921-
if(trace.selectedpoints) {
922-
newSelectBatch[id] = trace.selectedpoints;
923-
var selPts = trace.selectedpoints;
924-
var selDict = {};
925-
for(i = 0; i < selPts.length; i++) {
926-
selDict[selPts[i]] = true;
927-
}
928-
var unselPts = [];
929-
for(i = 0; i < stash.count; i++) {
930-
if(!selDict[i]) unselPts.push(i);
931-
}
932-
newUnselectBatch[id] = unselPts;
933-
}
934-
else {
935-
newSelectBatch[id] = [];
936-
newUnselectBatch[id] = arrayRange(stash.count);
937-
}
938-
}
939-
else {
940-
newSelectBatch[id] = scene.selectBatch[id];
941-
newUnselectBatch[id] = scene.unselectBatch[id];
942-
}
943-
}
944-
945-
scene.selectBatch = newSelectBatch;
946-
scene.unselectBatch = newUnselectBatch;
947-
948-
scene.scatter2d.update(scene.unselectedOptions);
949-
}
950-
951-
scene.select2d.update(scene.markerOptions);
952-
scene.select2d.update(scene.selectedOptions);
953-
}
954889
}
955890

891+
var selectMode = dragmode === 'lasso' || dragmode === 'select';
956892

957893
// provide viewport and range
958894
var vpRange = cdata.map(function(cdscatter) {
959895
if(!cdscatter || !cdscatter[0] || !cdscatter[0].trace) return;
960896
var cd = cdscatter[0];
961897
var trace = cd.trace;
962898
var stash = cd.t;
899+
var id = stash.index;
963900
var x = stash.rawx,
964901
y = stash.rawy;
965902

@@ -981,7 +918,28 @@ function plot(container, subplot, cdata) {
981918
(height - vpSize.t) - (1 - yaxis.domain[1]) * vpSize.h
982919
];
983920

984-
if(trace.selectedpoints || dragmode === 'lasso' || dragmode === 'select') {
921+
if(trace.selectedpoints || selectMode) {
922+
if(!selectMode) selectMode = true;
923+
924+
if(!scene.selectBatch) scene.selectBatch = [];
925+
if(!scene.unselectBatch) scene.unselectBatch = [];
926+
927+
// regenerate scene batch, if traces number changed during selection
928+
if(trace.selectedpoints) {
929+
scene.selectBatch[id] = trace.selectedpoints;
930+
931+
var selPts = trace.selectedpoints;
932+
var selDict = {};
933+
for(i = 0; i < selPts.length; i++) {
934+
selDict[selPts[i]] = true;
935+
}
936+
var unselPts = [];
937+
for(i = 0; i < stash.count; i++) {
938+
if(!selDict[i]) unselPts.push(i);
939+
}
940+
scene.unselectBatch[id] = unselPts;
941+
}
942+
985943
// precalculate px coords since we are not going to pan during select
986944
var xpx = Array(stash.count), ypx = Array(stash.count);
987945
for(i = 0; i < stash.count; i++) {
@@ -1001,6 +959,21 @@ function plot(container, subplot, cdata) {
1001959
} : null;
1002960
});
1003961

962+
if(selectMode) {
963+
// create select2d
964+
if(!scene.select2d) {
965+
// create scatter instance by cloning scatter2d
966+
scene.select2d = createScatter(layout._glcanvas.data()[1].regl, {clone: scene.scatter2d});
967+
}
968+
969+
// update only traces with selection
970+
scene.scatter2d.update(scene.unselectedOptions.map(function(opts, i) {
971+
return scene.selectBatch[i] ? opts : null;
972+
}));
973+
scene.select2d.update(scene.markerOptions);
974+
scene.select2d.update(scene.selectedOptions);
975+
}
976+
1004977
// uploat viewport/range data to GPU
1005978
if(scene.fill2d) {
1006979
scene.fill2d.update(vpRange);
@@ -1222,7 +1195,14 @@ function selectPoints(searchInfo, polygon) {
12221195
if(!scene.selectBatch) {
12231196
scene.selectBatch = [];
12241197
scene.unselectBatch = [];
1198+
}
12251199

1200+
if(!scene.selectBatch[stash.index]) {
1201+
// enter every trace select mode
1202+
for(i = 0; i < scene.count; i++) {
1203+
scene.selectBatch[i] = [];
1204+
scene.unselectBatch[i] = [];
1205+
}
12261206
// we should turn scatter2d into unselected once we have any points selected
12271207
scene.scatter2d.update(scene.unselectedOptions);
12281208
}

0 commit comments

Comments
 (0)