@@ -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' ) ;
@@ -116,7 +115,6 @@ function calc(gd, trace) {
116
115
opts . marker . snap = stash . tree || TOO_MANY_POINTS ;
117
116
}
118
117
119
- // save scene opts batch
120
118
scene . lineOptions . push ( opts . line ) ;
121
119
scene . errorXOptions . push ( opts . errorX ) ;
122
120
scene . errorYOptions . push ( opts . errorY ) ;
@@ -127,8 +125,9 @@ function calc(gd, trace) {
127
125
scene . textOptions . push ( opts . text ) ;
128
126
scene . textSelectedOptions . push ( opts . textSel ) ;
129
127
scene . textUnselectedOptions . push ( opts . textUnsel ) ;
128
+ scene . selectBatch . push ( [ ] ) ;
129
+ scene . unselectBatch . push ( [ ] ) ;
130
130
131
- // stash scene ref
132
131
stash . _scene = scene ;
133
132
stash . index = scene . count ;
134
133
stash . x = x ;
@@ -213,19 +212,20 @@ function sceneUpdate(gd, subplot) {
213
212
errorYOptions : [ ] ,
214
213
textOptions : [ ] ,
215
214
textSelectedOptions : [ ] ,
216
- textUnselectedOptions : [ ]
215
+ textUnselectedOptions : [ ] ,
216
+ // selection batches
217
+ selectBatch : [ ] ,
218
+ unselectBatch : [ ]
217
219
} ;
218
220
219
221
var initOpts = {
220
- selectBatch : null ,
221
- unselectBatch : null ,
222
222
// regl- component stubs, initialized in dirty plot call
223
223
fill2d : false ,
224
224
scatter2d : false ,
225
225
error2d : false ,
226
226
line2d : false ,
227
227
glText : false ,
228
- select2d : null
228
+ select2d : false
229
229
} ;
230
230
231
231
if ( ! subplot . _scene ) {
@@ -276,17 +276,22 @@ function sceneUpdate(gd, subplot) {
276
276
if ( scene . errorXOptions [ i ] ) error2d . draw ( i ) ;
277
277
if ( scene . errorYOptions [ i ] ) error2d . draw ( i + count ) ;
278
278
}
279
- if ( scatter2d && scene . markerOptions [ i ] && ( ! selectBatch || ! selectBatch [ i ] ) ) {
280
- scatter2d . draw ( i ) ;
279
+ if ( scatter2d && scene . markerOptions [ i ] ) {
280
+ if ( unselectBatch [ i ] . length ) {
281
+ var arg = Lib . repeat ( [ ] , scene . count ) ;
282
+ arg [ i ] = unselectBatch [ i ] ;
283
+ scatter2d . draw ( arg ) ;
284
+ } else {
285
+ scatter2d . draw ( i ) ;
286
+ }
281
287
}
282
288
if ( glText [ i ] && scene . textOptions [ i ] ) {
283
289
glText [ i ] . render ( ) ;
284
290
}
285
291
}
286
292
287
- if ( scatter2d && select2d && selectBatch ) {
293
+ if ( select2d ) {
288
294
select2d . draw ( selectBatch ) ;
289
- scatter2d . draw ( unselectBatch ) ;
290
295
}
291
296
292
297
scene . dirty = false ;
@@ -350,6 +355,7 @@ function plot(gd, subplot, cdata) {
350
355
351
356
var fullLayout = gd . _fullLayout ;
352
357
var scene = subplot . _scene ;
358
+ var count = scene . count ;
353
359
var xaxis = subplot . xaxis ;
354
360
var yaxis = subplot . yaxis ;
355
361
var i , j ;
@@ -383,28 +389,28 @@ function plot(gd, subplot, cdata) {
383
389
scene . fill2d = createLine ( regl ) ;
384
390
}
385
391
if ( scene . glText === true ) {
386
- scene . glText = new Array ( scene . count ) ;
387
- for ( i = 0 ; i < scene . count ; i ++ ) {
392
+ scene . glText = new Array ( count ) ;
393
+ for ( i = 0 ; i < count ; i ++ ) {
388
394
scene . glText [ i ] = new Text ( regl ) ;
389
395
}
390
396
}
391
397
392
398
// update main marker options
393
399
if ( scene . glText ) {
394
- if ( scene . count > scene . glText . length ) {
400
+ if ( count > scene . glText . length ) {
395
401
// add gl text marker
396
- var textsToAdd = scene . count - scene . glText . length ;
402
+ var textsToAdd = count - scene . glText . length ;
397
403
for ( i = 0 ; i < textsToAdd ; i ++ ) {
398
404
scene . glText . push ( new Text ( regl ) ) ;
399
405
}
400
- } else if ( scene . count < scene . glText . length ) {
406
+ } else if ( count < scene . glText . length ) {
401
407
// remove gl text marker
402
- var textsToRemove = scene . glText . length - scene . count ;
403
- var removedTexts = scene . glText . splice ( scene . count , textsToRemove ) ;
408
+ var textsToRemove = scene . glText . length - count ;
409
+ var removedTexts = scene . glText . splice ( count , textsToRemove ) ;
404
410
removedTexts . forEach ( function ( text ) { text . destroy ( ) ; } ) ;
405
411
}
406
412
407
- for ( i = 0 ; i < scene . count ; i ++ ) {
413
+ for ( i = 0 ; i < count ; i ++ ) {
408
414
scene . glText [ i ] . update ( scene . textOptions [ i ] ) ;
409
415
}
410
416
}
@@ -437,7 +443,7 @@ function plot(gd, subplot, cdata) {
437
443
}
438
444
439
445
// fill requires linked traces, so we generate it's positions here
440
- scene . fillOrder = Lib . repeat ( null , scene . count ) ;
446
+ scene . fillOrder = Lib . repeat ( null , count ) ;
441
447
if ( scene . fill2d ) {
442
448
scene . fillOptions = scene . fillOptions . map ( function ( fillOptions , i ) {
443
449
var cdscatter = cdata [ i ] ;
@@ -556,13 +562,11 @@ function plot(gd, subplot, cdata) {
556
562
}
557
563
558
564
// form batch arrays, and check for selected points
559
- scene . selectBatch = null ;
560
- scene . unselectBatch = null ;
561
565
var dragmode = fullLayout . dragmode ;
562
566
var selectMode = dragmode === 'lasso' || dragmode === 'select' ;
563
567
var clickSelectEnabled = fullLayout . clickmode . indexOf ( 'select' ) > - 1 ;
564
568
565
- for ( i = 0 ; i < cdata . length ; i ++ ) {
569
+ for ( i = 0 ; i < count ; i ++ ) {
566
570
var cd0 = cdata [ i ] [ 0 ] ;
567
571
var trace = cd0 . trace ;
568
572
var stash = cd0 . t ;
@@ -574,11 +578,6 @@ function plot(gd, subplot, cdata) {
574
578
if ( trace . selectedpoints || selectMode || clickSelectEnabled ) {
575
579
if ( ! selectMode ) selectMode = true ;
576
580
577
- if ( ! scene . selectBatch ) {
578
- scene . selectBatch = [ ] ;
579
- scene . unselectBatch = [ ] ;
580
- }
581
-
582
581
// regenerate scene batch, if traces number changed during selection
583
582
if ( trace . selectedpoints ) {
584
583
var selPts = scene . selectBatch [ index ] = Lib . selIndices2selPoints ( trace ) ;
@@ -610,21 +609,24 @@ function plot(gd, subplot, cdata) {
610
609
}
611
610
}
612
611
613
-
614
612
if ( selectMode ) {
615
- // create select2d
613
+ // create scatter instance by cloning scatter2d
616
614
if ( ! scene . select2d ) {
617
- // create scatter instance by cloning scatter2d
618
615
scene . select2d = createScatter ( fullLayout . _glcanvas . data ( ) [ 1 ] . regl ) ;
619
616
}
620
617
621
- if ( scene . scatter2d && scene . selectBatch && scene . selectBatch . length ) {
622
- // update only traces with selection
623
- scene . scatter2d . update ( scene . markerUnselectedOptions . map ( function ( opts , i ) {
624
- return scene . selectBatch [ i ] ? opts : null ;
625
- } ) ) ;
618
+ // use unselected styles on 'context' canvas
619
+ if ( scene . scatter2d ) {
620
+ var unselOpts = new Array ( count ) ;
621
+ for ( i = 0 ; i < count ; i ++ ) {
622
+ unselOpts [ i ] = scene . selectBatch [ i ] . length || scene . unselectBatch [ i ] . length ?
623
+ scene . markerUnselectedOptions [ i ] :
624
+ { } ;
625
+ }
626
+ scene . scatter2d . update ( unselOpts ) ;
626
627
}
627
628
629
+ // use selected style on 'focus' canvas
628
630
if ( scene . select2d ) {
629
631
scene . select2d . update ( scene . markerOptions ) ;
630
632
scene . select2d . update ( scene . markerSelectedOptions ) ;
@@ -639,9 +641,9 @@ function plot(gd, subplot, cdata) {
639
641
} ) ;
640
642
}
641
643
} else {
644
+ // reset 'context' scatter2d opts to base opts,
645
+ // thus unsetting markerUnselectedOptions from selection
642
646
if ( scene . scatter2d ) {
643
- // reset scatter2d opts to base opts,
644
- // thus unsetting markerUnselectedOptions from selection
645
647
scene . scatter2d . update ( scene . markerOptions ) ;
646
648
}
647
649
}
@@ -871,23 +873,23 @@ function selectPoints(searchInfo, selectionTester) {
871
873
var x = stash . x ;
872
874
var y = stash . y ;
873
875
var scene = stash . _scene ;
876
+ var index = stash . index ;
874
877
875
878
if ( ! scene ) return selection ;
876
879
877
880
var hasText = subTypes . hasText ( trace ) ;
878
881
var hasMarkers = subTypes . hasMarkers ( trace ) ;
879
882
var hasOnlyLines = ! hasMarkers && ! hasText ;
883
+
880
884
if ( trace . visible !== true || hasOnlyLines ) return selection ;
881
885
886
+ var els = [ ] ;
887
+ var unels = [ ] ;
888
+
882
889
// degenerate polygon does not enable selection
883
890
// filter out points by visible scatter ones
884
- var els = null ;
885
- var unels = null ;
886
- // FIXME: clearing selection does not work here
887
- var i ;
888
891
if ( selectionTester !== false && ! selectionTester . degenerate ) {
889
- els = [ ] , unels = [ ] ;
890
- for ( i = 0 ; i < len ; i ++ ) {
892
+ for ( var i = 0 ; i < len ; i ++ ) {
891
893
if ( selectionTester . contains ( [ stash . xpx [ i ] , stash . ypx [ i ] ] , false , i , searchInfo ) ) {
892
894
els . push ( i ) ;
893
895
selection . push ( {
@@ -899,32 +901,27 @@ function selectPoints(searchInfo, selectionTester) {
899
901
unels . push ( i ) ;
900
902
}
901
903
}
902
- } else {
903
- unels = arrayRange ( len ) ;
904
904
}
905
905
906
- // make sure selectBatch is created
907
- if ( ! scene . selectBatch ) {
908
- scene . selectBatch = [ ] ;
909
- scene . unselectBatch = [ ] ;
910
- }
906
+ if ( hasMarkers ) {
907
+ var scatter2d = scene . scatter2d ;
911
908
912
- if ( ! scene . selectBatch [ stash . index ] ) {
913
- // enter every trace select mode
914
- for ( i = 0 ; i < scene . count ; i ++ ) {
915
- scene . selectBatch [ i ] = [ ] ;
916
- scene . unselectBatch [ i ] = [ ] ;
917
- }
918
- // we should turn scatter2d into unselected once we have any points selected
919
- if ( hasMarkers ) {
920
- scene . scatter2d . update ( scene . markerUnselectedOptions ) ;
909
+ if ( ! scene . selectBatch [ 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
+ } else if ( ! els . length && ! unels . length ) {
915
+ // reset to base styles when clearing
916
+ var baseOpts = new Array ( scene . count ) ;
917
+ baseOpts [ index ] = scene . markerOptions [ index ] ;
918
+ scatter2d . update . apply ( scatter2d , baseOpts ) ;
921
919
}
922
920
}
923
921
924
- scene . selectBatch [ stash . index ] = els ;
925
- scene . unselectBatch [ stash . index ] = unels ;
922
+ scene . selectBatch [ index ] = els ;
923
+ scene . unselectBatch [ index ] = unels ;
926
924
927
- // update text options
928
925
if ( hasText ) {
929
926
styleTextSelection ( cd ) ;
930
927
}
@@ -946,7 +943,7 @@ function styleTextSelection(cd) {
946
943
var opts = Lib . extendFlat ( { } , baseOpts ) ;
947
944
var i , j ;
948
945
949
- if ( els && unels ) {
946
+ if ( els . length || unels . length ) {
950
947
var stc = selOpts . color ;
951
948
var utc = unselOpts . color ;
952
949
var base = baseOpts . color ;
0 commit comments