2 * @fileoverview Test cases for the interaction model.
4 * @author konigsberg@google.com (Robert Konigsbrg)
6 describe("interaction-model", function() {
8 beforeEach(function() {
9 document
.body
.innerHTML
= "<div id='graph'></div>";
12 afterEach(function() {
33 function getXLabels() {
34 var x_labels
= document
.getElementsByClassName("dygraph-axis-label-x");
36 for (var i
= 0; i
< x_labels
.length
; i
++) {
37 ary
.push(x_labels
[i
].innerHTML
);
43 it('testPan', function() {
44 var originalXRange = g.xAxisRange();
45 var originalYRange = g.yAxisRange(0);
47 DygraphOps.dispatchMouseDown(g, xRange[0], yRange[0]);
48 DygraphOps.dispatchMouseMove(g, xRange[1], yRange[0]); // this is really necessary.
49 DygraphOps.dispatchMouseUp(g, xRange[1], yRange[0]);
51 assert.closeTo(xRange, g.xAxisRange(), 0.2);
52 // assert.closeTo(originalYRange, g.yAxisRange(0), 0.2); // Not true, it's something in the middle.
54 var midX = (xRange[1] - xRange[0]) / 2;
55 DygraphOps.dispatchMouseDown(g, midX, yRange[0]);
56 DygraphOps.dispatchMouseMove(g, midX, yRange[1]); // this is really necessary.
57 DygraphOps.dispatchMouseUp(g, midX, yRange[1]);
59 assert.closeTo(xRange, g.xAxisRange(), 0.2);
60 assert.closeTo(yRange, g.yAxisRange(0), 0.2);
65 * This tests that when changing the interaction model so pan is used instead
66 * of zoom as the default behavior, a standard click method is still called.
68 it('testClickCallbackIsCalled', function() {
71 var clickCallback
= function(event
, x
) {
75 var graph
= document
.getElementById("graph");
76 var g
= new Dygraph(graph
, data1
,
80 clickCallback
: clickCallback
83 DygraphOps
.dispatchMouseDown_Point(g
, 10, 10);
84 DygraphOps
.dispatchMouseMove_Point(g
, 10, 10);
85 DygraphOps
.dispatchMouseUp_Point(g
, 10, 10);
87 assert
.equal(20, clicked
);
91 * This tests that when changing the interaction model so pan is used instead
92 * of zoom as the default behavior, a standard click method is still called.
94 it('testClickCallbackIsCalledOnCustomPan', function() {
97 var clickCallback
= function(event
, x
) {
101 function customDown(event
, g
, context
) {
102 context
.initializeMouseDown(event
, g
, context
);
103 Dygraph
.startPan(event
, g
, context
);
106 function customMove(event
, g
, context
) {
107 Dygraph
.movePan(event
, g
, context
);
110 function customUp(event
, g
, context
) {
111 Dygraph
.endPan(event
, g
, context
);
117 clickCallback
: clickCallback
,
119 'mousedown' : customDown
,
120 'mousemove' : customMove
,
121 'mouseup' : customUp
,
125 var graph
= document
.getElementById("graph");
126 var g
= new Dygraph(graph
, data1
, opts
);
128 DygraphOps
.dispatchMouseDown_Point(g
, 10, 10);
129 DygraphOps
.dispatchMouseMove_Point(g
, 10, 10);
130 DygraphOps
.dispatchMouseUp_Point(g
, 10, 10);
132 assert
.equal(20, clicked
);
135 var clickAt
= function(g
, x
, y
) {
136 DygraphOps
.dispatchMouseDown(g
, x
, y
);
137 DygraphOps
.dispatchMouseMove(g
, x
, y
);
138 DygraphOps
.dispatchMouseUp(g
, x
, y
);
142 * This tests that clickCallback is still called with the nonInteractiveModel.
144 it('testClickCallbackIsCalledWithNonInteractiveModel', function() {
147 // TODO(danvk): also test pointClickCallback here.
148 var clickCallback
= function(event
, x
) {
155 clickCallback
: clickCallback
,
156 interactionModel
: Dygraph
.Interaction
.nonInteractiveModel_
159 var graph
= document
.getElementById("graph");
160 var g
= new Dygraph(graph
, data1
, opts
);
162 DygraphOps
.dispatchMouseDown_Point(g
, 10, 10);
163 DygraphOps
.dispatchMouseMove_Point(g
, 10, 10);
164 DygraphOps
.dispatchMouseUp_Point(g
, 10, 10);
166 assert
.equal(20, clicked
);
170 * A sanity test to ensure pointClickCallback is called.
172 it('testPointClickCallback', function() {
174 var g
= new Dygraph('graph', data2
, {
175 pointClickCallback
: function(event
, point
) {
182 assert
.isNotNull(clicked
);
183 assert
.equal(4, clicked
.xval
);
184 assert
.equal(40, clicked
.yval
);
188 * A sanity test to ensure pointClickCallback is not called when out of range.
190 it('testNoPointClickCallbackWhenOffPoint', function() {
192 var g
= new Dygraph(document
.getElementById("graph"), data2
, {
193 pointClickCallback
: function(event
, point
) {
200 assert
.isUndefined(clicked
);
204 * Ensures pointClickCallback circle size is taken into account.
206 it('testPointClickCallback_circleSize', function() {
207 // TODO(konigsberg): Implement.
211 * Ensures that pointClickCallback is called prior to clickCallback
213 it('testPointClickCallbackCalledPriorToClickCallback', function() {
217 var g
= new Dygraph(document
.getElementById("graph"), data2
, {
218 pointClickCallback
: function(event
, point
) {
220 pointClicked
= counter
;
222 clickCallback
: function(event
, point
) {
229 assert
.equal(1, pointClicked
);
230 assert
.equal(2, clicked
);
234 * Ensures that when there's no pointClickCallback, clicking on a point still calls
237 it('testClickCallback_clickOnPoint', function() {
239 var g
= new Dygraph(document
.getElementById("graph"), data2
, {
240 clickCallback
: function(event
, point
) {
246 assert
.equal(1, clicked
);
249 it('testIsZoomed_none', function() {
250 var g
= new Dygraph(document
.getElementById("graph"), data2
, {});
252 assert
.isFalse(g
.isZoomed());
253 assert
.isFalse(g
.isZoomed("x"));
254 assert
.isFalse(g
.isZoomed("y"));
257 it('testIsZoomed_x', function() {
258 var g
= new Dygraph(document
.getElementById("graph"), data2
, {});
260 DygraphOps
.dispatchMouseDown_Point(g
, 100, 100);
261 DygraphOps
.dispatchMouseMove_Point(g
, 130, 100);
262 DygraphOps
.dispatchMouseUp_Point(g
, 130, 100);
264 assert
.isTrue(g
.isZoomed());
265 assert
.isTrue(g
.isZoomed("x"));
266 assert
.isFalse(g
.isZoomed("y"));
269 it('testIsZoomed_y', function() {
270 var g
= new Dygraph(document
.getElementById("graph"), data2
, {});
272 DygraphOps
.dispatchMouseDown_Point(g
, 10, 10);
273 DygraphOps
.dispatchMouseMove_Point(g
, 10, 30);
274 DygraphOps
.dispatchMouseUp_Point(g
, 10, 30);
276 assert
.isTrue(g
.isZoomed());
277 assert
.isFalse(g
.isZoomed("x"));
278 assert
.isTrue(g
.isZoomed("y"));
281 it('testIsZoomed_both', function() {
282 var g
= new Dygraph(document
.getElementById("graph"), data2
, {});
285 DygraphOps
.dispatchMouseDown_Point(g
, 100, 100);
286 DygraphOps
.dispatchMouseMove_Point(g
, 130, 100);
287 DygraphOps
.dispatchMouseUp_Point(g
, 130, 100);
290 DygraphOps
.dispatchMouseDown_Point(g
, 100, 100);
291 DygraphOps
.dispatchMouseMove_Point(g
, 100, 130);
292 DygraphOps
.dispatchMouseUp_Point(g
, 100, 130);
295 assert
.isTrue(g
.isZoomed());
296 assert
.isTrue(g
.isZoomed("x"));
297 assert
.isTrue(g
.isZoomed("y"));
300 it('testIsZoomed_updateOptions_none', function() {
301 var g
= new Dygraph(document
.getElementById("graph"), data2
, {});
305 assert
.isFalse(g
.isZoomed());
306 assert
.isFalse(g
.isZoomed("x"));
307 assert
.isFalse(g
.isZoomed("y"));
310 it('testIsZoomed_updateOptions_x', function() {
311 var g
= new Dygraph(document
.getElementById("graph"), data2
, {});
313 g
.updateOptions({dateWindow
: [-.5, .3]});
314 assert
.isTrue(g
.isZoomed());
315 assert
.isTrue(g
.isZoomed("x"));
316 assert
.isFalse(g
.isZoomed("y"));
319 it('testIsZoomed_updateOptions_y', function() {
320 var g
= new Dygraph(document
.getElementById("graph"), data2
, {});
322 g
.updateOptions({valueRange
: [1, 10]});
324 assert
.isTrue(g
.isZoomed());
325 assert
.isFalse(g
.isZoomed("x"));
326 assert
.isTrue(g
.isZoomed("y"));
329 it('testIsZoomed_updateOptions_both', function() {
330 var g
= new Dygraph(document
.getElementById("graph"), data2
, {});
332 g
.updateOptions({dateWindow
: [-1, 1], valueRange
: [1, 10]});
334 assert
.isTrue(g
.isZoomed());
335 assert
.isTrue(g
.isZoomed("x"));
336 assert
.isTrue(g
.isZoomed("y"));
340 it('testCorrectAxisValueRangeAfterUnzoom', function() {
341 var g
= new Dygraph(document
.getElementById("graph"),
349 DygraphOps
.dispatchMouseDown_Point(g
, 100, 100);
350 DygraphOps
.dispatchMouseMove_Point(g
, 130, 100);
351 DygraphOps
.dispatchMouseUp_Point(g
, 130, 100);
354 DygraphOps
.dispatchMouseDown_Point(g
, 100, 100);
355 DygraphOps
.dispatchMouseMove_Point(g
, 100, 130);
356 DygraphOps
.dispatchMouseUp_Point(g
, 100, 130);
357 var currentYAxisRange
= g
.yAxisRange();
358 var currentXAxisRange
= g
.xAxisRange();
360 //check that the range for the axis has changed
361 assert
.notEqual(1, currentXAxisRange
[0]);
362 assert
.notEqual(10, currentXAxisRange
[1]);
363 assert
.notEqual(1, currentYAxisRange
[0]);
364 assert
.notEqual(50, currentYAxisRange
[1]);
366 // unzoom by doubleclick. This is really the order in which a browser
367 // generates events, and we depend on it.
368 DygraphOps
.dispatchMouseDown_Point(g
, 10, 10);
369 DygraphOps
.dispatchMouseUp_Point(g
, 10, 10);
370 DygraphOps
.dispatchMouseDown_Point(g
, 10, 10);
371 DygraphOps
.dispatchMouseUp_Point(g
, 10, 10);
372 DygraphOps
.dispatchDoubleClick(g
, null);
374 // check if range for y-axis was reset to original value
375 // TODO check if range for x-axis is correct.
376 // Currently not possible because dateRange is set to null and extremes are returned
377 var newYAxisRange
= g
.yAxisRange();
378 assert
.equal(1, newYAxisRange
[0]);
379 assert
.equal(50, newYAxisRange
[1]);
383 * Ensures pointClickCallback is called when some points along the y-axis don't
386 it('testPointClickCallback_missingData', function() {
388 // There's a B-value at 2, but no A-value.
398 var g
= new Dygraph(document
.getElementById("graph"), data
, {
399 pointClickCallback
: function(event
, point
) {
406 assert
.equal(2, clicked
.xval
);
407 assert
.equal(110, clicked
.yval
);
410 describe('animated zooms', function() {
414 oldDuration
= Dygraph
.ANIMATION_DURATION
;
415 Dygraph
.ANIMATION_DURATION
= 100; // speed up the animation for testing
418 Dygraph
.ANIMATION_DURATION
= oldDuration
;
421 it('should support animated zooms', function(done
) {
431 var g
= new Dygraph('graph', data
, {
435 // updating the dateWindow does not result in an animation.
436 assert
.deepEqual([1, 4], g
.xAxisRange());
437 g
.updateOptions({dateWindow
: [2, 4]});
438 assert
.deepEqual([2, 4], g
.xAxisRange());
441 // zoomCallback is called once when the animation is complete.
442 zoomCallback
: function(xMin
, xMax
) {
443 assert
.equal(1, xMin
);
444 assert
.equal(4, xMax
);
445 assert
.deepEqual([1, 4], g
.xAxisRange());
450 // Zoom out -- resetZoom() _does_ produce an animation.
452 assert
.notDeepEqual([2, 4], g
.xAxisRange()); // first frame is synchronous
453 assert
.notDeepEqual([1, 4], g
.xAxisRange());
455 // at this point control flow goes up to zoomCallback