2 * @fileoverview Test cases for the callbacks.
4 * @author uemit.seren@gmail.com (Ümit Seren)
7 describe("callback", function() {
11 beforeEach(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 afterEach(function() {
20 window
.XMLHttpRequest
= xhr
;
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 it('testHighlightCallbackIsCalled', function() {
39 var highlightCallback
= function(e
, x
, pts
, row
) {
40 assert
.equal(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 assert
.equal(3, h_row
);
58 //check there are only two points (because first series is hidden)
59 assert
.equal(2, h_pts
.length
);
64 * Test that drawPointCallback isn't called when drawPoints is false
66 it('testDrawPointCallback_disabled', function() {
69 var callback
= function() {
70 assert
.equal(g
, this);
74 var graph
= document
.getElementById("graph");
75 var g
= new Dygraph(graph
, data
, {
76 drawPointCallback
: callback
,
79 assert
.isFalse(called
);
83 * Test that drawPointCallback is called when drawPoints is true
85 it('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
100 assert
.isTrue(called
);
101 assert
.equal(g
, callbackThis
);
105 * Test that drawPointCallback is called when drawPoints is true
107 it('testDrawPointCallback_pointSize', function() {
111 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
112 assert
.equal(g
, this);
113 pointSize
= pointSizeParam
;
117 var graph
= document
.getElementById("graph");
118 var g
= new Dygraph(graph
, data
, {
120 drawPointCallback
: callback
123 assert
.equal(1.5, pointSize
);
124 assert
.equal(12, count
); // one call per data point.
126 var g
= new Dygraph(graph
, data
, {
128 drawPointCallback
: callback
,
132 assert
.equal(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 it('testDrawPointCallback_isolated', function() {
143 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
144 assert
.equal(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 assert
.equal(2, xvalues
.length
);
163 assert
.equal(13, xvalues
[0]);
164 assert
.equal(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 assert
.equal(3, xvalues
.length
);
173 assert
.equal(11, xvalues
[0]);
174 assert
.equal(13, xvalues
[1]);
175 assert
.equal(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 it('testDrawHighlightPointCallbackIsCalled', function() {
186 var drawHighlightPointCallback
= function() {
187 assert
.equal(g
, this);
191 var graph
= document
.getElementById("graph");
192 var g
= new Dygraph(graph
, data
,
196 drawHighlightPointCallback
: drawHighlightPointCallback
199 assert
.isFalse(called
);
200 DygraphOps
.dispatchMouseMove(g
, 13, 10);
201 assert
.isTrue(called
);
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 assert
.equal(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 assert
.equal(1, h_row
);
245 assert
.equal('c', h_series
);
247 //now move up in the same row
248 DygraphOps
.dispatchMouseMove(g
, 11.45, 1.5);
249 assert
.equal(1, h_row
);
250 assert
.equal('b', h_series
);
252 //and a bit to the right
253 DygraphOps
.dispatchMouseMove(g
, 11.55, 1.5);
254 assert
.equal(2, h_row
);
255 assert
.equal('c', h_series
);
257 DygraphOps
.dispatchMouseMove(g
, 11, 1.5);
258 assert
.equal(1, h_row
);
259 assert
.equal('c', h_series
);
261 //now move up in the same row
262 DygraphOps
.dispatchMouseMove(g
, 11, 2.5);
263 assert
.equal(1, h_row
);
264 assert
.equal('b', h_series
);
271 * Test basic closest-point highlighting.
273 it('testClosestPointCallback', function() {
274 runClosestTest(false, 1, 3);
278 * Test setSelection() with series name
280 it('testSetSelection', function() {
281 var g
= runClosestTest(false, 1, 3);
282 assert
.equal(1, g
.attr_('strokeWidth', 'c'));
283 g
.setSelection(false, 'c');
284 assert
.equal(3, g
.attr_('strokeWidth', 'c'));
288 * Test closest-point highlighting for stacked graph
290 it('testClosestPointStackedCallback', function() {
291 runClosestTest(true, 1, 3);
295 * Closest-point highlighting with legend CSS - border around active series.
297 it('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 it('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 it('testSetSelectionLocking', function() {
321 var g
= runClosestTest(false, 2, 4);
323 // Default behavior, 'b' is closest
324 DygraphOps
.dispatchMouseMove(g
, 11, 4);
325 assert
.equal('b', g
.getHighlightSeries());
327 // Now lock selection to 'c'
328 g
.setSelection(false, 'c', true);
329 DygraphOps
.dispatchMouseMove(g
, 11, 4);
330 assert
.equal('c', g
.getHighlightSeries());
332 // Unlock, should be back to 'b'
334 DygraphOps
.dispatchMouseMove(g
, 11, 4);
335 assert
.equal('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 it('testNaNData', function() {
356 var highlightCallback
= function(e
, x
, pts
, row
) {
357 assert
.equal(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 assert
.equal(1, h_row
);
376 // Explicitly test closest point algorithms
377 var dom
= g
.toDomCoords(10.1, 0.9);
378 assert
.equal(1, g
.findClosestRow(dom
[0]));
380 var res
= g
.findClosestPoint(dom
[0], dom
[1]);
381 assert
.equal(1, res
.row
);
382 assert
.equal('b', res
.seriesName
);
384 res
= g
.findStackedPoint(dom
[0], dom
[1]);
385 assert
.equal(1, res
.row
);
386 assert
.equal('c', res
.seriesName
);
390 * This tests that stacked point searches work for data containing NaNs.
392 it('testNaNDataStack', function() {
409 var highlightCallback
= function(e
, x
, pts
, row
) {
410 assert
.equal(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 assert
.equal(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 assert
.equal(1, res
.row
);
434 assert
.equal('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 assert
.equal(0, res
.row
);
440 assert
.equal(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 assert
.equal(3, res
.row
);
446 assert
.equal('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 assert
.equal(6, res
.row
);
452 assert
.equal('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 assert
.equal(7, res
.row
);
458 assert
.equal('b', res
.seriesName
);
461 it('testGapHighlight', function() {
475 var highlightCallback
= function(e
, x
, pts
, row
) {
476 assert
.equal(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 assert
.equal(0, h_row
);
495 assert
.equal(1, h_pts
.length
);
496 assert
.equal(3, h_pts
[0].yval
);
497 assert
.equal('B', h_pts
[0].name
);
499 DygraphOps
.dispatchMouseMove(g
, 6.1, 10);
501 assert
.equal(1, h_pts
.length
);
502 assert(isNaN(h_pts
[0].yval
));
503 assert
.equal('A', h_pts
[0].name
);
505 DygraphOps
.dispatchMouseMove(g
, 8.1, 10);
506 //point from series A
507 assert
.equal(6, h_row
);
508 assert
.equal(1, h_pts
.length
);
509 assert
.equal(8, h_pts
[0].yval
);
510 assert
.equal('A', h_pts
[0].name
);
513 it('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 throw "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 assert
.isFalse(failed
, "exception thrown during mouseout");
546 // Regression test for http://code.google.com/p/dygraphs/issues/detail
?id
=355
547 it('testHighlightCallbackRow', function() {
549 var highlightCallback
= function(e
, x
, pts
, row
) {
550 assert
.equal(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 assert
.equal(0, highlightRow
);
572 DygraphOps
.dispatchMouseMove_Point(g
, 100, 0);
573 assert
.equal(1, highlightRow
);
574 DygraphOps
.dispatchMouseMove_Point(g
, 200, 0);
575 assert
.equal(2, highlightRow
);
576 DygraphOps
.dispatchMouseMove_Point(g
, 300, 0);
577 assert
.equal(3, highlightRow
);
578 DygraphOps
.dispatchMouseMove_Point(g
, 400, 0);
579 assert
.equal(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 assert
.equal(2, highlightRow
);
587 assert
.equal('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 it('testUnderlayCallback_noSeries', function() {
598 var callback
= function(canvas
, area
, g
) {
599 assert
.equal(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
610 assert
.isTrue(called
);
611 assert
.isFalse(isNaN(yMin
));
612 assert
.isFalse(isNaN(yMax
));
616 * Test that underlay callback receives the correct y-axis range.
618 it('testUnderlayCallback_yAxisRange', function() {
622 var callback
= function(canvas
, area
, g
) {
623 assert
.equal(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 assert
.equal(0, yMin
);
635 assert
.equal(10, yMax
);
639 * Test that drawPointCallback is called for isolated points and correct idx for the point is returned.
641 it('testDrawPointCallback_idx', function() {
645 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
646 assert
.equal(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 assert
.equal(2, indices
.length
);
665 assert
.deepEqual([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 assert
.equal(3, indices
.length
);
674 assert
.deepEqual([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 assert
.equal(3, indices
.length
);
684 assert
.deepEqual([2, 3, 4],indices
);
688 * Test that the correct idx is returned for the point in the onHiglightCallback.
690 it('testDrawHighlightPointCallback_idx', function() {
691 var idxToCheck
= null;
693 var drawHighlightPointCallback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
694 assert
.equal(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
, {
700 drawHighlightPointCallback
: drawHighlightPointCallback
,
704 assert
.isNull(idxToCheck
);
705 DygraphOps
.dispatchMouseMove(g
, 3, 0);
706 // check that NaN point is not highlighted
707 assert
.isNull(idxToCheck
);
708 DygraphOps
.dispatchMouseMove(g
, 1, 2);
709 // check that correct index is returned
710 assert
.equal(0,idxToCheck
);
711 DygraphOps
.dispatchMouseMove(g
, 6, 3);
712 assert
.equal(5,idxToCheck
);