@@ -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