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 // First gap, no data due to NaN contagion.
424 dom
= g
.toDomCoords(12.1, 0.9);
425 res
= g
.findStackedPoint(dom
[0], dom
[1]);
426 assertEquals(3, res
.row
);
427 assertEquals(undefined
, res
.seriesName
);
429 // Second gap, no data due to NaN contagion.
430 dom
= g
.toDomCoords(15.1, 0.9);
431 res
= g
.findStackedPoint(dom
[0], dom
[1]);
432 assertEquals(6, res
.row
);
433 assertEquals(undefined
, res
.seriesName
);
435 // Isolated points should work, finding series b in this case.
436 dom
= g
.toDomCoords(15.9, 3.1);
437 res
= g
.findStackedPoint(dom
[0], dom
[1]);
438 assertEquals(7, res
.row
);
439 assertEquals('b', res
.seriesName
);
442 CallbackTestCase
.prototype.testGapHighlight
= function() {
456 var highlightCallback
= function(e
, x
, pts
, row
) {
461 var graph
= document
.getElementById("graph");
462 var g
= new Dygraph(graph
, dataGap
, {
465 //stackedGraph: true,
466 connectSeparatedPoints
: true,
468 labels
: ['x', 'A', 'B'],
469 highlightCallback
: highlightCallback
472 DygraphOps
.dispatchMouseMove(g
, 1.1, 10);
473 //point from series B
474 assertEquals(0, h_row
);
475 assertEquals(1, h_pts
.length
);
476 assertEquals(3, h_pts
[0].yval
);
477 assertEquals('B', h_pts
[0].name
);
479 DygraphOps
.dispatchMouseMove(g
, 6.1, 10);
481 assertEquals(1, h_pts
.length
);
482 assert(isNaN(h_pts
[0].yval
));
483 assertEquals('A', h_pts
[0].name
);
485 DygraphOps
.dispatchMouseMove(g
, 8.1, 10);
486 //point from series A
487 assertEquals(6, h_row
);
488 assertEquals(1, h_pts
.length
);
489 assertEquals(8, h_pts
[0].yval
);
490 assertEquals('A', h_pts
[0].name
);
493 CallbackTestCase
.prototype.testFailedResponse
= function() {
495 // Fake out the XMLHttpRequest so it doesn't do anything.
496 XMLHttpRequest
= function () {};
497 XMLHttpRequest
.prototype.open
= function () {};
498 XMLHttpRequest
.prototype.send
= function () {};
500 var highlightCallback
= function(e
, x
, pts
, row
) {
501 fail("should not reach here");
504 var graph
= document
.getElementById("graph");
505 graph
.style
.border
= "2px solid black";
506 var g
= new Dygraph(graph
, "data.csv", { // fake name
509 highlightCallback
: highlightCallback
512 DygraphOps
.dispatchMouseOver_Point(g
, 800, 800);
513 DygraphOps
.dispatchMouseMove_Point(g
, 100, 100);
514 DygraphOps
.dispatchMouseMove_Point(g
, 800, 800);
516 var oldOnerror
= window
.onerror
;
518 window
.onerror
= function() { failed
= true; return false; }
520 DygraphOps
.dispatchMouseOut_Point(g
, 800, 800); // This call should not throw an exception.
522 assertFalse("exception thrown during mouseout", failed
);