Commit | Line | Data |
---|---|---|
9c831431 RK |
1 | /** |
2 | * @fileoverview Test cases for the interaction model. | |
3 | * | |
4 | * @author konigsberg@google.com (Robert Konigsbrg) | |
5 | */ | |
6 | var InteractionModelTestCase = TestCase("interaction-model"); | |
7 | ||
8 | InteractionModelTestCase.prototype.setUp = function() { | |
9 | document.body.innerHTML = "<div id='graph'></div>"; | |
10 | }; | |
11 | ||
12 | InteractionModelTestCase.prototype.tearDown = function() { | |
13 | }; | |
14 | ||
af3a17a8 RK |
15 | var data1 = "X,Y\n" + |
16 | "20,-1\n" + | |
17 | "21,0\n" + | |
18 | "22,1\n" + | |
19 | "23,0\n"; | |
20 | ||
21 | var data2 = | |
22 | [[1, 10], | |
23 | [2, 20], | |
24 | [3, 30], | |
25 | [4, 40], | |
26 | [5, 120], | |
27 | [6, 50], | |
28 | [7, 70], | |
29 | [8, 90], | |
30 | [9, 50]]; | |
31 | ||
9c831431 RK |
32 | function getXLabels() { |
33 | var x_labels = document.getElementsByClassName("dygraph-axis-label-x"); | |
34 | var ary = []; | |
35 | for (var i = 0; i < x_labels.length; i++) { | |
36 | ary.push(x_labels[i].innerHTML); | |
37 | } | |
38 | return ary; | |
39 | } | |
40 | ||
41 | InteractionModelTestCase.prototype.pan = function(g, xRange, yRange) { | |
42 | var originalXRange = g.xAxisRange(); | |
43 | var originalYRange = g.yAxisRange(0); | |
44 | ||
45 | DygraphOps.dispatchMouseDown(g, xRange[0], yRange[0]); | |
46 | DygraphOps.dispatchMouseMove(g, xRange[1], yRange[0]); // this is really necessary. | |
47 | DygraphOps.dispatchMouseUp(g, xRange[1], yRange[0]); | |
48 | ||
49 | assertEqualsDelta(xRange, g.xAxisRange(), 0.2); | |
50 | // assertEqualsDelta(originalYRange, g.yAxisRange(0), 0.2); // Not true, it's something in the middle. | |
51 | ||
52 | var midX = (xRange[1] - xRange[0]) / 2; | |
53 | DygraphOps.dispatchMouseDown(g, midX, yRange[0]); | |
54 | DygraphOps.dispatchMouseMove(g, midX, yRange[1]); // this is really necessary. | |
55 | DygraphOps.dispatchMouseUp(g, midX, yRange[1]); | |
56 | ||
57 | assertEqualsDelta(xRange, g.xAxisRange(), 0.2); | |
58 | assertEqualsDelta(yRange, g.yAxisRange(0), 0.2); | |
59 | } | |
60 | ||
61 | /** | |
62 | * This tests that when changing the interaction model so pan is used instead | |
63 | * of zoom as the default behavior, a standard click method is still called. | |
64 | */ | |
65 | InteractionModelTestCase.prototype.testClickCallbackIsCalled = function() { | |
66 | var clicked; | |
67 | ||
68 | var clickCallback = function(event, x) { | |
69 | clicked = x; | |
70 | }; | |
71 | ||
9c831431 | 72 | var graph = document.getElementById("graph"); |
af3a17a8 | 73 | var g = new Dygraph(graph, data1, |
9c831431 RK |
74 | { |
75 | width: 100, | |
76 | height : 100, | |
77 | clickCallback : clickCallback | |
78 | }); | |
79 | ||
80 | DygraphOps.dispatchMouseDown_Point(g, 10, 10); | |
81 | DygraphOps.dispatchMouseMove_Point(g, 10, 10); | |
82 | DygraphOps.dispatchMouseUp_Point(g, 10, 10); | |
83 | ||
84 | assertEquals(20, clicked); | |
85 | }; | |
86 | ||
87 | /** | |
88 | * This tests that when changing the interaction model so pan is used instead | |
89 | * of zoom as the default behavior, a standard click method is still called. | |
90 | */ | |
91 | InteractionModelTestCase.prototype.testClickCallbackIsCalledOnCustomPan = function() { | |
92 | var clicked; | |
93 | ||
94 | var clickCallback = function(event, x) { | |
95 | clicked = x; | |
96 | }; | |
97 | ||
9c831431 RK |
98 | function customDown(event, g, context) { |
99 | context.initializeMouseDown(event, g, context); | |
100 | Dygraph.startPan(event, g, context); | |
101 | } | |
102 | ||
103 | function customMove(event, g, context) { | |
104 | Dygraph.movePan(event, g, context); | |
105 | } | |
106 | ||
107 | function customUp(event, g, context) { | |
108 | Dygraph.endPan(event, g, context); | |
109 | } | |
110 | ||
111 | var opts = { | |
112 | width: 100, | |
113 | height : 100, | |
114 | clickCallback : clickCallback, | |
115 | interactionModel : { | |
116 | 'mousedown' : customDown, | |
117 | 'mousemove' : customMove, | |
118 | 'mouseup' : customUp, | |
119 | } | |
120 | }; | |
121 | ||
122 | var graph = document.getElementById("graph"); | |
af3a17a8 | 123 | var g = new Dygraph(graph, data1, opts); |
9c831431 RK |
124 | |
125 | DygraphOps.dispatchMouseDown_Point(g, 10, 10); | |
126 | DygraphOps.dispatchMouseMove_Point(g, 10, 10); | |
127 | DygraphOps.dispatchMouseUp_Point(g, 10, 10); | |
128 | ||
fc4e84fa | 129 | assertEquals(20, clicked); |
9c831431 RK |
130 | }; |
131 | ||
af3a17a8 RK |
132 | InteractionModelTestCase.clickAt = function(g, x, y) { |
133 | DygraphOps.dispatchMouseDown(g, x, y); | |
134 | DygraphOps.dispatchMouseMove(g, x, y); | |
135 | DygraphOps.dispatchMouseUp(g, x, y); | |
136 | } | |
137 | ||
138 | /** | |
027e9e9b DV |
139 | * This tests that clickCallback is still called with the nonInteractiveModel. |
140 | */ | |
141 | InteractionModelTestCase.prototype.testClickCallbackIsCalledWithNonInteractiveModel = function() { | |
142 | var clicked; | |
143 | ||
144 | // TODO(danvk): also test pointClickCallback here. | |
145 | var clickCallback = function(event, x) { | |
146 | clicked = x; | |
147 | }; | |
148 | ||
149 | var opts = { | |
150 | width: 100, | |
151 | height : 100, | |
152 | clickCallback : clickCallback, | |
0290d079 | 153 | interactionModel : Dygraph.Interaction.nonInteractiveModel_ |
027e9e9b DV |
154 | }; |
155 | ||
156 | var graph = document.getElementById("graph"); | |
157 | var g = new Dygraph(graph, data1, opts); | |
158 | ||
159 | DygraphOps.dispatchMouseDown_Point(g, 10, 10); | |
160 | DygraphOps.dispatchMouseMove_Point(g, 10, 10); | |
161 | DygraphOps.dispatchMouseUp_Point(g, 10, 10); | |
162 | ||
163 | assertEquals(20, clicked); | |
164 | }; | |
165 | ||
166 | /** | |
af3a17a8 RK |
167 | * A sanity test to ensure pointClickCallback is called. |
168 | */ | |
169 | InteractionModelTestCase.prototype.testPointClickCallback = function() { | |
170 | var clicked; | |
171 | var g = new Dygraph(document.getElementById("graph"), data2, { | |
172 | pointClickCallback : function(event, point) { | |
173 | clicked = point; | |
174 | } | |
175 | }); | |
176 | ||
177 | InteractionModelTestCase.clickAt(g, 4, 40); | |
178 | ||
179 | assertEquals(4, clicked.xval); | |
180 | assertEquals(40, clicked.yval); | |
181 | }; | |
182 | ||
183 | /** | |
184 | * A sanity test to ensure pointClickCallback is not called when out of range. | |
185 | */ | |
186 | InteractionModelTestCase.prototype.testNoPointClickCallbackWhenOffPoint = function() { | |
187 | var clicked; | |
188 | var g = new Dygraph(document.getElementById("graph"), data2, { | |
189 | pointClickCallback : function(event, point) { | |
190 | clicked = point; | |
191 | } | |
192 | }); | |
193 | ||
194 | InteractionModelTestCase.clickAt(g, 5, 40); | |
195 | ||
196 | assertUndefined(clicked); | |
197 | }; | |
198 | ||
199 | /** | |
200 | * Ensures pointClickCallback circle size is taken into account. | |
201 | */ | |
202 | InteractionModelTestCase.prototype.testPointClickCallback_circleSize = function() { | |
203 | // TODO(konigsberg): Implement. | |
204 | }; | |
205 | ||
206 | /** | |
207 | * Ensures that pointClickCallback is called prior to clickCallback | |
208 | */ | |
209 | InteractionModelTestCase.prototype.testPointClickCallbackCalledPriorToClickCallback = function() { | |
210 | var counter = 0; | |
211 | var pointClicked; | |
212 | var clicked; | |
213 | var g = new Dygraph(document.getElementById("graph"), data2, { | |
214 | pointClickCallback : function(event, point) { | |
215 | counter++; | |
216 | pointClicked = counter; | |
217 | }, | |
218 | clickCallback : function(event, point) { | |
219 | counter++; | |
220 | clicked = counter; | |
221 | } | |
222 | }); | |
223 | ||
224 | InteractionModelTestCase.clickAt(g, 4, 40); | |
225 | assertEquals(1, pointClicked); | |
226 | assertEquals(2, clicked); | |
227 | }; | |
228 | ||
229 | /** | |
230 | * Ensures that when there's no pointClickCallback, clicking on a point still calls | |
231 | * clickCallback | |
232 | */ | |
233 | InteractionModelTestCase.prototype.testClickCallback_clickOnPoint = function() { | |
234 | var clicked; | |
235 | var g = new Dygraph(document.getElementById("graph"), data2, { | |
236 | clickCallback : function(event, point) { | |
237 | clicked = 1; | |
238 | } | |
239 | }); | |
240 | ||
241 | InteractionModelTestCase.clickAt(g, 4, 40); | |
242 | assertEquals(1, clicked); | |
243 | }; | |
244 | ||
32566cec RK |
245 | InteractionModelTestCase.prototype.testIsZoomed_none = function() { |
246 | var g = new Dygraph(document.getElementById("graph"), data2, {}); | |
247 | ||
248 | assertFalse(g.isZoomed()); | |
249 | assertFalse(g.isZoomed("x")); | |
250 | assertFalse(g.isZoomed("y")); | |
357f7a8a RK |
251 | }; |
252 | ||
32566cec RK |
253 | InteractionModelTestCase.prototype.testIsZoomed_x = function() { |
254 | var g = new Dygraph(document.getElementById("graph"), data2, {}); | |
255 | ||
5ee26cc1 DV |
256 | DygraphOps.dispatchMouseDown_Point(g, 100, 100); |
257 | DygraphOps.dispatchMouseMove_Point(g, 130, 100); | |
258 | DygraphOps.dispatchMouseUp_Point(g, 130, 100); | |
32566cec RK |
259 | |
260 | assertTrue(g.isZoomed()); | |
261 | assertTrue(g.isZoomed("x")); | |
262 | assertFalse(g.isZoomed("y")); | |
263 | }; | |
264 | ||
265 | InteractionModelTestCase.prototype.testIsZoomed_y = function() { | |
266 | var g = new Dygraph(document.getElementById("graph"), data2, {}); | |
267 | ||
268 | DygraphOps.dispatchMouseDown_Point(g, 10, 10); | |
269 | DygraphOps.dispatchMouseMove_Point(g, 10, 30); | |
270 | DygraphOps.dispatchMouseUp_Point(g, 10, 30); | |
271 | ||
272 | assertTrue(g.isZoomed()); | |
273 | assertFalse(g.isZoomed("x")); | |
274 | assertTrue(g.isZoomed("y")); | |
275 | }; | |
276 | ||
277 | InteractionModelTestCase.prototype.testIsZoomed_both = function() { | |
278 | var g = new Dygraph(document.getElementById("graph"), data2, {}); | |
279 | ||
280 | // Zoom x axis | |
5ee26cc1 DV |
281 | DygraphOps.dispatchMouseDown_Point(g, 100, 100); |
282 | DygraphOps.dispatchMouseMove_Point(g, 130, 100); | |
283 | DygraphOps.dispatchMouseUp_Point(g, 130, 100); | |
32566cec RK |
284 | |
285 | // Now zoom y axis | |
5ee26cc1 DV |
286 | DygraphOps.dispatchMouseDown_Point(g, 100, 100); |
287 | DygraphOps.dispatchMouseMove_Point(g, 100, 130); | |
288 | DygraphOps.dispatchMouseUp_Point(g, 100, 130); | |
32566cec RK |
289 | |
290 | ||
291 | assertTrue(g.isZoomed()); | |
292 | assertTrue(g.isZoomed("x")); | |
293 | assertTrue(g.isZoomed("y")); | |
294 | }; | |
295 | ||
296 | InteractionModelTestCase.prototype.testIsZoomed_updateOptions_none = function() { | |
297 | var g = new Dygraph(document.getElementById("graph"), data2, {}); | |
298 | ||
299 | g.updateOptions({}); | |
300 | ||
301 | assertFalse(g.isZoomed()); | |
302 | assertFalse(g.isZoomed("x")); | |
303 | assertFalse(g.isZoomed("y")); | |
304 | }; | |
305 | ||
306 | InteractionModelTestCase.prototype.testIsZoomed_updateOptions_x = function() { | |
307 | var g = new Dygraph(document.getElementById("graph"), data2, {}); | |
308 | ||
309 | g.updateOptions({dateWindow: [-.5, .3]}); | |
310 | assertTrue(g.isZoomed()); | |
311 | assertTrue(g.isZoomed("x")); | |
312 | assertFalse(g.isZoomed("y")); | |
313 | }; | |
314 | ||
315 | InteractionModelTestCase.prototype.testIsZoomed_updateOptions_y = function() { | |
316 | var g = new Dygraph(document.getElementById("graph"), data2, {}); | |
317 | ||
318 | g.updateOptions({valueRange: [1, 10]}); | |
319 | ||
320 | assertTrue(g.isZoomed()); | |
321 | assertFalse(g.isZoomed("x")); | |
322 | assertTrue(g.isZoomed("y")); | |
323 | }; | |
324 | ||
325 | InteractionModelTestCase.prototype.testIsZoomed_updateOptions_both = function() { | |
326 | var g = new Dygraph(document.getElementById("graph"), data2, {}); | |
327 | ||
328 | g.updateOptions({dateWindow: [-1, 1], valueRange: [1, 10]}); | |
329 | ||
330 | assertTrue(g.isZoomed()); | |
331 | assertTrue(g.isZoomed("x")); | |
332 | assertTrue(g.isZoomed("y")); | |
333 | }; | |
1357d81e US |
334 | |
335 | ||
9aedaae3 | 336 | InteractionModelTestCase.prototype.testCorrectAxisValueRangeAfterUnzoom = function() { |
5ee26cc1 DV |
337 | var g = new Dygraph(document.getElementById("graph"), |
338 | data2, { | |
339 | valueRange: [1, 50], | |
340 | dateWindow: [1, 9], | |
341 | animatedZooms:false | |
342 | }); | |
1357d81e | 343 | |
9aedaae3 | 344 | // Zoom x axis |
5ee26cc1 DV |
345 | DygraphOps.dispatchMouseDown_Point(g, 100, 100); |
346 | DygraphOps.dispatchMouseMove_Point(g, 130, 100); | |
347 | DygraphOps.dispatchMouseUp_Point(g, 130, 100); | |
1357d81e | 348 | |
9aedaae3 | 349 | // Zoom y axis |
5ee26cc1 DV |
350 | DygraphOps.dispatchMouseDown_Point(g, 100, 100); |
351 | DygraphOps.dispatchMouseMove_Point(g, 100, 130); | |
352 | DygraphOps.dispatchMouseUp_Point(g, 100, 130); | |
9aedaae3 US |
353 | currentYAxisRange = g.yAxisRange(); |
354 | currentXAxisRange = g.xAxisRange(); | |
355 | ||
356 | //check that the range for the axis has changed | |
5ee26cc1 DV |
357 | assertNotEquals(1, currentXAxisRange[0]); |
358 | assertNotEquals(10, currentXAxisRange[1]); | |
359 | assertNotEquals(1, currentYAxisRange[0]); | |
360 | assertNotEquals(50, currentYAxisRange[1]); | |
9aedaae3 | 361 | |
f3cd243e DV |
362 | // unzoom by doubleclick. This is really the order in which a browser |
363 | // generates events, and we depend on it. | |
364 | DygraphOps.dispatchMouseDown_Point(g, 10, 10); | |
365 | DygraphOps.dispatchMouseUp_Point(g, 10, 10); | |
366 | DygraphOps.dispatchMouseDown_Point(g, 10, 10); | |
367 | DygraphOps.dispatchMouseUp_Point(g, 10, 10); | |
1357d81e US |
368 | DygraphOps.dispatchDoubleClick(g, null); |
369 | ||
9aedaae3 US |
370 | // check if range for y-axis was reset to original value |
371 | // TODO check if range for x-axis is correct. | |
372 | // Currently not possible because dateRange is set to null and extremes are returned | |
373 | newYAxisRange = g.yAxisRange(); | |
5ee26cc1 DV |
374 | assertEquals(1, newYAxisRange[0]); |
375 | assertEquals(50, newYAxisRange[1]); | |
1357d81e | 376 | }; |
dbcf3e6d DV |
377 | |
378 | /** | |
379 | * Ensures pointClickCallback is called when some points along the y-axis don't | |
380 | * exist. | |
381 | */ | |
382 | InteractionModelTestCase.prototype.testPointClickCallback_missingData = function() { | |
383 | ||
384 | // There's a B-value at 2, but no A-value. | |
385 | var data = | |
386 | "X,A,B\n" + | |
387 | "1,,100\n"+ | |
388 | "2,,110\n"+ | |
389 | "3,140,120\n"+ | |
390 | "4,130,110\n"+ | |
391 | ""; | |
392 | ||
393 | var clicked; | |
394 | var g = new Dygraph(document.getElementById("graph"), data, { | |
395 | pointClickCallback : function(event, point) { | |
396 | clicked = point; | |
397 | } | |
398 | }); | |
399 | ||
400 | InteractionModelTestCase.clickAt(g, 2, 110); | |
401 | ||
402 | assertEquals(2, clicked.xval); | |
403 | assertEquals(110, clicked.yval); | |
404 | }; |