@@ -28,6 +28,7 @@ var createError = require('regl-error2d');
28
28
var rgba = require ( 'color-normalize' ) ;
29
29
var svgSdf = require ( 'svg-path-sdf' ) ;
30
30
var createRegl = require ( 'regl' ) ;
31
+ var arrayRange = require ( 'array-range' ) ;
31
32
var fillHoverText = require ( '../scatter/fill_hover_text' ) ;
32
33
var isNumeric = require ( 'fast-isnumeric' ) ;
33
34
@@ -122,7 +123,6 @@ function calc(container, trace) {
122
123
}
123
124
}
124
125
125
-
126
126
calcColorscales ( trace ) ;
127
127
128
128
var options = sceneOptions ( container , subplot , trace , positions ) ;
@@ -396,7 +396,9 @@ function sceneOptions(container, subplot, trace, positions) {
396
396
function makeSelectedOptions ( selected , markerOpts ) {
397
397
var options = { } ;
398
398
399
- if ( selected . marker . symbol ) {
399
+ if ( ! selected ) return options ;
400
+
401
+ if ( selected . marker && selected . marker . symbol ) {
400
402
options = makeMarkerOptions ( extend ( { } , markerOpts , selected . marker ) ) ;
401
403
}
402
404
@@ -599,12 +601,15 @@ function sceneUpdate(container, subplot) {
599
601
scene . error2d . draw ( i ) ;
600
602
scene . error2d . draw ( i + scene . count ) ;
601
603
}
602
- if ( scene . scatter2d && ! scene . selectBatch ) {
603
- 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
+ }
604
609
}
605
610
}
606
611
607
- // persistent selection draw
612
+ // draw traces in selection mode
608
613
if ( scene . select2d && scene . selectBatch ) {
609
614
scene . select2d . draw ( scene . selectBatch ) ;
610
615
scene . scatter2d . draw ( scene . unselectBatch ) ;
@@ -740,8 +745,8 @@ function plot(container, subplot, cdata) {
740
745
if ( ! cdata . length ) return ;
741
746
742
747
var layout = container . _fullLayout ;
743
- var stash = cdata [ 0 ] [ 0 ] . t ;
744
- var scene = stash . scene ;
748
+ var scene = cdata [ 0 ] [ 0 ] . t . scene ;
749
+ var dragmode = layout . dragmode ;
745
750
746
751
// we may have more subplots than initialized data due to Axes.getSubplots method
747
752
if ( ! scene ) return ;
@@ -782,6 +787,7 @@ function plot(container, subplot, cdata) {
782
787
scene . fill2d = createLine ( regl ) ;
783
788
}
784
789
790
+ // update main marker options
785
791
if ( scene . line2d ) {
786
792
scene . line2d . update ( scene . lineOptions ) ;
787
793
}
@@ -790,13 +796,7 @@ function plot(container, subplot, cdata) {
790
796
scene . error2d . update ( errorBatch ) ;
791
797
}
792
798
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
- }
799
+ scene . scatter2d . update ( scene . markerOptions ) ;
800
800
}
801
801
// fill requires linked traces, so we generate it's positions here
802
802
if ( scene . fill2d ) {
@@ -888,21 +888,15 @@ function plot(container, subplot, cdata) {
888
888
}
889
889
}
890
890
891
- // make sure selection layer is initialized if we require selection
892
- var dragmode = layout . dragmode ;
893
-
894
- if ( dragmode === 'lasso' || dragmode === 'select' ) {
895
- if ( scene . select2d && scene . selectBatch ) {
896
- scene . scatter2d . update ( scene . unselectedOptions ) ;
897
- }
898
- }
891
+ var selectMode = dragmode === 'lasso' || dragmode === 'select' ;
899
892
900
893
// provide viewport and range
901
894
var vpRange = cdata . map ( function ( cdscatter ) {
902
895
if ( ! cdscatter || ! cdscatter [ 0 ] || ! cdscatter [ 0 ] . trace ) return ;
903
896
var cd = cdscatter [ 0 ] ;
904
897
var trace = cd . trace ;
905
898
var stash = cd . t ;
899
+ var id = stash . index ;
906
900
var x = stash . rawx ,
907
901
y = stash . rawy ;
908
902
@@ -924,30 +918,16 @@ function plot(container, subplot, cdata) {
924
918
( height - vpSize . t ) - ( 1 - yaxis . domain [ 1 ] ) * vpSize . h
925
919
] ;
926
920
927
- if ( trace . selectedpoints || dragmode === 'lasso' || dragmode === 'select' ) {
928
- // create select2d
929
- if ( ! scene . select2d && scene . scatter2d ) {
930
- var selectRegl = layout . _glcanvas . data ( ) [ 1 ] . regl ;
921
+ if ( trace . selectedpoints || selectMode ) {
922
+ if ( ! selectMode ) selectMode = true ;
931
923
932
- // create scatter instance by cloning scatter2d
933
- scene . select2d = createScatter ( selectRegl , { clone : scene . scatter2d } ) ;
934
- scene . select2d . update ( scene . selectedOptions ) ;
924
+ if ( ! scene . selectBatch ) scene . selectBatch = [ ] ;
925
+ if ( ! scene . unselectBatch ) scene . unselectBatch = [ ] ;
935
926
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
- }
927
+ // regenerate scene batch, if traces number changed during selection
928
+ if ( trace . selectedpoints ) {
929
+ scene . selectBatch [ id ] = trace . selectedpoints ;
947
930
948
- // form unselected batch
949
- if ( trace . selectedpoints && ! scene . unselectBatch [ stash . index ] ) {
950
- scene . selectBatch [ stash . index ] = trace . selectedpoints ;
951
931
var selPts = trace . selectedpoints ;
952
932
var selDict = { } ;
953
933
for ( i = 0 ; i < selPts . length ; i ++ ) {
@@ -957,7 +937,7 @@ function plot(container, subplot, cdata) {
957
937
for ( i = 0 ; i < stash . count ; i ++ ) {
958
938
if ( ! selDict [ i ] ) unselPts . push ( i ) ;
959
939
}
960
- scene . unselectBatch [ stash . index ] = unselPts ;
940
+ scene . unselectBatch [ id ] = unselPts ;
961
941
}
962
942
963
943
// precalculate px coords since we are not going to pan during select
@@ -979,6 +959,21 @@ function plot(container, subplot, cdata) {
979
959
} : null ;
980
960
} ) ;
981
961
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
+
982
977
// uploat viewport/range data to GPU
983
978
if ( scene . fill2d ) {
984
979
scene . fill2d . update ( vpRange ) ;
@@ -1193,18 +1188,25 @@ function selectPoints(searchInfo, polygon) {
1193
1188
}
1194
1189
}
1195
1190
else {
1196
- unels = Array ( stash . count ) ;
1197
- for ( i = 0 ; i < stash . count ; i ++ ) {
1198
- unels [ i ] = i ;
1199
- }
1191
+ unels = arrayRange ( stash . count ) ;
1200
1192
}
1201
1193
1202
- // create selection style once we have something selected
1194
+ // make sure selectBatch is created
1203
1195
if ( ! scene . selectBatch ) {
1204
- scene . selectBatch = Array ( scene . count ) ;
1205
- scene . unselectBatch = Array ( scene . count ) ;
1196
+ scene . selectBatch = [ ] ;
1197
+ scene . unselectBatch = [ ] ;
1198
+ }
1199
+
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
+ }
1206
+ // we should turn scatter2d into unselected once we have any points selected
1206
1207
scene . scatter2d . update ( scene . unselectedOptions ) ;
1207
1208
}
1209
+
1208
1210
scene . selectBatch [ stash . index ] = els ;
1209
1211
scene . unselectBatch [ stash . index ] = unels ;
1210
1212
0 commit comments