@@ -14,6 +14,7 @@ var assertHoverLabelContent = customAssertions.assertHoverLabelContent;
14
14
// from the mousemove events and then simulate
15
15
// a click event on mouseup
16
16
var click = require ( '../assets/timed_click' ) ;
17
+ var doubleClick = require ( '../assets/double_click' ) ;
17
18
var hover = require ( '../assets/hover' ) ;
18
19
var delay = require ( '../assets/delay' ) ;
19
20
var mouseEvent = require ( '../assets/mouse_event' ) ;
@@ -963,4 +964,174 @@ describe('@noCI @gl Test gl2d lasso/select:', function() {
963
964
. catch ( failTest )
964
965
. then ( done ) ;
965
966
} ) ;
967
+
968
+ it ( 'should behave correctly during select+doubleclick+pan scenarios' , function ( done ) {
969
+ gd = createGraphDiv ( ) ;
970
+
971
+ // See https://github.com/plotly/plotly.js/issues/2767
972
+
973
+ function grabScene ( ) {
974
+ return gd . calcdata [ 0 ] [ 0 ] . t . _scene ;
975
+ }
976
+
977
+ function _assert ( msg , exp ) {
978
+ var scene = grabScene ( ) ;
979
+ var scatter2d = scene . scatter2d ;
980
+
981
+ expect ( ( scene . markerOptions || [ ] ) [ 0 ] . opacity )
982
+ . toBe ( 1 , 'marker.opacity - ' + msg ) ;
983
+ expect ( ( scene . markerSelectedOptions || [ ] ) [ 0 ] . opacity )
984
+ . toBe ( 1 , 'selected.marker.opacity - ' + msg ) ;
985
+ expect ( ( scene . markerUnselectedOptions || [ ] ) [ 0 ] . opacity )
986
+ . toBe ( 0.2 , 'unselected.marker.opacity - ' + msg ) ;
987
+
988
+ expect ( scene . selectBatch ) . toEqual ( exp . selectBatch ) ;
989
+ expect ( scene . unselectBatch ) . toEqual ( exp . unselectBatch ) ;
990
+
991
+ var updateCalls = scatter2d . update . calls . all ( ) ;
992
+ var drawCalls = scatter2d . draw . calls . all ( ) ;
993
+
994
+ expect ( updateCalls . length ) . toBe (
995
+ exp . updateArgs . length ,
996
+ 'scatter2d.update has been called the correct number of times - ' + msg
997
+ ) ;
998
+ updateCalls . forEach ( function ( d , i ) {
999
+ d . args . forEach ( function ( arg , j ) {
1000
+ if ( 'range' in arg [ 0 ] ) {
1001
+ // no need to assert range value in detail
1002
+ expect ( exp . updateArgs [ i ] [ j ] ) . toBe (
1003
+ 'range' ,
1004
+ 'scatter.update range update - ' + msg
1005
+ ) ;
1006
+ } else {
1007
+ expect ( arg ) . toBe (
1008
+ exp . updateArgs [ i ] [ j ] ,
1009
+ 'scatter.update call' + i + ' arg' + j + ' - ' + msg
1010
+ ) ;
1011
+ }
1012
+ } ) ;
1013
+ } ) ;
1014
+
1015
+ expect ( drawCalls . length ) . toBe (
1016
+ exp . drawArgs . length ,
1017
+ 'scatter2d.draw has been called the correct number of times - ' + msg
1018
+ ) ;
1019
+ drawCalls . forEach ( function ( d , i ) {
1020
+ d . args . forEach ( function ( arg , j ) {
1021
+ expect ( arg ) . toBe (
1022
+ exp . drawArgs [ i ] [ j ] ,
1023
+ 'scatter.draw call' + i + ' arg' + j + ' - ' + msg
1024
+ ) ;
1025
+ } ) ;
1026
+ } ) ;
1027
+
1028
+ scene . scatter2d . update . calls . reset ( ) ;
1029
+ scene . scatter2d . draw . calls . reset ( ) ;
1030
+ }
1031
+
1032
+ var unselectBatchOld ;
1033
+
1034
+ Plotly . newPlot ( 'graph' , [ {
1035
+ type : 'scattergl' ,
1036
+ mode : 'markers' ,
1037
+ y : [ 1 , 2 , 1 ] ,
1038
+ marker : { size : 30 }
1039
+ } ] , {
1040
+ dragmode : 'select' ,
1041
+ margin : { t : 0 , b : 0 , l : 0 , r : 0 } ,
1042
+ width : 500 ,
1043
+ height : 500
1044
+ } )
1045
+ . then ( delay ( 100 ) )
1046
+ . then ( function ( ) {
1047
+ var scene = grabScene ( ) ;
1048
+ spyOn ( scene . scatter2d , 'update' ) . and . callThrough ( ) ;
1049
+ spyOn ( scene . scatter2d , 'draw' ) . and . callThrough ( ) ;
1050
+ } )
1051
+ . then ( function ( ) {
1052
+ _assert ( 'base' , {
1053
+ selectBatch : [ ] ,
1054
+ unselectBatch : [ ] ,
1055
+ updateArgs : [ ] ,
1056
+ drawArgs : [ ]
1057
+ } ) ;
1058
+ } )
1059
+ . then ( function ( ) { return select ( [ [ 20 , 20 ] , [ 480 , 250 ] ] ) ; } )
1060
+ . then ( function ( ) {
1061
+ var scene = grabScene ( ) ;
1062
+ _assert ( 'after select' , {
1063
+ selectBatch : [ [ 1 ] ] ,
1064
+ unselectBatch : [ [ 0 , 2 ] ] ,
1065
+ updateArgs : [
1066
+ // N.B. scatter2d now draws unselected options
1067
+ [ scene . markerUnselectedOptions ] ,
1068
+ ] ,
1069
+ drawArgs : [
1070
+ [ scene . unselectBatch ]
1071
+ ]
1072
+ } ) ;
1073
+ } )
1074
+ . then ( function ( ) { return doubleClick ( 250 , 250 ) ; } )
1075
+ . then ( function ( ) {
1076
+ var scene = grabScene ( ) ;
1077
+ _assert ( 'after doubleclick' , {
1078
+ selectBatch : [ null ] ,
1079
+ unselectBatch : [ [ 0 , 1 , 2 ] ] ,
1080
+ updateArgs : [ ] ,
1081
+ drawArgs : [
1082
+ // call in no-selection loop (can we get rid of this?)
1083
+ [ 0 ] ,
1084
+ // call with unselectBatch
1085
+ [ scene . unselectBatch ]
1086
+ ]
1087
+ } ) ;
1088
+ } )
1089
+ . then ( function ( ) { return Plotly . relayout ( gd , 'dragmode' , 'pan' ) ; } )
1090
+ . then ( function ( ) {
1091
+ _assert ( 'after relayout to *pan*' , {
1092
+ selectBatch : [ null ] ,
1093
+ unselectBatch : [ [ 0 , 1 , 2 ] ] ,
1094
+ // nothing to do when relayouting to 'pan'
1095
+ updateArgs : [ ] ,
1096
+ drawArgs : [ ]
1097
+ } ) ;
1098
+
1099
+ // keep ref for next _assert()
1100
+ var scene = grabScene ( ) ;
1101
+ unselectBatchOld = scene . unselectBatch ;
1102
+ } )
1103
+ . then ( function ( ) { return drag ( [ [ 200 , 200 ] , [ 250 , 250 ] ] ) ; } )
1104
+ . then ( function ( ) {
1105
+ var scene = grabScene ( ) ;
1106
+ _assert ( 'after pan' , {
1107
+ selectBatch : null ,
1108
+ unselectBatch : null ,
1109
+ // drag triggers:
1110
+ // - 2 scene.update() calls, which each invoke
1111
+ // + 1 scatter2d.update (updating viewport)
1112
+ // + 2 scatter2d.draw (same as after double-click)
1113
+ //
1114
+ // replot on mouseup triggers:
1115
+ // - 1 scatter2d.update updating viewport
1116
+ // - 1 scatter2d.update resetting markerOptions
1117
+ // - 1 (full) scene.draw()
1118
+ updateArgs : [
1119
+ [ 'range' ] ,
1120
+ [ 'range' ] ,
1121
+ // N.B. bring scatter2d back to 'base' marker options
1122
+ [ scene . markerOptions ] ,
1123
+ [ 'range' ]
1124
+ ] ,
1125
+ drawArgs : [
1126
+ [ 0 ] ,
1127
+ [ unselectBatchOld ] ,
1128
+ [ 0 ] ,
1129
+ [ unselectBatchOld ] ,
1130
+ [ 0 ]
1131
+ ]
1132
+ } ) ;
1133
+ } )
1134
+ . catch ( failTest )
1135
+ . then ( done ) ;
1136
+ } ) ;
966
1137
} ) ;
0 commit comments