@@ -12,7 +12,6 @@ var createScatter = require('regl-scatter2d');
12
12
var createLine = require ( 'regl-line2d' ) ;
13
13
var createError = require ( 'regl-error2d' ) ;
14
14
var cluster = require ( 'point-cluster' ) ;
15
- var arrayRange = require ( 'array-range' ) ;
16
15
var Text = require ( 'gl-text' ) ;
17
16
18
17
var Registry = require ( '../../registry' ) ;
@@ -126,6 +125,8 @@ function calc(gd, trace) {
126
125
scene . textOptions . push ( opts . text ) ;
127
126
scene . textSelectedOptions . push ( opts . textSel ) ;
128
127
scene . textUnselectedOptions . push ( opts . textUnsel ) ;
128
+ scene . selectBatch . push ( [ ] ) ;
129
+ scene . unselectBatch . push ( [ ] ) ;
129
130
130
131
stash . _scene = scene ;
131
132
stash . index = scene . count ;
@@ -209,13 +210,14 @@ function sceneUpdate(gd, subplot) {
209
210
errorYOptions : [ ] ,
210
211
textOptions : [ ] ,
211
212
textSelectedOptions : [ ] ,
212
- textUnselectedOptions : [ ]
213
+ textUnselectedOptions : [ ] ,
214
+ // selection batches
215
+ selectBatch : [ ] ,
216
+ unselectBatch : [ ]
213
217
} ;
214
218
215
219
// regl- component stubs, initialized in dirty plot call
216
220
var initOpts = {
217
- selectBatch : null ,
218
- unselectBatch : null ,
219
221
fill2d : false ,
220
222
scatter2d : false ,
221
223
error2d : false ,
@@ -272,17 +274,22 @@ function sceneUpdate(gd, subplot) {
272
274
if ( scene . errorXOptions [ i ] ) error2d . draw ( i ) ;
273
275
if ( scene . errorYOptions [ i ] ) error2d . draw ( i + count ) ;
274
276
}
275
- if ( scatter2d && scene . markerOptions [ i ] && ( ! selectBatch || ! selectBatch [ i ] ) ) {
276
- scatter2d . draw ( i ) ;
277
+ if ( scatter2d && scene . markerOptions [ i ] ) {
278
+ if ( unselectBatch [ i ] . length ) {
279
+ var arg = Lib . repeat ( [ ] , scene . count ) ;
280
+ arg [ i ] = unselectBatch [ i ] ;
281
+ scatter2d . draw ( arg ) ;
282
+ } else if ( ! selectBatch [ i ] . length ) {
283
+ scatter2d . draw ( i ) ;
284
+ }
277
285
}
278
286
if ( glText [ i ] && scene . textOptions [ i ] ) {
279
287
glText [ i ] . render ( ) ;
280
288
}
281
289
}
282
290
283
- if ( scatter2d && select2d && selectBatch ) {
291
+ if ( select2d ) {
284
292
select2d . draw ( selectBatch ) ;
285
- scatter2d . draw ( unselectBatch ) ;
286
293
}
287
294
288
295
scene . dirty = false ;
@@ -553,8 +560,6 @@ function plot(gd, subplot, cdata) {
553
560
}
554
561
555
562
// form batch arrays, and check for selected points
556
- scene . selectBatch = null ;
557
- scene . unselectBatch = null ;
558
563
var dragmode = fullLayout . dragmode ;
559
564
var selectMode = dragmode === 'lasso' || dragmode === 'select' ;
560
565
var clickSelectEnabled = fullLayout . clickmode . indexOf ( 'select' ) > - 1 ;
@@ -571,11 +576,6 @@ function plot(gd, subplot, cdata) {
571
576
if ( trace . selectedpoints || selectMode || clickSelectEnabled ) {
572
577
if ( ! selectMode ) selectMode = true ;
573
578
574
- if ( ! scene . selectBatch ) {
575
- scene . selectBatch = [ ] ;
576
- scene . unselectBatch = [ ] ;
577
- }
578
-
579
579
// regenerate scene batch, if traces number changed during selection
580
580
if ( trace . selectedpoints ) {
581
581
var selPts = scene . selectBatch [ index ] = Lib . selIndices2selPoints ( trace ) ;
@@ -613,13 +613,18 @@ function plot(gd, subplot, cdata) {
613
613
scene . select2d = createScatter ( fullLayout . _glcanvas . data ( ) [ 1 ] . regl ) ;
614
614
}
615
615
616
- if ( scene . scatter2d && scene . selectBatch && scene . selectBatch . length ) {
617
- // update only traces with selection
618
- scene . scatter2d . update ( scene . markerUnselectedOptions . map ( function ( opts , i ) {
619
- return scene . selectBatch [ i ] ? opts : null ;
620
- } ) ) ;
616
+ // use unselected styles on 'context' canvas
617
+ if ( scene . scatter2d ) {
618
+ var unselOpts = new Array ( count ) ;
619
+ for ( i = 0 ; i < count ; i ++ ) {
620
+ unselOpts [ i ] = scene . selectBatch [ i ] . length || scene . unselectBatch [ i ] . length ?
621
+ scene . markerUnselectedOptions [ i ] :
622
+ { } ;
623
+ }
624
+ scene . scatter2d . update ( unselOpts ) ;
621
625
}
622
626
627
+ // use selected style on 'focus' canvas
623
628
if ( scene . select2d ) {
624
629
scene . select2d . update ( scene . markerOptions ) ;
625
630
scene . select2d . update ( scene . markerSelectedOptions ) ;
@@ -854,7 +859,6 @@ function calcHover(pointData, x, y, trace) {
854
859
return pointData ;
855
860
}
856
861
857
-
858
862
function selectPoints ( searchInfo , selectionTester ) {
859
863
var cd = searchInfo . cd ;
860
864
var selection = [ ] ;
@@ -864,23 +868,23 @@ function selectPoints(searchInfo, selectionTester) {
864
868
var x = stash . x ;
865
869
var y = stash . y ;
866
870
var scene = stash . _scene ;
871
+ var index = stash . index ;
867
872
868
873
if ( ! scene ) return selection ;
869
874
870
875
var hasText = subTypes . hasText ( trace ) ;
871
876
var hasMarkers = subTypes . hasMarkers ( trace ) ;
872
877
var hasOnlyLines = ! hasMarkers && ! hasText ;
878
+
873
879
if ( trace . visible !== true || hasOnlyLines ) return selection ;
874
880
881
+ var els = [ ] ;
882
+ var unels = [ ] ;
883
+
875
884
// degenerate polygon does not enable selection
876
885
// filter out points by visible scatter ones
877
- var els = null ;
878
- var unels = null ;
879
- // FIXME: clearing selection does not work here
880
- var i ;
881
886
if ( selectionTester !== false && ! selectionTester . degenerate ) {
882
- els = [ ] , unels = [ ] ;
883
- for ( i = 0 ; i < len ; i ++ ) {
887
+ for ( var i = 0 ; i < len ; i ++ ) {
884
888
if ( selectionTester . contains ( [ stash . xpx [ i ] , stash . ypx [ i ] ] , false , i , searchInfo ) ) {
885
889
els . push ( i ) ;
886
890
selection . push ( {
@@ -892,30 +896,26 @@ function selectPoints(searchInfo, selectionTester) {
892
896
unels . push ( i ) ;
893
897
}
894
898
}
895
- } else {
896
- unels = arrayRange ( len ) ;
897
899
}
898
900
899
- // make sure selectBatch is created
900
- if ( ! scene . selectBatch ) {
901
- scene . selectBatch = [ ] ;
902
- scene . unselectBatch = [ ] ;
903
- }
901
+ if ( hasMarkers ) {
902
+ var scatter2d = scene . scatter2d ;
904
903
905
- if ( ! scene . selectBatch [ stash . index ] ) {
906
- // enter every trace select mode
907
- for ( i = 0 ; i < scene . count ; i ++ ) {
908
- scene . selectBatch [ i ] = [ ] ;
909
- scene . unselectBatch [ i ] = [ ] ;
910
- }
911
- // we should turn scatter2d into unselected once we have any points selected
912
- if ( hasMarkers ) {
913
- scene . scatter2d . update ( scene . markerUnselectedOptions ) ;
904
+ if ( ! els . length && ! unels . length ) {
905
+ // reset to base styles when clearing
906
+ var baseOpts = new Array ( scene . count ) ;
907
+ baseOpts [ index ] = scene . markerOptions [ index ] ;
908
+ scatter2d . update . apply ( scatter2d , baseOpts ) ;
909
+ } else if ( ! scene . selectBatch [ index ] . length && ! scene . unselectBatch [ index ] . length ) {
910
+ // set unselected styles on 'context' canvas (if not done already)
911
+ var unselOpts = new Array ( scene . count ) ;
912
+ unselOpts [ index ] = scene . markerUnselectedOptions [ index ] ;
913
+ scatter2d . update . apply ( scatter2d , unselOpts ) ;
914
914
}
915
915
}
916
916
917
- scene . selectBatch [ stash . index ] = els ;
918
- scene . unselectBatch [ stash . index ] = unels ;
917
+ scene . selectBatch [ index ] = els ;
918
+ scene . unselectBatch [ index ] = unels ;
919
919
920
920
if ( hasText ) {
921
921
styleTextSelection ( cd ) ;
@@ -938,7 +938,7 @@ function styleTextSelection(cd) {
938
938
var opts = Lib . extendFlat ( { } , baseOpts ) ;
939
939
var i , j ;
940
940
941
- if ( els && unels ) {
941
+ if ( els . length || unels . length ) {
942
942
var stc = selOpts . color ;
943
943
var utc = unselOpts . color ;
944
944
var base = baseOpts . color ;
0 commit comments