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