Skip to content

Commit c331266

Browse files
committed
Unify selection mode
1 parent 28f7ea2 commit c331266

File tree

3 files changed

+83
-60
lines changed

3 files changed

+83
-60
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"3d-view": "^2.0.0",
5858
"@plotly/d3-sankey": "^0.5.0",
5959
"alpha-shape": "^1.0.0",
60+
"array-range": "^1.0.1",
6061
"bubleify": "^1.0.0",
6162
"canvas-fit": "^1.5.0",
6263
"color-normalize": "^1.0.3",
@@ -98,7 +99,7 @@
9899
"regl": "^1.3.1",
99100
"regl-error2d": "^2.0.3",
100101
"regl-line2d": "^2.1.2",
101-
"regl-scatter2d": "^2.1.12",
102+
"regl-scatter2d": "^2.1.13",
102103
"right-now": "^1.0.0",
103104
"robust-orientation": "^1.1.3",
104105
"sane-topojson": "^2.0.0",

src/plots/cartesian/select.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) {
278278
else {
279279
// TODO: remove in v2 - this was probably never intended to work as it does,
280280
// but in case anyone depends on it we don't want to break it now.
281-
gd.emit('plotly_selected', undefined);
281+
gd.emit('plotly_selected', {points: [], range: null});
282282
}
283283

284284
Fx.click(gd, evt);

src/traces/scattergl/index.js

Lines changed: 80 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var createError = require('regl-error2d');
2828
var rgba = require('color-normalize');
2929
var svgSdf = require('svg-path-sdf');
3030
var createRegl = require('regl');
31+
var arrayRange = require('array-range');
3132
var fillHoverText = require('../scatter/fill_hover_text');
3233
var isNumeric = require('fast-isnumeric');
3334

@@ -122,7 +123,6 @@ function calc(container, trace) {
122123
}
123124
}
124125

125-
126126
calcColorscales(trace);
127127

128128
var options = sceneOptions(container, subplot, trace, positions);
@@ -599,6 +599,7 @@ function sceneUpdate(container, subplot) {
599599
scene.error2d.draw(i);
600600
scene.error2d.draw(i + scene.count);
601601
}
602+
602603
if(scene.scatter2d && !scene.selectBatch) {
603604
scene.scatter2d.draw(i);
604605
}
@@ -740,8 +741,9 @@ function plot(container, subplot, cdata) {
740741
if(!cdata.length) return;
741742

742743
var layout = container._fullLayout;
743-
var stash = cdata[0][0].t;
744-
var scene = stash.scene;
744+
var scene = cdata[0][0].t.scene;
745+
var i;
746+
var dragmode = layout.dragmode;
745747

746748
// we may have more subplots than initialized data due to Axes.getSubplots method
747749
if(!scene) return;
@@ -782,6 +784,7 @@ function plot(container, subplot, cdata) {
782784
scene.fill2d = createLine(regl);
783785
}
784786

787+
// update main marker options
785788
if(scene.line2d) {
786789
scene.line2d.update(scene.lineOptions);
787790
}
@@ -790,13 +793,7 @@ function plot(container, subplot, cdata) {
790793
scene.error2d.update(errorBatch);
791794
}
792795
if(scene.scatter2d) {
793-
if(!scene.selectBatch) {
794-
scene.scatter2d.update(scene.markerOptions);
795-
}
796-
else {
797-
scene.scatter2d.update(scene.unselectedOptions);
798-
scene.select2d.update(scene.selectedOptions);
799-
}
796+
scene.scatter2d.update(scene.markerOptions);
800797
}
801798
// fill requires linked traces, so we generate it's positions here
802799
if(scene.fill2d) {
@@ -886,17 +883,77 @@ function plot(container, subplot, cdata) {
886883

887884
scene.fill2d.update(scene.fillOptions);
888885
}
889-
}
890886

891-
// make sure selection layer is initialized if we require selection
892-
var dragmode = layout.dragmode;
893887

894-
if(dragmode === 'lasso' || dragmode === 'select') {
895-
if(scene.select2d && scene.selectBatch) {
896-
scene.scatter2d.update(scene.unselectedOptions);
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);
897953
}
898954
}
899955

956+
900957
// provide viewport and range
901958
var vpRange = cdata.map(function(cdscatter) {
902959
if(!cdscatter || !cdscatter[0] || !cdscatter[0].trace) return;
@@ -925,41 +982,6 @@ function plot(container, subplot, cdata) {
925982
];
926983

927984
if(trace.selectedpoints || dragmode === 'lasso' || dragmode === 'select') {
928-
// create select2d
929-
if(!scene.select2d && scene.scatter2d) {
930-
var selectRegl = layout._glcanvas.data()[1].regl;
931-
932-
// create scatter instance by cloning scatter2d
933-
scene.select2d = createScatter(selectRegl, {clone: scene.scatter2d});
934-
scene.select2d.update(scene.selectedOptions);
935-
936-
// create selection style once we have something selected
937-
if(trace.selectedpoints && !scene.selectBatch) {
938-
scene.selectBatch = Array(scene.count);
939-
scene.unselectBatch = Array(scene.count);
940-
scene.scatter2d.update(scene.unselectedOptions);
941-
}
942-
}
943-
else {
944-
// update selection positions, since they may have changed by panning or alike
945-
scene.select2d.update(scene.selectedOptions);
946-
}
947-
948-
// form unselected batch
949-
if(trace.selectedpoints && !scene.unselectBatch[stash.index]) {
950-
scene.selectBatch[stash.index] = trace.selectedpoints;
951-
var selPts = trace.selectedpoints;
952-
var selDict = {};
953-
for(i = 0; i < selPts.length; i++) {
954-
selDict[selPts[i]] = true;
955-
}
956-
var unselPts = [];
957-
for(i = 0; i < stash.count; i++) {
958-
if(!selDict[i]) unselPts.push(i);
959-
}
960-
scene.unselectBatch[stash.index] = unselPts;
961-
}
962-
963985
// precalculate px coords since we are not going to pan during select
964986
var xpx = Array(stash.count), ypx = Array(stash.count);
965987
for(i = 0; i < stash.count; i++) {
@@ -1193,18 +1215,18 @@ function selectPoints(searchInfo, polygon) {
11931215
}
11941216
}
11951217
else {
1196-
unels = Array(stash.count);
1197-
for(i = 0; i < stash.count; i++) {
1198-
unels[i] = i;
1199-
}
1218+
unels = arrayRange(stash.count);
12001219
}
12011220

1202-
// create selection style once we have something selected
1221+
// make sure selectBatch is created
12031222
if(!scene.selectBatch) {
1204-
scene.selectBatch = Array(scene.count);
1205-
scene.unselectBatch = Array(scene.count);
1223+
scene.selectBatch = [];
1224+
scene.unselectBatch = [];
1225+
1226+
// we should turn scatter2d into unselected once we have any points selected
12061227
scene.scatter2d.update(scene.unselectedOptions);
12071228
}
1229+
12081230
scene.selectBatch[stash.index] = els;
12091231
scene.unselectBatch[stash.index] = unels;
12101232

0 commit comments

Comments
 (0)