@@ -6,7 +6,15 @@ var Lib = require('@src/lib');
66var createGraphDiv = require ( '../assets/create_graph_div' ) ;
77var destroyGraphDiv = require ( '../assets/destroy_graph_div' ) ;
88var customMatchers = require ( '../assets/custom_matchers' ) ;
9+ var mouseEvent = require ( '../assets/mouse_event' ) ;
10+ var selectButton = require ( '../assets/modebar_button' ) ;
911
12+ var MODEBAR_DELAY = 500 ;
13+
14+ // put callback in the event queue
15+ function delay ( done ) {
16+ setTimeout ( done , 0 ) ;
17+ }
1018
1119describe ( 'Test plot structure' , function ( ) {
1220 'use strict' ;
@@ -142,6 +150,119 @@ describe('Test plot structure', function() {
142150 } ) ;
143151 } ) ;
144152
153+ describe ( 'scatter drag' , function ( ) {
154+
155+ var mock = require ( '@mocks/10.json' ) ,
156+ gd , modeBar , relayoutCallback ;
157+
158+ beforeEach ( function ( done ) {
159+ gd = createGraphDiv ( ) ;
160+
161+ Plotly . plot ( gd , mock . data , mock . layout ) . then ( function ( ) {
162+
163+ modeBar = gd . _fullLayout . _modeBar ;
164+ relayoutCallback = jasmine . createSpy ( 'relayoutCallback' ) ;
165+
166+ gd . on ( 'plotly_relayout' , relayoutCallback ) ;
167+
168+ delay ( done ) ;
169+ } ) ;
170+ } ) ;
171+
172+ it ( 'scatter plot should respond to drag interactions' , function ( done ) {
173+
174+ jasmine . addMatchers ( customMatchers ) ;
175+
176+ var precision = 5 ;
177+
178+ var buttonPan = selectButton ( modeBar , 'pan2d' ) ;
179+
180+ var originalX = [ - 0.6225 , 5.5 ] ;
181+ var originalY = [ - 1.6340975059013805 , 7.166241526218911 ] ;
182+
183+ expect ( gd . layout . xaxis . range ) . toBeCloseToArray ( originalX , precision ) ;
184+ expect ( gd . layout . yaxis . range ) . toBeCloseToArray ( originalY , precision ) ;
185+
186+ // Switch to pan mode
187+ expect ( buttonPan . isActive ( ) ) . toBe ( false ) ; // initially, zoom is active
188+ buttonPan . click ( ) ;
189+ expect ( buttonPan . isActive ( ) ) . toBe ( true ) ; // switched on dragmode
190+
191+ // Switching mode must not change visible range
192+ expect ( gd . layout . xaxis . range ) . toBeCloseToArray ( originalX , precision ) ;
193+ expect ( gd . layout . yaxis . range ) . toBeCloseToArray ( originalY , precision ) ;
194+
195+ setTimeout ( function ( ) {
196+
197+ expect ( relayoutCallback ) . toHaveBeenCalledTimes ( 1 ) ;
198+ relayoutCallback . calls . reset ( ) ;
199+
200+ // Drag scene along the X axis
201+
202+ mouseEvent ( 'mousedown' , 110 , 150 ) ;
203+ mouseEvent ( 'mousemove' , 220 , 150 ) ;
204+ mouseEvent ( 'mouseup' , 220 , 150 ) ;
205+
206+ expect ( gd . layout . xaxis . range ) . toBeCloseToArray ( [ - 2.0255729166666665 , 4.096927083333333 ] , precision ) ;
207+ expect ( gd . layout . yaxis . range ) . toBeCloseToArray ( originalY , precision ) ;
208+
209+ // Drag scene back along the X axis (not from the same starting point but same X delta)
210+
211+ mouseEvent ( 'mousedown' , 280 , 150 ) ;
212+ mouseEvent ( 'mousemove' , 170 , 150 ) ;
213+ mouseEvent ( 'mouseup' , 170 , 150 ) ;
214+
215+ expect ( gd . layout . xaxis . range ) . toBeCloseToArray ( originalX , precision ) ;
216+ expect ( gd . layout . yaxis . range ) . toBeCloseToArray ( originalY , precision ) ;
217+
218+ // Drag scene along the Y axis
219+
220+ mouseEvent ( 'mousedown' , 110 , 150 ) ;
221+ mouseEvent ( 'mousemove' , 110 , 190 ) ;
222+ mouseEvent ( 'mouseup' , 110 , 190 ) ;
223+
224+ expect ( gd . layout . xaxis . range ) . toBeCloseToArray ( originalX , precision ) ;
225+ expect ( gd . layout . yaxis . range ) . toBeCloseToArray ( [ - 0.3769062155984817 , 8.42343281652181 ] , precision ) ;
226+
227+ // Drag scene back along the Y axis (not from the same starting point but same Y delta)
228+
229+ mouseEvent ( 'mousedown' , 280 , 130 ) ;
230+ mouseEvent ( 'mousemove' , 280 , 90 ) ;
231+ mouseEvent ( 'mouseup' , 280 , 90 ) ;
232+
233+ expect ( gd . layout . xaxis . range ) . toBeCloseToArray ( originalX , precision ) ;
234+ expect ( gd . layout . yaxis . range ) . toBeCloseToArray ( originalY , precision ) ;
235+
236+ // Drag scene along both the X and Y axis
237+
238+ mouseEvent ( 'mousedown' , 110 , 150 ) ;
239+ mouseEvent ( 'mousemove' , 220 , 190 ) ;
240+ mouseEvent ( 'mouseup' , 220 , 190 ) ;
241+
242+ expect ( gd . layout . xaxis . range ) . toBeCloseToArray ( [ - 2.0255729166666665 , 4.096927083333333 ] , precision ) ;
243+ expect ( gd . layout . yaxis . range ) . toBeCloseToArray ( [ - 0.3769062155984817 , 8.42343281652181 ] , precision ) ;
244+
245+ // Drag scene back along the X and Y axis (not from the same starting point but same delta vector)
246+
247+ mouseEvent ( 'mousedown' , 280 , 130 ) ;
248+ mouseEvent ( 'mousemove' , 170 , 90 ) ;
249+ mouseEvent ( 'mouseup' , 170 , 90 ) ;
250+
251+ expect ( gd . layout . xaxis . range ) . toBeCloseToArray ( originalX , precision ) ;
252+ expect ( gd . layout . yaxis . range ) . toBeCloseToArray ( originalY , precision ) ;
253+
254+ setTimeout ( function ( ) {
255+
256+ expect ( relayoutCallback ) . toHaveBeenCalledTimes ( 6 ) ; // X and back; Y and back; XY and back
257+
258+ done ( ) ;
259+
260+ } , MODEBAR_DELAY ) ;
261+
262+ } , MODEBAR_DELAY ) ;
263+ } ) ;
264+ } ) ;
265+
145266 describe ( 'contour/heatmap traces' , function ( ) {
146267 var mock = require ( '@mocks/connectgaps_2d.json' ) ;
147268 var gd ;
0 commit comments