4d0b1723cfb9b2dbcd44eacdd9872c1649ec40d8
[dygraphs.git] / auto_tests / tests / callback.js
1 /**
2 * @fileoverview Test cases for the callbacks.
3 *
4 * @author uemit.seren@gmail.com (Ümit Seren)
5 */
6
7 var CallbackTestCase = TestCase("callback");
8
9 CallbackTestCase.prototype.setUp = function() {
10 document.body.innerHTML = "<div id='graph'></div><div id='selection'></div>";
11 this.styleSheet = document.createElement("style");
12 this.styleSheet.type = "text/css";
13 document.getElementsByTagName("head")[0].appendChild(this.styleSheet);
14 };
15
16 CallbackTestCase.prototype.tearDown = function() {
17 };
18
19 var data = "X,a\,b,c\n" +
20 "10,-1,1,2\n" +
21 "11,0,3,1\n" +
22 "12,1,4,2\n" +
23 "13,0,2,3\n";
24
25
26 /**
27 * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback
28 * is properly called when the first series is hidden (setVisibility = false)
29 *
30 */
31 CallbackTestCase.prototype.testHighlightCallbackIsCalled = function() {
32 var h_row;
33 var h_pts;
34
35 var highlightCallback = function(e, x, pts, row) {
36 h_row = row;
37 h_pts = pts;
38 };
39
40 var graph = document.getElementById("graph");
41 var g = new Dygraph(graph, data,
42 {
43 width: 100,
44 height: 100,
45 visibility: [false, true, true],
46 highlightCallback: highlightCallback
47 });
48
49 DygraphOps.dispatchMouseMove(g, 13, 10);
50
51 //check correct row is returned
52 assertEquals(3, h_row);
53 //check there are only two points (because first series is hidden)
54 assertEquals(2, h_pts.length);
55 };
56
57
58 /**
59 * Test that drawPointCallback isn't called when drawPoints is false
60 */
61 CallbackTestCase.prototype.testDrawPointCallback_disabled = function() {
62 var called = false;
63
64 var callback = function() {
65 called = true;
66 };
67
68 var graph = document.getElementById("graph");
69 var g = new Dygraph(graph, data, {
70 drawPointCallback : callback,
71 });
72
73 assertFalse(called);
74 };
75
76 /**
77 * Test that drawPointCallback is called when drawPoints is true
78 */
79 CallbackTestCase.prototype.testDrawPointCallback_enabled = function() {
80 var called = false;
81
82 var callback = function() {
83 called = true;
84 };
85
86 var graph = document.getElementById("graph");
87 var g = new Dygraph(graph, data, {
88 drawPoints : true,
89 drawPointCallback : callback
90 });
91
92 assertTrue(called);
93 };
94
95 /**
96 * Test that drawPointCallback is called when drawPoints is true
97 */
98 CallbackTestCase.prototype.testDrawPointCallback_pointSize = function() {
99 var pointSize = 0;
100 var count = 0;
101
102 var callback = function(g, seriesName, canvasContext, cx, cy, color, pointSizeParam) {
103 pointSize = pointSizeParam;
104 count++;
105 };
106
107 var graph = document.getElementById("graph");
108 var g = new Dygraph(graph, data, {
109 drawPoints : true,
110 drawPointCallback : callback
111 });
112
113 assertEquals(1.5, pointSize);
114 assertEquals(12, count); // one call per data point.
115
116 var g = new Dygraph(graph, data, {
117 drawPoints : true,
118 drawPointCallback : callback,
119 pointSize : 8
120 });
121
122 assertEquals(8, pointSize);
123 };
124
125 /**
126 * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback
127 * is properly called when the first series is hidden (setVisibility = false)
128 *
129 */
130 CallbackTestCase.prototype.testDrawHighlightPointCallbackIsCalled = function() {
131 var called = false;
132
133 var drawHighlightPointCallback = function() {
134 called = true;
135 };
136
137 var graph = document.getElementById("graph");
138 var g = new Dygraph(graph, data,
139 {
140 width: 100,
141 height : 100,
142 drawHighlightPointCallback : drawHighlightPointCallback
143 });
144
145 assertFalse(called);
146 DygraphOps.dispatchMouseMove(g, 13, 10);
147 assertTrue(called);
148 };
149
150 /**
151 * Test the closest-series highlighting methods for normal and stacked modes.
152 * Also pass in line widths for plain and highlighted lines for easier visual
153 * confirmation that the highlighted line is drawn on top of the others.
154 */
155 var runClosestTest = function(isStacked, widthNormal, widthHighlighted) {
156 var h_row;
157 var h_pts;
158 var h_series;
159
160 var graph = document.getElementById("graph");
161 var g = new Dygraph(graph, data,
162 {
163 width: 600,
164 height: 400,
165 visibility: [false, true, true],
166 stackedGraph: isStacked,
167 strokeWidth: widthNormal,
168 strokeBorderWidth: 2,
169 highlightCircleSize: widthNormal * 2,
170 highlightSeriesBackgroundAlpha: 0.3,
171
172 highlightSeriesOpts: {
173 strokeWidth: widthHighlighted,
174 highlightCircleSize: widthHighlighted * 2
175 }
176 });
177
178 var highlightCallback = function(e, x, pts, row, set) {
179 h_row = row;
180 h_pts = pts;
181 h_series = set;
182 document.getElementById('selection').innerHTML='row=' + row + ', set=' + set;
183 };
184
185 g.updateOptions({highlightCallback: highlightCallback}, true);
186
187 if (isStacked) {
188 DygraphOps.dispatchMouseMove(g, 11.45, 1.4);
189 assertEquals(1, h_row);
190 assertEquals('c', h_series);
191
192 //now move up in the same row
193 DygraphOps.dispatchMouseMove(g, 11.45, 1.5);
194 assertEquals(1, h_row);
195 assertEquals('b', h_series);
196
197 //and a bit to the right
198 DygraphOps.dispatchMouseMove(g, 11.55, 1.5);
199 assertEquals(2, h_row);
200 assertEquals('c', h_series);
201 } else {
202 DygraphOps.dispatchMouseMove(g, 11, 1.5);
203 assertEquals(1, h_row);
204 assertEquals('c', h_series);
205
206 //now move up in the same row
207 DygraphOps.dispatchMouseMove(g, 11, 2.5);
208 assertEquals(1, h_row);
209 assertEquals('b', h_series);
210 }
211
212 return g;
213 };
214
215 /**
216 * Test basic closest-point highlighting.
217 */
218 CallbackTestCase.prototype.testClosestPointCallback = function() {
219 runClosestTest(false, 1, 3);
220 }
221
222 /**
223 * Test setSelection() with series name
224 */
225 CallbackTestCase.prototype.testSetSelection = function() {
226 var g = runClosestTest(false, 1, 3);
227 assertEquals(1, g.attr_('strokeWidth', 'c'));
228 g.setSelection(false, 'c');
229 assertEquals(3, g.attr_('strokeWidth', 'c'));
230 }
231
232 /**
233 * Test closest-point highlighting for stacked graph
234 */
235 CallbackTestCase.prototype.testClosestPointStackedCallback = function() {
236 runClosestTest(true, 1, 3);
237 }
238
239 /**
240 * Closest-point highlighting with legend CSS - border around active series.
241 */
242 CallbackTestCase.prototype.testClosestPointCallbackCss1 = function() {
243 var css = "div.dygraph-legend > span { display: block; }\n" +
244 "div.dygraph-legend > span.highlight { border: 1px solid grey; }\n";
245 this.styleSheet.innerHTML = css;
246 runClosestTest(false, 2, 4);
247 this.styleSheet.innerHTML = '';
248 }
249
250 /**
251 * Closest-point highlighting with legend CSS - show only closest series.
252 */
253 CallbackTestCase.prototype.testClosestPointCallbackCss2 = function() {
254 var css = "div.dygraph-legend > span { display: none; }\n" +
255 "div.dygraph-legend > span.highlight { display: inline; }\n";
256 this.styleSheet.innerHTML = css;
257 runClosestTest(false, 10, 15);
258 this.styleSheet.innerHTML = '';
259 // TODO(klausw): verify that the highlighted line is drawn on top?
260 }
261
262 /**
263 * This tests that closest point searches work for data containing NaNs.
264 *
265 * It's intended to catch a regression where a NaN Y value confuses the
266 * closest-point algorithm, treating it as closer as any previous point.
267 */
268 CallbackTestCase.prototype.testNaNData = function() {
269 var dataNaN = [
270 [9, -1, NaN, NaN],
271 [10, -1, 1, 2],
272 [11, 0, 3, 1],
273 [12, 1, 4, NaN],
274 [13, 0, 2, 3],
275 [14, -1, 1, 4]];
276
277 var h_row;
278 var h_pts;
279
280 var highlightCallback = function(e, x, pts, row) {
281 h_row = row;
282 h_pts = pts;
283 };
284
285 var graph = document.getElementById("graph");
286 var g = new Dygraph(graph, dataNaN,
287 {
288 width: 600,
289 height: 400,
290 labels: ['x', 'a', 'b', 'c'],
291 visibility: [false, true, true],
292 highlightCallback: highlightCallback
293 });
294
295 DygraphOps.dispatchMouseMove(g, 10.1, 0.9);
296 //check correct row is returned
297 assertEquals(1, h_row);
298
299 // Explicitly test closest point algorithms
300 var dom = g.toDomCoords(10.1, 0.9);
301 assertEquals(1, g.findClosestRow(dom[0]));
302
303 var res = g.findClosestPoint(dom[0], dom[1]);
304 assertEquals(1, res.row);
305 assertEquals('b', res.seriesName);
306
307 res = g.findStackedPoint(dom[0], dom[1]);
308 assertEquals(1, res.row);
309 assertEquals('c', res.seriesName);
310 };
311
312 /**
313 * This tests that stacked point searches work for data containing NaNs.
314 */
315 CallbackTestCase.prototype.testNaNDataStack = function() {
316 var dataNaN = [
317 [9, -1, NaN, NaN],
318 [10, -1, 1, 2],
319 [11, 0, 3, 1],
320 [12, 1, NaN, 2],
321 [13, 0, 2, 3],
322 [14, -1, 1, 4],
323 [15, 0, 2, NaN],
324 [16, 1, 1, 3],
325 [17, 1, NaN, 3],
326 [18, 0, 2, 5],
327 [19, 0, 1, 4]];
328
329 var h_row;
330 var h_pts;
331
332 var highlightCallback = function(e, x, pts, row) {
333 h_row = row;
334 h_pts = pts;
335 };
336
337 var graph = document.getElementById("graph");
338 var g = new Dygraph(graph, dataNaN,
339 {
340 width: 600,
341 height: 400,
342 labels: ['x', 'a', 'b', 'c'],
343 visibility: [false, true, true],
344 stackedGraph: true,
345 highlightCallback: highlightCallback
346 });
347
348 DygraphOps.dispatchMouseMove(g, 10.1, 0.9);
349 //check correct row is returned
350 assertEquals(1, h_row);
351
352 // Explicitly test stacked point algorithm.
353 var dom = g.toDomCoords(10.1, 0.9);
354 var res = g.findStackedPoint(dom[0], dom[1]);
355 assertEquals(1, res.row);
356 assertEquals('c', res.seriesName);
357
358 // First gap, no data due to NaN contagion.
359 dom = g.toDomCoords(12.1, 0.9);
360 res = g.findStackedPoint(dom[0], dom[1]);
361 assertEquals(3, res.row);
362 assertEquals(undefined, res.seriesName);
363
364 // Second gap, no data due to NaN contagion.
365 dom = g.toDomCoords(15.1, 0.9);
366 res = g.findStackedPoint(dom[0], dom[1]);
367 assertEquals(6, res.row);
368 assertEquals(undefined, res.seriesName);
369
370 // Isolated points should work, finding series b in this case.
371 dom = g.toDomCoords(15.9, 3.1);
372 res = g.findStackedPoint(dom[0], dom[1]);
373 assertEquals(7, res.row);
374 assertEquals('b', res.seriesName);
375 };
376
377 CallbackTestCase.prototype.testGapHighlight = function() {
378 var dataGap = [
379 [1, null, 3],
380 [2, 2, null],
381 [3, null, 5],
382 [4, 4, null],
383 [5, null, 7],
384 [6, NaN, null],
385 [8, 8, null],
386 [10, 10, null]];
387
388 var h_row;
389 var h_pts;
390
391 var highlightCallback = function(e, x, pts, row) {
392 h_row = row;
393 h_pts = pts;
394 };
395
396 var graph = document.getElementById("graph");
397 var g = new Dygraph(graph, dataGap, {
398 width: 400,
399 height: 300,
400 //stackedGraph: true,
401 connectSeparatedPoints: true,
402 drawPoints: true,
403 labels: ['x', 'A', 'B'],
404 highlightCallback : highlightCallback
405 });
406
407 DygraphOps.dispatchMouseMove(g, 1.1, 10);
408 //point from series B
409 assertEquals(0, h_row);
410 assertEquals(1, h_pts.length);
411 assertEquals(3, h_pts[0].yval);
412 assertEquals('B', h_pts[0].name);
413
414 DygraphOps.dispatchMouseMove(g, 6.1, 10);
415 // A is NaN at x=6
416 assertEquals(1, h_pts.length);
417 assert(isNaN(h_pts[0].yval));
418 assertEquals('A', h_pts[0].name);
419
420 DygraphOps.dispatchMouseMove(g, 8.1, 10);
421 //point from series A
422 assertEquals(6, h_row);
423 assertEquals(1, h_pts.length);
424 assertEquals(8, h_pts[0].yval);
425 assertEquals('A', h_pts[0].name);
426 };