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
) {
38 assertEquals(g
, this);
43 var graph
= document
.getElementById("graph");
44 var g
= new Dygraph(graph
, data
,
48 visibility
: [false, true, true],
49 highlightCallback
: highlightCallback
52 DygraphOps
.dispatchMouseMove(g
, 13, 10);
54 //check correct row is returned
55 assertEquals(3, h_row
);
56 //check there are only two points (because first series is hidden)
57 assertEquals(2, h_pts
.length
);
62 * Test that drawPointCallback isn't called when drawPoints is false
64 CallbackTestCase
.prototype.testDrawPointCallback_disabled
= function() {
67 var callback
= function() {
68 assertEquals(g
, this);
72 var graph
= document
.getElementById("graph");
73 var g
= new Dygraph(graph
, data
, {
74 drawPointCallback
: callback
,
81 * Test that drawPointCallback is called when drawPoints is true
83 CallbackTestCase
.prototype.testDrawPointCallback_enabled
= function() {
85 var callbackThis
= null;
87 var callback
= function() {
92 var graph
= document
.getElementById("graph");
93 var g
= new Dygraph(graph
, data
, {
95 drawPointCallback
: callback
99 assertEquals(g
, callbackThis
);
103 * Test that drawPointCallback is called when drawPoints is true
105 CallbackTestCase
.prototype.testDrawPointCallback_pointSize
= function() {
109 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
110 assertEquals(g
, this);
111 pointSize
= pointSizeParam
;
115 var graph
= document
.getElementById("graph");
116 var g
= new Dygraph(graph
, data
, {
118 drawPointCallback
: callback
121 assertEquals(1.5, pointSize
);
122 assertEquals(12, count
); // one call per data point.
124 var g
= new Dygraph(graph
, data
, {
126 drawPointCallback
: callback
,
130 assertEquals(8, pointSize
);
134 * Test that drawPointCallback is called for isolated points when
135 * drawPoints is false, and also for gap points if that's enabled.
137 CallbackTestCase
.prototype.testDrawPointCallback_isolated
= function() {
141 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
142 assertEquals(g
, this);
143 var dx
= g
.toDataXCoord(cx
);
145 Dygraph
.Circles
.DEFAULT
.apply(this, arguments
);
148 var graph
= document
.getElementById("graph");
149 var testdata
= [[10, 2], [11, 3], [12, NaN
], [13, 2], [14, NaN
], [15, 3]];
154 drawPointCallback
: callback
,
158 // Test that isolated points get drawn
159 g
= new Dygraph(graph
, testdata
, graphOpts
);
160 assertEquals(2, xvalues
.length
);
161 assertEquals(13, xvalues
[0]);
162 assertEquals(15, xvalues
[1]);
164 // Test that isolated points + gap points get drawn when
165 // drawGapEdgePoints is set. This should add one point at the right
166 // edge of the segment at x=11, but not at the graph edge at x=10.
167 xvalues
= []; // Reset for new test
168 graphOpts
.drawGapEdgePoints
= true;
169 g
= new Dygraph(graph
, testdata
, graphOpts
);
170 assertEquals(3, xvalues
.length
);
171 assertEquals(11, xvalues
[0]);
172 assertEquals(13, xvalues
[1]);
173 assertEquals(15, xvalues
[2]);
177 * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback
178 * is properly called when the first series is hidden (setVisibility = false)
181 CallbackTestCase
.prototype.testDrawHighlightPointCallbackIsCalled
= function() {
184 var drawHighlightPointCallback
= function() {
185 assertEquals(g
, this);
189 var graph
= document
.getElementById("graph");
190 var g
= new Dygraph(graph
, data
,
194 drawHighlightPointCallback
: drawHighlightPointCallback
198 DygraphOps
.dispatchMouseMove(g
, 13, 10);
203 * Test the closest-series highlighting methods for normal and stacked modes.
204 * Also pass in line widths for plain and highlighted lines for easier visual
205 * confirmation that the highlighted line is drawn on top of the others.
207 var runClosestTest
= function(isStacked
, widthNormal
, widthHighlighted
) {
212 var graph
= document
.getElementById("graph");
213 var g
= new Dygraph(graph
, data
,
217 visibility
: [false, true, true],
218 stackedGraph
: isStacked
,
219 strokeWidth
: widthNormal
,
220 strokeBorderWidth
: 2,
221 highlightCircleSize
: widthNormal
* 2,
222 highlightSeriesBackgroundAlpha
: 0.3,
224 highlightSeriesOpts
: {
225 strokeWidth
: widthHighlighted
,
226 highlightCircleSize
: widthHighlighted
* 2
230 var highlightCallback
= function(e
, x
, pts
, row
, set
) {
231 assertEquals(g
, this);
235 document
.getElementById('selection').innerHTML
='row=' + row
+ ', set=' + set
;
238 g
.updateOptions({highlightCallback
: highlightCallback
}, true);
241 DygraphOps
.dispatchMouseMove(g
, 11.45, 1.4);
242 assertEquals(1, h_row
);
243 assertEquals('c', h_series
);
245 //now move up in the same row
246 DygraphOps
.dispatchMouseMove(g
, 11.45, 1.5);
247 assertEquals(1, h_row
);
248 assertEquals('b', h_series
);
250 //and a bit to the right
251 DygraphOps
.dispatchMouseMove(g
, 11.55, 1.5);
252 assertEquals(2, h_row
);
253 assertEquals('c', h_series
);
255 DygraphOps
.dispatchMouseMove(g
, 11, 1.5);
256 assertEquals(1, h_row
);
257 assertEquals('c', h_series
);
259 //now move up in the same row
260 DygraphOps
.dispatchMouseMove(g
, 11, 2.5);
261 assertEquals(1, h_row
);
262 assertEquals('b', h_series
);
269 * Test basic closest-point highlighting.
271 CallbackTestCase
.prototype.testClosestPointCallback
= function() {
272 runClosestTest(false, 1, 3);
276 * Test setSelection() with series name
278 CallbackTestCase
.prototype.testSetSelection
= function() {
279 var g
= runClosestTest(false, 1, 3);
280 assertEquals(1, g
.attr_('strokeWidth', 'c'));
281 g
.setSelection(false, 'c');
282 assertEquals(3, g
.attr_('strokeWidth', 'c'));
286 * Test closest-point highlighting for stacked graph
288 CallbackTestCase
.prototype.testClosestPointStackedCallback
= function() {
289 runClosestTest(true, 1, 3);
293 * Closest-point highlighting with legend CSS - border around active series.
295 CallbackTestCase
.prototype.testClosestPointCallbackCss1
= function() {
296 var css
= "div.dygraph-legend > span { display: block; }\n" +
297 "div.dygraph-legend > span.highlight { border: 1px solid grey; }\n";
298 this.styleSheet
.innerHTML
= css
;
299 runClosestTest(false, 2, 4);
300 this.styleSheet
.innerHTML
= '';
304 * Closest-point highlighting with legend CSS - show only closest series.
306 CallbackTestCase
.prototype.testClosestPointCallbackCss2
= function() {
307 var css
= "div.dygraph-legend > span { display: none; }\n" +
308 "div.dygraph-legend > span.highlight { display: inline; }\n";
309 this.styleSheet
.innerHTML
= css
;
310 runClosestTest(false, 10, 15);
311 this.styleSheet
.innerHTML
= '';
312 // TODO(klausw): verify that the highlighted line is drawn on top?
316 * Closest-point highlighting with locked series.
318 CallbackTestCase
.prototype.testSetSelectionLocking
= function() {
319 var g
= runClosestTest(false, 2, 4);
321 // Default behavior, 'b' is closest
322 DygraphOps
.dispatchMouseMove(g
, 11, 4);
323 assertEquals('b', g
.getHighlightSeries());
325 // Now lock selection to 'c'
326 g
.setSelection(false, 'c', true);
327 DygraphOps
.dispatchMouseMove(g
, 11, 4);
328 assertEquals('c', g
.getHighlightSeries());
330 // Unlock, should be back to 'b'
332 DygraphOps
.dispatchMouseMove(g
, 11, 4);
333 assertEquals('b', g
.getHighlightSeries());
337 * This tests that closest point searches work for data containing NaNs.
339 * It's intended to catch a regression where a NaN Y value confuses the
340 * closest-point algorithm, treating it as closer as any previous point.
342 CallbackTestCase
.prototype.testNaNData
= function() {
354 var highlightCallback
= function(e
, x
, pts
, row
) {
355 assertEquals(g
, this);
360 var graph
= document
.getElementById("graph");
361 var g
= new Dygraph(graph
, dataNaN
,
365 labels
: ['x', 'a', 'b', 'c'],
366 visibility
: [false, true, true],
367 highlightCallback
: highlightCallback
370 DygraphOps
.dispatchMouseMove(g
, 10.1, 0.9);
371 //check correct row is returned
372 assertEquals(1, h_row
);
374 // Explicitly test closest point algorithms
375 var dom
= g
.toDomCoords(10.1, 0.9);
376 assertEquals(1, g
.findClosestRow(dom
[0]));
378 var res
= g
.findClosestPoint(dom
[0], dom
[1]);
379 assertEquals(1, res
.row
);
380 assertEquals('b', res
.seriesName
);
382 res
= g
.findStackedPoint(dom
[0], dom
[1]);
383 assertEquals(1, res
.row
);
384 assertEquals('c', res
.seriesName
);
388 * This tests that stacked point searches work for data containing NaNs.
390 CallbackTestCase
.prototype.testNaNDataStack
= function() {
407 var highlightCallback
= function(e
, x
, pts
, row
) {
408 assertEquals(g
, this);
413 var graph
= document
.getElementById("graph");
414 var g
= new Dygraph(graph
, dataNaN
,
418 labels
: ['x', 'a', 'b', 'c'],
419 visibility
: [false, true, true],
421 highlightCallback
: highlightCallback
424 DygraphOps
.dispatchMouseMove(g
, 10.1, 0.9);
425 //check correct row is returned
426 assertEquals(1, h_row
);
428 // Explicitly test stacked point algorithm.
429 var dom
= g
.toDomCoords(10.1, 0.9);
430 var res
= g
.findStackedPoint(dom
[0], dom
[1]);
431 assertEquals(1, res
.row
);
432 assertEquals('c', res
.seriesName
);
434 // All-NaN area at left, should get no points.
435 dom
= g
.toDomCoords(9.1, 0.9);
436 res
= g
.findStackedPoint(dom
[0], dom
[1]);
437 assertEquals(0, res
.row
);
438 assertEquals(undefined
, res
.seriesName
);
440 // First gap, get 'c' since it's non-NaN.
441 dom
= g
.toDomCoords(12.1, 0.9);
442 res
= g
.findStackedPoint(dom
[0], dom
[1]);
443 assertEquals(3, res
.row
);
444 assertEquals('c', res
.seriesName
);
446 // Second gap, get 'b' since 'c' is NaN.
447 dom
= g
.toDomCoords(15.1, 0.9);
448 res
= g
.findStackedPoint(dom
[0], dom
[1]);
449 assertEquals(6, res
.row
);
450 assertEquals('b', res
.seriesName
);
452 // Isolated points should work, finding series b in this case.
453 dom
= g
.toDomCoords(15.9, 3.1);
454 res
= g
.findStackedPoint(dom
[0], dom
[1]);
455 assertEquals(7, res
.row
);
456 assertEquals('b', res
.seriesName
);
459 CallbackTestCase
.prototype.testGapHighlight
= function() {
473 var highlightCallback
= function(e
, x
, pts
, row
) {
474 assertEquals(g
, this);
479 var graph
= document
.getElementById("graph");
480 var g
= new Dygraph(graph
, dataGap
, {
483 //stackedGraph: true,
484 connectSeparatedPoints
: true,
486 labels
: ['x', 'A', 'B'],
487 highlightCallback
: highlightCallback
490 DygraphOps
.dispatchMouseMove(g
, 1.1, 10);
491 //point from series B
492 assertEquals(0, h_row
);
493 assertEquals(1, h_pts
.length
);
494 assertEquals(3, h_pts
[0].yval
);
495 assertEquals('B', h_pts
[0].name
);
497 DygraphOps
.dispatchMouseMove(g
, 6.1, 10);
499 assertEquals(1, h_pts
.length
);
500 assert(isNaN(h_pts
[0].yval
));
501 assertEquals('A', h_pts
[0].name
);
503 DygraphOps
.dispatchMouseMove(g
, 8.1, 10);
504 //point from series A
505 assertEquals(6, h_row
);
506 assertEquals(1, h_pts
.length
);
507 assertEquals(8, h_pts
[0].yval
);
508 assertEquals('A', h_pts
[0].name
);
511 CallbackTestCase
.prototype.testFailedResponse
= function() {
513 // Fake out the XMLHttpRequest so it doesn't do anything.
514 XMLHttpRequest
= function () {};
515 XMLHttpRequest
.prototype.open
= function () {};
516 XMLHttpRequest
.prototype.send
= function () {};
518 var highlightCallback
= function(e
, x
, pts
, row
) {
519 fail("should not reach here");
522 var graph
= document
.getElementById("graph");
523 graph
.style
.border
= "2px solid black";
524 var g
= new Dygraph(graph
, "data.csv", { // fake name
527 highlightCallback
: highlightCallback
530 DygraphOps
.dispatchMouseOver_Point(g
, 800, 800);
531 DygraphOps
.dispatchMouseMove_Point(g
, 100, 100);
532 DygraphOps
.dispatchMouseMove_Point(g
, 800, 800);
534 var oldOnerror
= window
.onerror
;
536 window
.onerror
= function() { failed
= true; return false; }
538 DygraphOps
.dispatchMouseOut_Point(g
, 800, 800); // This call should not throw an exception.
540 assertFalse("exception thrown during mouseout", failed
);
544 // Regression test for http://code.google.com/p/dygraphs/issues/detail
?id
=355
545 CallbackTestCase
.prototype.testHighlightCallbackRow
= function() {
547 var highlightCallback
= function(e
, x
, pts
, row
) {
548 assertEquals(g
, this);
552 var graph
= document
.getElementById("graph");
553 var g
= new Dygraph(graph
,
563 highlightCallback
: highlightCallback
566 // Mouse over each of the points
567 DygraphOps
.dispatchMouseOver_Point(g
, 0, 0);
568 DygraphOps
.dispatchMouseMove_Point(g
, 0, 0);
569 assertEquals(0, highlightRow
);
570 DygraphOps
.dispatchMouseMove_Point(g
, 100, 0);
571 assertEquals(1, highlightRow
);
572 DygraphOps
.dispatchMouseMove_Point(g
, 200, 0);
573 assertEquals(2, highlightRow
);
574 DygraphOps
.dispatchMouseMove_Point(g
, 300, 0);
575 assertEquals(3, highlightRow
);
576 DygraphOps
.dispatchMouseMove_Point(g
, 400, 0);
577 assertEquals(4, highlightRow
);
579 // Now zoom and verify that the row numbers still refer to rows in the data
581 g
.updateOptions({dateWindow
: [2, 4]});
582 DygraphOps
.dispatchMouseOver_Point(g
, 0, 0);
583 DygraphOps
.dispatchMouseMove_Point(g
, 0, 0);
584 assertEquals(2, highlightRow
);
585 assertEquals('2: Y: 3 Z: 4', Util
.getLegend());
589 * Test that underlay callback is called even when there are no series,
590 * and that the y axis ranges are not NaN.
592 CallbackTestCase
.prototype.underlayCallback_noSeries
= function() {
596 var callback
= function(canvas
, area
, g
) {
597 assertEquals(g
, this);
599 yMin
= g
.yAxisRange(0)[0];
600 yMax
= g
.yAxisRange(0)[1];
603 var graph
= document
.getElementById("graph");
604 var g
= new Dygraph(graph
, "\n", {
605 underlayCallback
: callback
609 assertFalse(isNaN(yMin
));
610 assertFalse(isNaN(yMax
));
614 * Test that underlay callback receives the correct y-axis range.
616 CallbackTestCase
.prototype.underlayCallback_yAxisRange
= function() {
620 var callback
= function(canvas
, area
, g
) {
621 assertEquals(g
, this);
622 yMin
= g
.yAxisRange(0)[0];
623 yMax
= g
.yAxisRange(0)[1];
626 var graph
= document
.getElementById("graph");
627 var g
= new Dygraph(graph
, "\n", {
629 underlayCallback
: callback
632 assertEquals(0, yMin
);
633 assertEquals(10, yMax
);
637 * Test that drawPointCallback is called for isolated points and correct idx for the point is returned.
639 CallbackTestCase
.prototype.testDrawPointCallback_idx
= function() {
643 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
644 assertEquals(g
, this);
646 Dygraph
.Circles
.DEFAULT
.apply(this, arguments
);
649 var graph
= document
.getElementById("graph");
651 var testdata
= [[10, 2], [11, 3], [12, NaN
], [13, 2], [14, NaN
], [15, 3]];
656 drawPointCallback
: callback
,
660 // Test that correct idx for isolated points are passed to the callback.
661 g
= new Dygraph(graph
, testdata
, graphOpts
);
662 assertEquals(2, indices
.length
);
663 assertEquals([3, 5],indices
);
665 // Test that correct indices for isolated points + gap points are passed to the callback when
666 // drawGapEdgePoints is set. This should add one point at the right
667 // edge of the segment at x=11, but not at the graph edge at x=10.
668 indices
= []; // Reset for new test
669 graphOpts
.drawGapEdgePoints
= true;
670 g
= new Dygraph(graph
, testdata
, graphOpts
);
671 assertEquals(3, indices
.length
);
672 assertEquals([1, 3, 5],indices
);
675 //Test that correct indices are passed to the callback when zoomed in.
676 indices
= []; // Reset for new test
677 graphOpts
.dateWindow
= [12.5,13.5]
678 graphOpts
.drawPoints
= true;
679 testdata
= [[10, 2], [11, 3], [12, 4], [13, 2], [14, 5], [15, 3]];
680 g
= new Dygraph(graph
, testdata
, graphOpts
);
681 assertEquals(3, indices
.length
);
682 assertEquals([2, 3, 4],indices
);
686 * Test that the correct idx is returned for the point in the onHiglightCallback.
688 CallbackTestCase
.prototype.testDrawHighlightPointCallback_idx
= function() {
689 var idxToCheck
= null;
691 var drawHighlightPointCallback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
692 assertEquals(g
, this);
695 var testdata
= [[1, 2], [2, 3], [3, NaN
], [4, 2], [5, NaN
], [6, 3]];
696 var graph
= document
.getElementById("graph");
697 var g
= new Dygraph(graph
, testdata
,
699 drawHighlightPointCallback
: drawHighlightPointCallback
702 assertNull(idxToCheck
);
703 DygraphOps
.dispatchMouseMove(g
, 3, 0);
704 // check that NaN point is not highlighted
705 assertNull(idxToCheck
);
706 DygraphOps
.dispatchMouseMove(g
, 1, 2);
707 // check that correct index is returned
708 assertEquals(0,idxToCheck
);
709 DygraphOps
.dispatchMouseMove(g
, 6, 3);
710 assertEquals(5,idxToCheck
);