2 * @fileoverview Test cases for the callbacks.
4 * @author uemit.seren@gmail.com (Ümit Seren)
7 var CallbackTestCase
= TestCase("callback");
9 CallbackTestCase
.prototype.setUp
= function() {
10 document
.body
.innerHTML
= "<div id='graph'></div><div id='selection'></div>";
11 this.xhr
= XMLHttpRequest
;
12 this.styleSheet
= document
.createElement("style");
13 this.styleSheet
.type
= "text/css";
14 document
.getElementsByTagName("head")[0].appendChild(this.styleSheet
);
17 CallbackTestCase
.prototype.tearDown
= function() {
18 XMLHttpRequest
= this.xhr
;
21 var data
= "X,a\,b,c\n" +
29 * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback
30 * is properly called when the first series is hidden (setVisibility = false)
33 CallbackTestCase
.prototype.testHighlightCallbackIsCalled
= function() {
37 var highlightCallback
= function(e
, x
, pts
, row
) {
42 var graph
= document
.getElementById("graph");
43 var g
= new Dygraph(graph
, data
,
47 visibility
: [false, true, true],
48 highlightCallback
: highlightCallback
51 DygraphOps
.dispatchMouseMove(g
, 13, 10);
53 //check correct row is returned
54 assertEquals(3, h_row
);
55 //check there are only two points (because first series is hidden)
56 assertEquals(2, h_pts
.length
);
61 * Test that drawPointCallback isn't called when drawPoints is false
63 CallbackTestCase
.prototype.testDrawPointCallback_disabled
= function() {
66 var callback
= function() {
70 var graph
= document
.getElementById("graph");
71 var g
= new Dygraph(graph
, data
, {
72 drawPointCallback
: callback
,
79 * Test that drawPointCallback is called when drawPoints is true
81 CallbackTestCase
.prototype.testDrawPointCallback_enabled
= function() {
84 var callback
= function() {
88 var graph
= document
.getElementById("graph");
89 var g
= new Dygraph(graph
, data
, {
91 drawPointCallback
: callback
98 * Test that drawPointCallback is called when drawPoints is true
100 CallbackTestCase
.prototype.testDrawPointCallback_pointSize
= function() {
104 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
105 pointSize
= pointSizeParam
;
109 var graph
= document
.getElementById("graph");
110 var g
= new Dygraph(graph
, data
, {
112 drawPointCallback
: callback
115 assertEquals(1.5, pointSize
);
116 assertEquals(12, count
); // one call per data point.
118 var g
= new Dygraph(graph
, data
, {
120 drawPointCallback
: callback
,
124 assertEquals(8, pointSize
);
128 * Test that drawPointCallback is called for isolated points when
129 * drawPoints is false, and also for gap points if that's enabled.
131 CallbackTestCase
.prototype.testDrawPointCallback_isolated
= function() {
135 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
136 var dx
= g
.toDataXCoord(cx
);
138 Dygraph
.Circles
.DEFAULT
.apply(this, arguments
);
141 var graph
= document
.getElementById("graph");
142 var testdata
= [[10, 2], [11, 3], [12, NaN
], [13, 2], [14, NaN
], [15, 3]];
147 drawPointCallback
: callback
,
151 // Test that isolated points get drawn
152 g
= new Dygraph(graph
, testdata
, graphOpts
);
153 assertEquals(2, xvalues
.length
);
154 assertEquals(13, xvalues
[0]);
155 assertEquals(15, xvalues
[1]);
157 // Test that isolated points + gap points get drawn when
158 // drawGapEdgePoints is set. This should add one point at the right
159 // edge of the segment at x=11, but not at the graph edge at x=10.
160 xvalues
= []; // Reset for new test
161 graphOpts
.drawGapEdgePoints
= true;
162 g
= new Dygraph(graph
, testdata
, graphOpts
);
163 assertEquals(3, xvalues
.length
);
164 assertEquals(11, xvalues
[0]);
165 assertEquals(13, xvalues
[1]);
166 assertEquals(15, xvalues
[2]);
170 * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback
171 * is properly called when the first series is hidden (setVisibility = false)
174 CallbackTestCase
.prototype.testDrawHighlightPointCallbackIsCalled
= function() {
177 var drawHighlightPointCallback
= function() {
181 var graph
= document
.getElementById("graph");
182 var g
= new Dygraph(graph
, data
,
186 drawHighlightPointCallback
: drawHighlightPointCallback
190 DygraphOps
.dispatchMouseMove(g
, 13, 10);
195 * Test the closest-series highlighting methods for normal and stacked modes.
196 * Also pass in line widths for plain and highlighted lines for easier visual
197 * confirmation that the highlighted line is drawn on top of the others.
199 var runClosestTest
= function(isStacked
, widthNormal
, widthHighlighted
) {
204 var graph
= document
.getElementById("graph");
205 var g
= new Dygraph(graph
, data
,
209 visibility
: [false, true, true],
210 stackedGraph
: isStacked
,
211 strokeWidth
: widthNormal
,
212 strokeBorderWidth
: 2,
213 highlightCircleSize
: widthNormal
* 2,
214 highlightSeriesBackgroundAlpha
: 0.3,
216 highlightSeriesOpts
: {
217 strokeWidth
: widthHighlighted
,
218 highlightCircleSize
: widthHighlighted
* 2
222 var highlightCallback
= function(e
, x
, pts
, row
, set
) {
226 document
.getElementById('selection').innerHTML
='row=' + row
+ ', set=' + set
;
229 g
.updateOptions({highlightCallback
: highlightCallback
}, true);
232 DygraphOps
.dispatchMouseMove(g
, 11.45, 1.4);
233 assertEquals(1, h_row
);
234 assertEquals('c', h_series
);
236 //now move up in the same row
237 DygraphOps
.dispatchMouseMove(g
, 11.45, 1.5);
238 assertEquals(1, h_row
);
239 assertEquals('b', h_series
);
241 //and a bit to the right
242 DygraphOps
.dispatchMouseMove(g
, 11.55, 1.5);
243 assertEquals(2, h_row
);
244 assertEquals('c', h_series
);
246 DygraphOps
.dispatchMouseMove(g
, 11, 1.5);
247 assertEquals(1, h_row
);
248 assertEquals('c', h_series
);
250 //now move up in the same row
251 DygraphOps
.dispatchMouseMove(g
, 11, 2.5);
252 assertEquals(1, h_row
);
253 assertEquals('b', h_series
);
260 * Test basic closest-point highlighting.
262 CallbackTestCase
.prototype.testClosestPointCallback
= function() {
263 runClosestTest(false, 1, 3);
267 * Test setSelection() with series name
269 CallbackTestCase
.prototype.testSetSelection
= function() {
270 var g
= runClosestTest(false, 1, 3);
271 assertEquals(1, g
.attr_('strokeWidth', 'c'));
272 g
.setSelection(false, 'c');
273 assertEquals(3, g
.attr_('strokeWidth', 'c'));
277 * Test closest-point highlighting for stacked graph
279 CallbackTestCase
.prototype.testClosestPointStackedCallback
= function() {
280 runClosestTest(true, 1, 3);
284 * Closest-point highlighting with legend CSS - border around active series.
286 CallbackTestCase
.prototype.testClosestPointCallbackCss1
= function() {
287 var css
= "div.dygraph-legend > span { display: block; }\n" +
288 "div.dygraph-legend > span.highlight { border: 1px solid grey; }\n";
289 this.styleSheet
.innerHTML
= css
;
290 runClosestTest(false, 2, 4);
291 this.styleSheet
.innerHTML
= '';
295 * Closest-point highlighting with legend CSS - show only closest series.
297 CallbackTestCase
.prototype.testClosestPointCallbackCss2
= function() {
298 var css
= "div.dygraph-legend > span { display: none; }\n" +
299 "div.dygraph-legend > span.highlight { display: inline; }\n";
300 this.styleSheet
.innerHTML
= css
;
301 runClosestTest(false, 10, 15);
302 this.styleSheet
.innerHTML
= '';
303 // TODO(klausw): verify that the highlighted line is drawn on top?
307 * Closest-point highlighting with locked series.
309 CallbackTestCase
.prototype.testSetSelectionLocking
= function() {
310 var g
= runClosestTest(false, 2, 4);
312 // Default behavior, 'b' is closest
313 DygraphOps
.dispatchMouseMove(g
, 11, 4);
314 assertEquals('b', g
.getHighlightSeries());
316 // Now lock selection to 'c'
317 g
.setSelection(false, 'c', true);
318 DygraphOps
.dispatchMouseMove(g
, 11, 4);
319 assertEquals('c', g
.getHighlightSeries());
321 // Unlock, should be back to 'b'
323 DygraphOps
.dispatchMouseMove(g
, 11, 4);
324 assertEquals('b', g
.getHighlightSeries());
328 * This tests that closest point searches work for data containing NaNs.
330 * It's intended to catch a regression where a NaN Y value confuses the
331 * closest-point algorithm, treating it as closer as any previous point.
333 CallbackTestCase
.prototype.testNaNData
= function() {
345 var highlightCallback
= function(e
, x
, pts
, row
) {
350 var graph
= document
.getElementById("graph");
351 var g
= new Dygraph(graph
, dataNaN
,
355 labels
: ['x', 'a', 'b', 'c'],
356 visibility
: [false, true, true],
357 highlightCallback
: highlightCallback
360 DygraphOps
.dispatchMouseMove(g
, 10.1, 0.9);
361 //check correct row is returned
362 assertEquals(1, h_row
);
364 // Explicitly test closest point algorithms
365 var dom
= g
.toDomCoords(10.1, 0.9);
366 assertEquals(1, g
.findClosestRow(dom
[0]));
368 var res
= g
.findClosestPoint(dom
[0], dom
[1]);
369 assertEquals(1, res
.row
);
370 assertEquals('b', res
.seriesName
);
372 res
= g
.findStackedPoint(dom
[0], dom
[1]);
373 assertEquals(1, res
.row
);
374 assertEquals('c', res
.seriesName
);
378 * This tests that stacked point searches work for data containing NaNs.
380 CallbackTestCase
.prototype.testNaNDataStack
= function() {
397 var highlightCallback
= function(e
, x
, pts
, row
) {
402 var graph
= document
.getElementById("graph");
403 var g
= new Dygraph(graph
, dataNaN
,
407 labels
: ['x', 'a', 'b', 'c'],
408 visibility
: [false, true, true],
410 highlightCallback
: highlightCallback
413 DygraphOps
.dispatchMouseMove(g
, 10.1, 0.9);
414 //check correct row is returned
415 assertEquals(1, h_row
);
417 // Explicitly test stacked point algorithm.
418 var dom
= g
.toDomCoords(10.1, 0.9);
419 var res
= g
.findStackedPoint(dom
[0], dom
[1]);
420 assertEquals(1, res
.row
);
421 assertEquals('c', res
.seriesName
);
423 // All-NaN area at left, should get no points.
424 dom
= g
.toDomCoords(9.1, 0.9);
425 res
= g
.findStackedPoint(dom
[0], dom
[1]);
426 assertEquals(0, res
.row
);
427 assertEquals(undefined
, res
.seriesName
);
429 // First gap, get 'c' since it's non-NaN.
430 dom
= g
.toDomCoords(12.1, 0.9);
431 res
= g
.findStackedPoint(dom
[0], dom
[1]);
432 assertEquals(3, res
.row
);
433 assertEquals('c', res
.seriesName
);
435 // Second gap, get 'b' since 'c' is NaN.
436 dom
= g
.toDomCoords(15.1, 0.9);
437 res
= g
.findStackedPoint(dom
[0], dom
[1]);
438 assertEquals(6, res
.row
);
439 assertEquals('b', res
.seriesName
);
441 // Isolated points should work, finding series b in this case.
442 dom
= g
.toDomCoords(15.9, 3.1);
443 res
= g
.findStackedPoint(dom
[0], dom
[1]);
444 assertEquals(7, res
.row
);
445 assertEquals('b', res
.seriesName
);
448 CallbackTestCase
.prototype.testGapHighlight
= function() {
462 var highlightCallback
= function(e
, x
, pts
, row
) {
467 var graph
= document
.getElementById("graph");
468 var g
= new Dygraph(graph
, dataGap
, {
471 //stackedGraph: true,
472 connectSeparatedPoints
: true,
474 labels
: ['x', 'A', 'B'],
475 highlightCallback
: highlightCallback
478 DygraphOps
.dispatchMouseMove(g
, 1.1, 10);
479 //point from series B
480 assertEquals(0, h_row
);
481 assertEquals(1, h_pts
.length
);
482 assertEquals(3, h_pts
[0].yval
);
483 assertEquals('B', h_pts
[0].name
);
485 DygraphOps
.dispatchMouseMove(g
, 6.1, 10);
487 assertEquals(1, h_pts
.length
);
488 assert(isNaN(h_pts
[0].yval
));
489 assertEquals('A', h_pts
[0].name
);
491 DygraphOps
.dispatchMouseMove(g
, 8.1, 10);
492 //point from series A
493 assertEquals(6, h_row
);
494 assertEquals(1, h_pts
.length
);
495 assertEquals(8, h_pts
[0].yval
);
496 assertEquals('A', h_pts
[0].name
);
499 CallbackTestCase
.prototype.testFailedResponse
= function() {
501 // Fake out the XMLHttpRequest so it doesn't do anything.
502 XMLHttpRequest
= function () {};
503 XMLHttpRequest
.prototype.open
= function () {};
504 XMLHttpRequest
.prototype.send
= function () {};
506 var highlightCallback
= function(e
, x
, pts
, row
) {
507 fail("should not reach here");
510 var graph
= document
.getElementById("graph");
511 graph
.style
.border
= "2px solid black";
512 var g
= new Dygraph(graph
, "data.csv", { // fake name
515 highlightCallback
: highlightCallback
518 DygraphOps
.dispatchMouseOver_Point(g
, 800, 800);
519 DygraphOps
.dispatchMouseMove_Point(g
, 100, 100);
520 DygraphOps
.dispatchMouseMove_Point(g
, 800, 800);
522 var oldOnerror
= window
.onerror
;
524 window
.onerror
= function() { failed
= true; return false; }
526 DygraphOps
.dispatchMouseOut_Point(g
, 800, 800); // This call should not throw an exception.
528 assertFalse("exception thrown during mouseout", failed
);
532 // Regression test for http://code.google.com/p/dygraphs/issues/detail
?id
=355
533 CallbackTestCase
.prototype.testHighlightCallbackRow
= function() {
535 var highlightCallback
= function(e
, x
, pts
, row
) {
539 var graph
= document
.getElementById("graph");
540 var g
= new Dygraph(graph
,
550 highlightCallback
: highlightCallback
553 // Mouse over each of the points
554 DygraphOps
.dispatchMouseOver_Point(g
, 0, 0);
555 DygraphOps
.dispatchMouseMove_Point(g
, 0, 0);
556 assertEquals(0, highlightRow
);
557 DygraphOps
.dispatchMouseMove_Point(g
, 100, 0);
558 assertEquals(1, highlightRow
);
559 DygraphOps
.dispatchMouseMove_Point(g
, 200, 0);
560 assertEquals(2, highlightRow
);
561 DygraphOps
.dispatchMouseMove_Point(g
, 300, 0);
562 assertEquals(3, highlightRow
);
563 DygraphOps
.dispatchMouseMove_Point(g
, 400, 0);
564 assertEquals(4, highlightRow
);
566 // Now zoom and verify that the row numbers still refer to rows in the data
568 g
.updateOptions({dateWindow
: [2, 4]});
569 DygraphOps
.dispatchMouseOver_Point(g
, 0, 0);
570 DygraphOps
.dispatchMouseMove_Point(g
, 0, 0);
571 assertEquals(2, highlightRow
);
572 assertEquals('2: Y: 3 Z: 4', Util
.getLegend());
576 * Test that underlay callback is called even when there are no series,
577 * and that the y axis ranges are not NaN.
579 CallbackTestCase
.prototype.underlayCallback_noSeries
= function() {
583 var callback
= function(canvas
, area
, g
) {
585 yMin
= g
.yAxisRange(0)[0];
586 yMax
= g
.yAxisRange(0)[1];
589 var graph
= document
.getElementById("graph");
590 var g
= new Dygraph(graph
, "\n", {
591 underlayCallback
: callback
595 assertFalse(isNaN(yMin
));
596 assertFalse(isNaN(yMax
));
600 * Test that underlay callback receives the correct y-axis range.
602 CallbackTestCase
.prototype.underlayCallback_yAxisRange
= function() {
606 var callback
= function(canvas
, area
, g
) {
607 yMin
= g
.yAxisRange(0)[0];
608 yMax
= g
.yAxisRange(0)[1];
611 var graph
= document
.getElementById("graph");
612 var g
= new Dygraph(graph
, "\n", {
614 underlayCallback
: callback
617 assertEquals(0, yMin
);
618 assertEquals(10, yMax
);
622 * Test that drawPointCallback is called for isolated points and correct idx for the point is returned.
624 CallbackTestCase
.prototype.testDrawPointCallback_idx
= function() {
628 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
630 Dygraph
.Circles
.DEFAULT
.apply(this, arguments
);
633 var graph
= document
.getElementById("graph");
635 var testdata
= [[10, 2], [11, 3], [12, NaN
], [13, 2], [14, NaN
], [15, 3]];
640 drawPointCallback
: callback
,
644 // Test that correct idx for isolated points are passed to the callback.
645 g
= new Dygraph(graph
, testdata
, graphOpts
);
646 assertEquals(2, indices
.length
);
647 assertEquals([3, 5],indices
);
649 // Test that correct indices for isolated points + gap points are passed to the callback when
650 // drawGapEdgePoints is set. This should add one point at the right
651 // edge of the segment at x=11, but not at the graph edge at x=10.
652 indices
= []; // Reset for new test
653 graphOpts
.drawGapEdgePoints
= true;
654 g
= new Dygraph(graph
, testdata
, graphOpts
);
655 assertEquals(3, indices
.length
);
656 assertEquals([1, 3, 5],indices
);
659 //Test that correct indices are passed to the callback when zoomed in.
660 indices
= []; // Reset for new test
661 graphOpts
.dateWindow
= [12.5,13.5]
662 graphOpts
.drawPoints
= true;
663 testdata
= [[10, 2], [11, 3], [12, 4], [13, 2], [14, 5], [15, 3]];
664 g
= new Dygraph(graph
, testdata
, graphOpts
);
665 assertEquals(3, indices
.length
);
666 assertEquals([2, 3, 4],indices
);
670 * Test that the correct idx is returned for the point in the onHiglightCallback.
672 CallbackTestCase
.prototype.testDrawHighlightPointCallback_idx
= function() {
673 var idxToCheck
= null;
675 var drawHighlightPointCallback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
678 var testdata
= [[1, 2], [2, 3], [3, NaN
], [4, 2], [5, NaN
], [6, 3]];
679 var graph
= document
.getElementById("graph");
680 var g
= new Dygraph(graph
, testdata
,
682 drawHighlightPointCallback
: drawHighlightPointCallback
685 assertNull(idxToCheck
);
686 DygraphOps
.dispatchMouseMove(g
, 3, 0);
687 // check that NaN point is not highlighted
688 assertNull(idxToCheck
);
689 DygraphOps
.dispatchMouseMove(g
, 1, 2);
690 // check that correct index is returned
691 assertEquals(0,idxToCheck
);
692 DygraphOps
.dispatchMouseMove(g
, 6, 3);
693 assertEquals(5,idxToCheck
);