2 * @fileoverview Test cases for the callbacks.
4 * @author uemit.seren@gmail.com (Ümit Seren)
7 var CallbackTestCase
= TestCase("callback");
11 CallbackTestCase
.prototype.setUp
= function() {
12 document
.body
.innerHTML
= "<div id='graph'></div><div id='selection'></div>";
14 styleSheet
= document
.createElement("style");
15 styleSheet
.type
= "text/css";
16 document
.getElementsByTagName("head")[0].appendChild(styleSheet
);
19 CallbackTestCase
.prototype.tearDown
= function() {
23 var data
= "X,a\,b,c\n" +
31 * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback
32 * is properly called when the first series is hidden (setVisibility = false)
35 CallbackTestCase
.prototype.testHighlightCallbackIsCalled
= function() {
39 var highlightCallback
= function(e
, x
, pts
, row
) {
40 assertEquals(g
, this);
45 var graph
= document
.getElementById("graph");
46 var g
= new Dygraph(graph
, data
,
50 visibility
: [false, true, true],
51 highlightCallback
: highlightCallback
54 DygraphOps
.dispatchMouseMove(g
, 13, 10);
56 //check correct row is returned
57 assertEquals(3, h_row
);
58 //check there are only two points (because first series is hidden)
59 assertEquals(2, h_pts
.length
);
64 * Test that drawPointCallback isn't called when drawPoints is false
66 CallbackTestCase
.prototype.testDrawPointCallback_disabled
= function() {
69 var callback
= function() {
70 assertEquals(g
, this);
74 var graph
= document
.getElementById("graph");
75 var g
= new Dygraph(graph
, data
, {
76 drawPointCallback
: callback
,
83 * Test that drawPointCallback is called when drawPoints is true
85 CallbackTestCase
.prototype.testDrawPointCallback_enabled
= function() {
87 var callbackThis
= null;
89 var callback
= function() {
94 var graph
= document
.getElementById("graph");
95 var g
= new Dygraph(graph
, data
, {
97 drawPointCallback
: callback
101 assertEquals(g
, callbackThis
);
105 * Test that drawPointCallback is called when drawPoints is true
107 CallbackTestCase
.prototype.testDrawPointCallback_pointSize
= function() {
111 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
112 assertEquals(g
, this);
113 pointSize
= pointSizeParam
;
117 var graph
= document
.getElementById("graph");
118 var g
= new Dygraph(graph
, data
, {
120 drawPointCallback
: callback
123 assertEquals(1.5, pointSize
);
124 assertEquals(12, count
); // one call per data point.
126 var g
= new Dygraph(graph
, data
, {
128 drawPointCallback
: callback
,
132 assertEquals(8, pointSize
);
136 * Test that drawPointCallback is called for isolated points when
137 * drawPoints is false, and also for gap points if that's enabled.
139 CallbackTestCase
.prototype.testDrawPointCallback_isolated
= function() {
143 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
144 assertEquals(g
, this);
145 var dx
= g
.toDataXCoord(cx
);
147 Dygraph
.Circles
.DEFAULT
.apply(this, arguments
);
150 var graph
= document
.getElementById("graph");
151 var testdata
= [[10, 2], [11, 3], [12, NaN
], [13, 2], [14, NaN
], [15, 3]];
156 drawPointCallback
: callback
,
160 // Test that isolated points get drawn
161 g
= new Dygraph(graph
, testdata
, graphOpts
);
162 assertEquals(2, xvalues
.length
);
163 assertEquals(13, xvalues
[0]);
164 assertEquals(15, xvalues
[1]);
166 // Test that isolated points + gap points get drawn when
167 // drawGapEdgePoints is set. This should add one point at the right
168 // edge of the segment at x=11, but not at the graph edge at x=10.
169 xvalues
= []; // Reset for new test
170 graphOpts
.drawGapEdgePoints
= true;
171 g
= new Dygraph(graph
, testdata
, graphOpts
);
172 assertEquals(3, xvalues
.length
);
173 assertEquals(11, xvalues
[0]);
174 assertEquals(13, xvalues
[1]);
175 assertEquals(15, xvalues
[2]);
179 * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback
180 * is properly called when the first series is hidden (setVisibility = false)
183 CallbackTestCase
.prototype.testDrawHighlightPointCallbackIsCalled
= function() {
186 var drawHighlightPointCallback
= function() {
187 assertEquals(g
, this);
191 var graph
= document
.getElementById("graph");
192 var g
= new Dygraph(graph
, data
,
196 drawHighlightPointCallback
: drawHighlightPointCallback
200 DygraphOps
.dispatchMouseMove(g
, 13, 10);
205 * Test the closest-series highlighting methods for normal and stacked modes.
206 * Also pass in line widths for plain and highlighted lines for easier visual
207 * confirmation that the highlighted line is drawn on top of the others.
209 var runClosestTest
= function(isStacked
, widthNormal
, widthHighlighted
) {
214 var graph
= document
.getElementById("graph");
215 var g
= new Dygraph(graph
, data
,
219 visibility
: [false, true, true],
220 stackedGraph
: isStacked
,
221 strokeWidth
: widthNormal
,
222 strokeBorderWidth
: 2,
223 highlightCircleSize
: widthNormal
* 2,
224 highlightSeriesBackgroundAlpha
: 0.3,
226 highlightSeriesOpts
: {
227 strokeWidth
: widthHighlighted
,
228 highlightCircleSize
: widthHighlighted
* 2
232 var highlightCallback
= function(e
, x
, pts
, row
, set
) {
233 assertEquals(g
, this);
237 document
.getElementById('selection').innerHTML
='row=' + row
+ ', set=' + set
;
240 g
.updateOptions({highlightCallback
: highlightCallback
}, true);
243 DygraphOps
.dispatchMouseMove(g
, 11.45, 1.4);
244 assertEquals(1, h_row
);
245 assertEquals('c', h_series
);
247 //now move up in the same row
248 DygraphOps
.dispatchMouseMove(g
, 11.45, 1.5);
249 assertEquals(1, h_row
);
250 assertEquals('b', h_series
);
252 //and a bit to the right
253 DygraphOps
.dispatchMouseMove(g
, 11.55, 1.5);
254 assertEquals(2, h_row
);
255 assertEquals('c', h_series
);
257 DygraphOps
.dispatchMouseMove(g
, 11, 1.5);
258 assertEquals(1, h_row
);
259 assertEquals('c', h_series
);
261 //now move up in the same row
262 DygraphOps
.dispatchMouseMove(g
, 11, 2.5);
263 assertEquals(1, h_row
);
264 assertEquals('b', h_series
);
271 * Test basic closest-point highlighting.
273 CallbackTestCase
.prototype.testClosestPointCallback
= function() {
274 runClosestTest(false, 1, 3);
278 * Test setSelection() with series name
280 CallbackTestCase
.prototype.testSetSelection
= function() {
281 var g
= runClosestTest(false, 1, 3);
282 assertEquals(1, g
.attr_('strokeWidth', 'c'));
283 g
.setSelection(false, 'c');
284 assertEquals(3, g
.attr_('strokeWidth', 'c'));
288 * Test closest-point highlighting for stacked graph
290 CallbackTestCase
.prototype.testClosestPointStackedCallback
= function() {
291 runClosestTest(true, 1, 3);
295 * Closest-point highlighting with legend CSS - border around active series.
297 CallbackTestCase
.prototype.testClosestPointCallbackCss1
= function() {
298 var css
= "div.dygraph-legend > span { display: block; }\n" +
299 "div.dygraph-legend > span.highlight { border: 1px solid grey; }\n";
300 styleSheet
.innerHTML
= css
;
301 runClosestTest(false, 2, 4);
302 styleSheet
.innerHTML
= '';
306 * Closest-point highlighting with legend CSS - show only closest series.
308 CallbackTestCase
.prototype.testClosestPointCallbackCss2
= function() {
309 var css
= "div.dygraph-legend > span { display: none; }\n" +
310 "div.dygraph-legend > span.highlight { display: inline; }\n";
311 styleSheet
.innerHTML
= css
;
312 runClosestTest(false, 10, 15);
313 styleSheet
.innerHTML
= '';
314 // TODO(klausw): verify that the highlighted line is drawn on top?
318 * Closest-point highlighting with locked series.
320 CallbackTestCase
.prototype.testSetSelectionLocking
= function() {
321 var g
= runClosestTest(false, 2, 4);
323 // Default behavior, 'b' is closest
324 DygraphOps
.dispatchMouseMove(g
, 11, 4);
325 assertEquals('b', g
.getHighlightSeries());
327 // Now lock selection to 'c'
328 g
.setSelection(false, 'c', true);
329 DygraphOps
.dispatchMouseMove(g
, 11, 4);
330 assertEquals('c', g
.getHighlightSeries());
332 // Unlock, should be back to 'b'
334 DygraphOps
.dispatchMouseMove(g
, 11, 4);
335 assertEquals('b', g
.getHighlightSeries());
339 * This tests that closest point searches work for data containing NaNs.
341 * It's intended to catch a regression where a NaN Y value confuses the
342 * closest-point algorithm, treating it as closer as any previous point.
344 CallbackTestCase
.prototype.testNaNData
= function() {
356 var highlightCallback
= function(e
, x
, pts
, row
) {
357 assertEquals(g
, this);
362 var graph
= document
.getElementById("graph");
363 var g
= new Dygraph(graph
, dataNaN
,
367 labels
: ['x', 'a', 'b', 'c'],
368 visibility
: [false, true, true],
369 highlightCallback
: highlightCallback
372 DygraphOps
.dispatchMouseMove(g
, 10.1, 0.9);
373 //check correct row is returned
374 assertEquals(1, h_row
);
376 // Explicitly test closest point algorithms
377 var dom
= g
.toDomCoords(10.1, 0.9);
378 assertEquals(1, g
.findClosestRow(dom
[0]));
380 var res
= g
.findClosestPoint(dom
[0], dom
[1]);
381 assertEquals(1, res
.row
);
382 assertEquals('b', res
.seriesName
);
384 res
= g
.findStackedPoint(dom
[0], dom
[1]);
385 assertEquals(1, res
.row
);
386 assertEquals('c', res
.seriesName
);
390 * This tests that stacked point searches work for data containing NaNs.
392 CallbackTestCase
.prototype.testNaNDataStack
= function() {
409 var highlightCallback
= function(e
, x
, pts
, row
) {
410 assertEquals(g
, this);
415 var graph
= document
.getElementById("graph");
416 var g
= new Dygraph(graph
, dataNaN
,
420 labels
: ['x', 'a', 'b', 'c'],
421 visibility
: [false, true, true],
423 highlightCallback
: highlightCallback
426 DygraphOps
.dispatchMouseMove(g
, 10.1, 0.9);
427 //check correct row is returned
428 assertEquals(1, h_row
);
430 // Explicitly test stacked point algorithm.
431 var dom
= g
.toDomCoords(10.1, 0.9);
432 var res
= g
.findStackedPoint(dom
[0], dom
[1]);
433 assertEquals(1, res
.row
);
434 assertEquals('c', res
.seriesName
);
436 // All-NaN area at left, should get no points.
437 dom
= g
.toDomCoords(9.1, 0.9);
438 res
= g
.findStackedPoint(dom
[0], dom
[1]);
439 assertEquals(0, res
.row
);
440 assertEquals(undefined
, res
.seriesName
);
442 // First gap, get 'c' since it's non-NaN.
443 dom
= g
.toDomCoords(12.1, 0.9);
444 res
= g
.findStackedPoint(dom
[0], dom
[1]);
445 assertEquals(3, res
.row
);
446 assertEquals('c', res
.seriesName
);
448 // Second gap, get 'b' since 'c' is NaN.
449 dom
= g
.toDomCoords(15.1, 0.9);
450 res
= g
.findStackedPoint(dom
[0], dom
[1]);
451 assertEquals(6, res
.row
);
452 assertEquals('b', res
.seriesName
);
454 // Isolated points should work, finding series b in this case.
455 dom
= g
.toDomCoords(15.9, 3.1);
456 res
= g
.findStackedPoint(dom
[0], dom
[1]);
457 assertEquals(7, res
.row
);
458 assertEquals('b', res
.seriesName
);
461 CallbackTestCase
.prototype.testGapHighlight
= function() {
475 var highlightCallback
= function(e
, x
, pts
, row
) {
476 assertEquals(g
, this);
481 var graph
= document
.getElementById("graph");
482 var g
= new Dygraph(graph
, dataGap
, {
485 //stackedGraph: true,
486 connectSeparatedPoints
: true,
488 labels
: ['x', 'A', 'B'],
489 highlightCallback
: highlightCallback
492 DygraphOps
.dispatchMouseMove(g
, 1.1, 10);
493 //point from series B
494 assertEquals(0, h_row
);
495 assertEquals(1, h_pts
.length
);
496 assertEquals(3, h_pts
[0].yval
);
497 assertEquals('B', h_pts
[0].name
);
499 DygraphOps
.dispatchMouseMove(g
, 6.1, 10);
501 assertEquals(1, h_pts
.length
);
502 assert(isNaN(h_pts
[0].yval
));
503 assertEquals('A', h_pts
[0].name
);
505 DygraphOps
.dispatchMouseMove(g
, 8.1, 10);
506 //point from series A
507 assertEquals(6, h_row
);
508 assertEquals(1, h_pts
.length
);
509 assertEquals(8, h_pts
[0].yval
);
510 assertEquals('A', h_pts
[0].name
);
513 CallbackTestCase
.prototype.testFailedResponse
= function() {
515 // Fake out the XMLHttpRequest so it doesn't do anything.
516 XMLHttpRequest
= function () {};
517 XMLHttpRequest
.prototype.open
= function () {};
518 XMLHttpRequest
.prototype.send
= function () {};
520 var highlightCallback
= function(e
, x
, pts
, row
) {
521 fail("should not reach here");
524 var graph
= document
.getElementById("graph");
525 graph
.style
.border
= "2px solid black";
526 var g
= new Dygraph(graph
, "data.csv", { // fake name
529 highlightCallback
: highlightCallback
532 DygraphOps
.dispatchMouseOver_Point(g
, 800, 800);
533 DygraphOps
.dispatchMouseMove_Point(g
, 100, 100);
534 DygraphOps
.dispatchMouseMove_Point(g
, 800, 800);
536 var oldOnerror
= window
.onerror
;
538 window
.onerror
= function() { failed
= true; return false; }
540 DygraphOps
.dispatchMouseOut_Point(g
, 800, 800); // This call should not throw an exception.
542 assertFalse("exception thrown during mouseout", failed
);
546 // Regression test for http://code.google.com/p/dygraphs/issues/detail
?id
=355
547 CallbackTestCase
.prototype.testHighlightCallbackRow
= function() {
549 var highlightCallback
= function(e
, x
, pts
, row
) {
550 assertEquals(g
, this);
554 var graph
= document
.getElementById("graph");
555 var g
= new Dygraph(graph
,
565 highlightCallback
: highlightCallback
568 // Mouse over each of the points
569 DygraphOps
.dispatchMouseOver_Point(g
, 0, 0);
570 DygraphOps
.dispatchMouseMove_Point(g
, 0, 0);
571 assertEquals(0, highlightRow
);
572 DygraphOps
.dispatchMouseMove_Point(g
, 100, 0);
573 assertEquals(1, highlightRow
);
574 DygraphOps
.dispatchMouseMove_Point(g
, 200, 0);
575 assertEquals(2, highlightRow
);
576 DygraphOps
.dispatchMouseMove_Point(g
, 300, 0);
577 assertEquals(3, highlightRow
);
578 DygraphOps
.dispatchMouseMove_Point(g
, 400, 0);
579 assertEquals(4, highlightRow
);
581 // Now zoom and verify that the row numbers still refer to rows in the data
583 g
.updateOptions({dateWindow
: [2, 4]});
584 DygraphOps
.dispatchMouseOver_Point(g
, 0, 0);
585 DygraphOps
.dispatchMouseMove_Point(g
, 0, 0);
586 assertEquals(2, highlightRow
);
587 assertEquals('2: Y: 3 Z: 4', Util
.getLegend());
591 * Test that underlay callback is called even when there are no series,
592 * and that the y axis ranges are not NaN.
594 CallbackTestCase
.prototype.testUnderlayCallback_noSeries
= function() {
598 var callback
= function(canvas
, area
, g
) {
599 assertEquals(g
, this);
601 yMin
= g
.yAxisRange(0)[0];
602 yMax
= g
.yAxisRange(0)[1];
605 var graph
= document
.getElementById("graph");
606 var g
= new Dygraph(graph
, "\n", {
607 underlayCallback
: callback
611 assertFalse(isNaN(yMin
));
612 assertFalse(isNaN(yMax
));
616 * Test that underlay callback receives the correct y-axis range.
618 CallbackTestCase
.prototype.testUnderlayCallback_yAxisRange
= function() {
622 var callback
= function(canvas
, area
, g
) {
623 assertEquals(g
, this);
624 yMin
= g
.yAxisRange(0)[0];
625 yMax
= g
.yAxisRange(0)[1];
628 var graph
= document
.getElementById("graph");
629 var g
= new Dygraph(graph
, "\n", {
631 underlayCallback
: callback
634 assertEquals(0, yMin
);
635 assertEquals(10, yMax
);
639 * Test that drawPointCallback is called for isolated points and correct idx for the point is returned.
641 CallbackTestCase
.prototype.testDrawPointCallback_idx
= function() {
645 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
646 assertEquals(g
, this);
648 Dygraph
.Circles
.DEFAULT
.apply(this, arguments
);
651 var graph
= document
.getElementById("graph");
653 var testdata
= [[10, 2], [11, 3], [12, NaN
], [13, 2], [14, NaN
], [15, 3]];
658 drawPointCallback
: callback
,
662 // Test that correct idx for isolated points are passed to the callback.
663 g
= new Dygraph(graph
, testdata
, graphOpts
);
664 assertEquals(2, indices
.length
);
665 assertEquals([3, 5],indices
);
667 // Test that correct indices for isolated points + gap points are passed to the callback when
668 // drawGapEdgePoints is set. This should add one point at the right
669 // edge of the segment at x=11, but not at the graph edge at x=10.
670 indices
= []; // Reset for new test
671 graphOpts
.drawGapEdgePoints
= true;
672 g
= new Dygraph(graph
, testdata
, graphOpts
);
673 assertEquals(3, indices
.length
);
674 assertEquals([1, 3, 5],indices
);
677 //Test that correct indices are passed to the callback when zoomed in.
678 indices
= []; // Reset for new test
679 graphOpts
.dateWindow
= [12.5,13.5]
680 graphOpts
.drawPoints
= true;
681 testdata
= [[10, 2], [11, 3], [12, 4], [13, 2], [14, 5], [15, 3]];
682 g
= new Dygraph(graph
, testdata
, graphOpts
);
683 assertEquals(3, indices
.length
);
684 assertEquals([2, 3, 4],indices
);
688 * Test that the correct idx is returned for the point in the onHiglightCallback.
690 CallbackTestCase
.prototype.testDrawHighlightPointCallback_idx
= function() {
691 var idxToCheck
= null;
693 var drawHighlightPointCallback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
694 assertEquals(g
, this);
697 var testdata
= [[1, 2], [2, 3], [3, NaN
], [4, 2], [5, NaN
], [6, 3]];
698 var graph
= document
.getElementById("graph");
699 var g
= new Dygraph(graph
, testdata
,
701 drawHighlightPointCallback
: drawHighlightPointCallback
704 assertNull(idxToCheck
);
705 DygraphOps
.dispatchMouseMove(g
, 3, 0);
706 // check that NaN point is not highlighted
707 assertNull(idxToCheck
);
708 DygraphOps
.dispatchMouseMove(g
, 1, 2);
709 // check that correct index is returned
710 assertEquals(0,idxToCheck
);
711 DygraphOps
.dispatchMouseMove(g
, 6, 3);
712 assertEquals(5,idxToCheck
);