Commit | Line | Data |
---|---|---|
5469113b | 1 | /** |
1c6b239c | 2 | * @fileoverview Test cases for the callbacks. |
3 | * | |
4 | * @author uemit.seren@gmail.com (Ümit Seren) | |
5 | */ | |
6 | ||
e8c70e4e DV |
7 | import Dygraph from '../../src/dygraph'; |
8 | import * as utils from '../../src/dygraph-utils'; | |
9 | import Util from './Util'; | |
10 | import DygraphOps from './DygraphOps'; | |
11 | ||
89fdcedb | 12 | describe("callback", function() { |
1c6b239c | 13 | |
e8c70e4e DV |
14 | cleanupAfterEach(); |
15 | ||
319d0361 | 16 | var xhr, styleSheet; |
e8c70e4e | 17 | var graph; |
319d0361 | 18 | |
89fdcedb | 19 | beforeEach(function() { |
e8c70e4e DV |
20 | var container = document.getElementById('graph'); |
21 | container.innerHTML = "<div id='inner-graph'></div><div id='selection'></div>"; | |
22 | graph = container.querySelector('#inner-graph'); | |
319d0361 DV |
23 | xhr = XMLHttpRequest; |
24 | styleSheet = document.createElement("style"); | |
25 | styleSheet.type = "text/css"; | |
26 | document.getElementsByTagName("head")[0].appendChild(styleSheet); | |
89fdcedb | 27 | }); |
1c6b239c | 28 | |
89fdcedb DV |
29 | afterEach(function() { |
30 | window.XMLHttpRequest = xhr; | |
31 | }); | |
475f7420 | 32 | |
89fdcedb | 33 | var data = "X,a,b,c\n" + |
1c6b239c | 34 | "10,-1,1,2\n" + |
35 | "11,0,3,1\n" + | |
36 | "12,1,4,2\n" + | |
37 | "13,0,2,3\n"; | |
857a6931 | 38 | |
475f7420 KW |
39 | |
40 | /** | |
41 | * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback | |
42 | * is properly called when the first series is hidden (setVisibility = false) | |
43 | * | |
44 | */ | |
89fdcedb | 45 | it('testHighlightCallbackIsCalled', function() { |
475f7420 KW |
46 | var h_row; |
47 | var h_pts; | |
48 | ||
4ee251cb | 49 | var highlightCallback = function(e, x, pts, row) { |
89fdcedb | 50 | assert.equal(g, this); |
475f7420 KW |
51 | h_row = row; |
52 | h_pts = pts; | |
53 | }; | |
54 | ||
475f7420 KW |
55 | var g = new Dygraph(graph, data, |
56 | { | |
57 | width: 100, | |
58 | height: 100, | |
59 | visibility: [false, true, true], | |
60 | highlightCallback: highlightCallback | |
61 | }); | |
62 | ||
63 | DygraphOps.dispatchMouseMove(g, 13, 10); | |
64 | ||
65 | //check correct row is returned | |
89fdcedb | 66 | assert.equal(3, h_row); |
475f7420 | 67 | //check there are only two points (because first series is hidden) |
89fdcedb DV |
68 | assert.equal(2, h_pts.length); |
69 | }); | |
475f7420 | 70 | |
a8332379 RK |
71 | |
72 | /** | |
73 | * Test that drawPointCallback isn't called when drawPoints is false | |
74 | */ | |
89fdcedb | 75 | it('testDrawPointCallback_disabled', function() { |
a8332379 RK |
76 | var called = false; |
77 | ||
72c12eda | 78 | var callback = function() { |
89fdcedb | 79 | assert.equal(g, this); |
a8332379 | 80 | called = true; |
5469113b | 81 | }; |
a8332379 | 82 | |
a8332379 | 83 | var g = new Dygraph(graph, data, { |
4ee251cb | 84 | drawPointCallback: callback, |
a8332379 RK |
85 | }); |
86 | ||
89fdcedb DV |
87 | assert.isFalse(called); |
88 | }); | |
a8332379 RK |
89 | |
90 | /** | |
91 | * Test that drawPointCallback is called when drawPoints is true | |
92 | */ | |
89fdcedb | 93 | it('testDrawPointCallback_enabled', function() { |
a8332379 | 94 | var called = false; |
4ee251cb | 95 | var callbackThis = null; |
a8332379 | 96 | |
72c12eda | 97 | var callback = function() { |
4ee251cb | 98 | callbackThis = this; |
a8332379 | 99 | called = true; |
5469113b | 100 | }; |
a8332379 | 101 | |
a8332379 | 102 | var g = new Dygraph(graph, data, { |
4ee251cb DV |
103 | drawPoints: true, |
104 | drawPointCallback: callback | |
a8332379 RK |
105 | }); |
106 | ||
89fdcedb DV |
107 | assert.isTrue(called); |
108 | assert.equal(g, callbackThis); | |
109 | }); | |
72c12eda RK |
110 | |
111 | /** | |
112 | * Test that drawPointCallback is called when drawPoints is true | |
113 | */ | |
89fdcedb | 114 | it('testDrawPointCallback_pointSize', function() { |
72c12eda RK |
115 | var pointSize = 0; |
116 | var count = 0; | |
117 | ||
118 | var callback = function(g, seriesName, canvasContext, cx, cy, color, pointSizeParam) { | |
89fdcedb | 119 | assert.equal(g, this); |
72c12eda RK |
120 | pointSize = pointSizeParam; |
121 | count++; | |
5469113b | 122 | }; |
72c12eda | 123 | |
72c12eda | 124 | var g = new Dygraph(graph, data, { |
4ee251cb DV |
125 | drawPoints: true, |
126 | drawPointCallback: callback | |
72c12eda RK |
127 | }); |
128 | ||
89fdcedb DV |
129 | assert.equal(1.5, pointSize); |
130 | assert.equal(12, count); // one call per data point. | |
72c12eda RK |
131 | |
132 | var g = new Dygraph(graph, data, { | |
4ee251cb DV |
133 | drawPoints: true, |
134 | drawPointCallback: callback, | |
135 | pointSize: 8 | |
72c12eda RK |
136 | }); |
137 | ||
89fdcedb DV |
138 | assert.equal(8, pointSize); |
139 | }); | |
72c12eda RK |
140 | |
141 | /** | |
41273327 KW |
142 | * Test that drawPointCallback is called for isolated points when |
143 | * drawPoints is false, and also for gap points if that's enabled. | |
144 | */ | |
89fdcedb | 145 | it('testDrawPointCallback_isolated', function() { |
41273327 KW |
146 | var xvalues = []; |
147 | ||
148 | var g; | |
149 | var callback = function(g, seriesName, canvasContext, cx, cy, color, pointSizeParam) { | |
89fdcedb | 150 | assert.equal(g, this); |
41273327 KW |
151 | var dx = g.toDataXCoord(cx); |
152 | xvalues.push(dx); | |
e8c70e4e | 153 | utils.Circles.DEFAULT.apply(this, arguments); |
41273327 KW |
154 | }; |
155 | ||
41273327 KW |
156 | var testdata = [[10, 2], [11, 3], [12, NaN], [13, 2], [14, NaN], [15, 3]]; |
157 | var graphOpts = { | |
158 | labels: ['X', 'Y'], | |
159 | valueRange: [0, 4], | |
160 | drawPoints : false, | |
161 | drawPointCallback : callback, | |
162 | pointSize : 8 | |
163 | }; | |
164 | ||
165 | // Test that isolated points get drawn | |
166 | g = new Dygraph(graph, testdata, graphOpts); | |
89fdcedb DV |
167 | assert.equal(2, xvalues.length); |
168 | assert.equal(13, xvalues[0]); | |
169 | assert.equal(15, xvalues[1]); | |
41273327 | 170 | |
a5a50727 KW |
171 | // Test that isolated points + gap points get drawn when |
172 | // drawGapEdgePoints is set. This should add one point at the right | |
173 | // edge of the segment at x=11, but not at the graph edge at x=10. | |
41273327 | 174 | xvalues = []; // Reset for new test |
a5a50727 | 175 | graphOpts.drawGapEdgePoints = true; |
41273327 | 176 | g = new Dygraph(graph, testdata, graphOpts); |
89fdcedb DV |
177 | assert.equal(3, xvalues.length); |
178 | assert.equal(11, xvalues[0]); | |
179 | assert.equal(13, xvalues[1]); | |
180 | assert.equal(15, xvalues[2]); | |
181 | }); | |
41273327 KW |
182 | |
183 | /** | |
72c12eda | 184 | * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback |
5469113b KW |
185 | * is properly called when the first series is hidden (setVisibility = false) |
186 | * | |
72c12eda | 187 | */ |
89fdcedb | 188 | it('testDrawHighlightPointCallbackIsCalled', function() { |
72c12eda RK |
189 | var called = false; |
190 | ||
4ee251cb | 191 | var drawHighlightPointCallback = function() { |
89fdcedb | 192 | assert.equal(g, this); |
72c12eda | 193 | called = true; |
5469113b | 194 | }; |
72c12eda | 195 | |
72c12eda RK |
196 | var g = new Dygraph(graph, data, |
197 | { | |
198 | width: 100, | |
4ee251cb DV |
199 | height: 100, |
200 | drawHighlightPointCallback: drawHighlightPointCallback | |
72c12eda RK |
201 | }); |
202 | ||
89fdcedb | 203 | assert.isFalse(called); |
72c12eda | 204 | DygraphOps.dispatchMouseMove(g, 13, 10); |
89fdcedb DV |
205 | assert.isTrue(called); |
206 | }); | |
5469113b | 207 | |
475f7420 KW |
208 | /** |
209 | * Test the closest-series highlighting methods for normal and stacked modes. | |
210 | * Also pass in line widths for plain and highlighted lines for easier visual | |
211 | * confirmation that the highlighted line is drawn on top of the others. | |
212 | */ | |
857a6931 KW |
213 | var runClosestTest = function(isStacked, widthNormal, widthHighlighted) { |
214 | var h_row; | |
215 | var h_pts; | |
216 | var h_series; | |
217 | ||
857a6931 KW |
218 | var g = new Dygraph(graph, data, |
219 | { | |
220 | width: 600, | |
475f7420 | 221 | height: 400, |
857a6931 KW |
222 | visibility: [false, true, true], |
223 | stackedGraph: isStacked, | |
224 | strokeWidth: widthNormal, | |
225 | strokeBorderWidth: 2, | |
226 | highlightCircleSize: widthNormal * 2, | |
afdb20d8 | 227 | highlightSeriesBackgroundAlpha: 0.3, |
857a6931 KW |
228 | |
229 | highlightSeriesOpts: { | |
230 | strokeWidth: widthHighlighted, | |
231 | highlightCircleSize: widthHighlighted * 2 | |
232 | } | |
233 | }); | |
234 | ||
4ee251cb | 235 | var highlightCallback = function(e, x, pts, row, set) { |
89fdcedb | 236 | assert.equal(g, this); |
857a6931 KW |
237 | h_row = row; |
238 | h_pts = pts; | |
239 | h_series = set; | |
240 | document.getElementById('selection').innerHTML='row=' + row + ', set=' + set; | |
241 | }; | |
242 | ||
243 | g.updateOptions({highlightCallback: highlightCallback}, true); | |
244 | ||
245 | if (isStacked) { | |
246 | DygraphOps.dispatchMouseMove(g, 11.45, 1.4); | |
89fdcedb DV |
247 | assert.equal(1, h_row); |
248 | assert.equal('c', h_series); | |
857a6931 KW |
249 | |
250 | //now move up in the same row | |
251 | DygraphOps.dispatchMouseMove(g, 11.45, 1.5); | |
89fdcedb DV |
252 | assert.equal(1, h_row); |
253 | assert.equal('b', h_series); | |
857a6931 KW |
254 | |
255 | //and a bit to the right | |
256 | DygraphOps.dispatchMouseMove(g, 11.55, 1.5); | |
89fdcedb DV |
257 | assert.equal(2, h_row); |
258 | assert.equal('c', h_series); | |
857a6931 KW |
259 | } else { |
260 | DygraphOps.dispatchMouseMove(g, 11, 1.5); | |
89fdcedb DV |
261 | assert.equal(1, h_row); |
262 | assert.equal('c', h_series); | |
857a6931 KW |
263 | |
264 | //now move up in the same row | |
265 | DygraphOps.dispatchMouseMove(g, 11, 2.5); | |
89fdcedb DV |
266 | assert.equal(1, h_row); |
267 | assert.equal('b', h_series); | |
857a6931 KW |
268 | } |
269 | ||
270 | return g; | |
271 | }; | |
272 | ||
273 | /** | |
274 | * Test basic closest-point highlighting. | |
275 | */ | |
89fdcedb | 276 | it('testClosestPointCallback', function() { |
857a6931 | 277 | runClosestTest(false, 1, 3); |
89fdcedb | 278 | }); |
857a6931 KW |
279 | |
280 | /** | |
281 | * Test setSelection() with series name | |
282 | */ | |
89fdcedb | 283 | it('testSetSelection', function() { |
857a6931 | 284 | var g = runClosestTest(false, 1, 3); |
89fdcedb | 285 | assert.equal(1, g.attr_('strokeWidth', 'c')); |
857a6931 | 286 | g.setSelection(false, 'c'); |
89fdcedb DV |
287 | assert.equal(3, g.attr_('strokeWidth', 'c')); |
288 | }); | |
857a6931 KW |
289 | |
290 | /** | |
291 | * Test closest-point highlighting for stacked graph | |
292 | */ | |
89fdcedb | 293 | it('testClosestPointStackedCallback', function() { |
857a6931 | 294 | runClosestTest(true, 1, 3); |
89fdcedb | 295 | }); |
857a6931 KW |
296 | |
297 | /** | |
298 | * Closest-point highlighting with legend CSS - border around active series. | |
299 | */ | |
89fdcedb | 300 | it('testClosestPointCallbackCss1', function() { |
857a6931 | 301 | var css = "div.dygraph-legend > span { display: block; }\n" + |
4ee251cb | 302 | "div.dygraph-legend > span.highlight { border: 1px solid grey; }\n"; |
319d0361 | 303 | styleSheet.innerHTML = css; |
857a6931 | 304 | runClosestTest(false, 2, 4); |
319d0361 | 305 | styleSheet.innerHTML = ''; |
89fdcedb | 306 | }); |
857a6931 KW |
307 | |
308 | /** | |
309 | * Closest-point highlighting with legend CSS - show only closest series. | |
310 | */ | |
89fdcedb | 311 | it('testClosestPointCallbackCss2', function() { |
857a6931 | 312 | var css = "div.dygraph-legend > span { display: none; }\n" + |
4ee251cb | 313 | "div.dygraph-legend > span.highlight { display: inline; }\n"; |
319d0361 | 314 | styleSheet.innerHTML = css; |
857a6931 | 315 | runClosestTest(false, 10, 15); |
319d0361 | 316 | styleSheet.innerHTML = ''; |
857a6931 | 317 | // TODO(klausw): verify that the highlighted line is drawn on top? |
89fdcedb | 318 | }); |
a937d031 KW |
319 | |
320 | /** | |
b9a3ece4 KW |
321 | * Closest-point highlighting with locked series. |
322 | */ | |
89fdcedb | 323 | it('testSetSelectionLocking', function() { |
b9a3ece4 KW |
324 | var g = runClosestTest(false, 2, 4); |
325 | ||
326 | // Default behavior, 'b' is closest | |
327 | DygraphOps.dispatchMouseMove(g, 11, 4); | |
89fdcedb | 328 | assert.equal('b', g.getHighlightSeries()); |
b9a3ece4 KW |
329 | |
330 | // Now lock selection to 'c' | |
331 | g.setSelection(false, 'c', true); | |
332 | DygraphOps.dispatchMouseMove(g, 11, 4); | |
89fdcedb | 333 | assert.equal('c', g.getHighlightSeries()); |
b9a3ece4 KW |
334 | |
335 | // Unlock, should be back to 'b' | |
336 | g.clearSelection(); | |
337 | DygraphOps.dispatchMouseMove(g, 11, 4); | |
89fdcedb DV |
338 | assert.equal('b', g.getHighlightSeries()); |
339 | }); | |
b9a3ece4 KW |
340 | |
341 | /** | |
a937d031 KW |
342 | * This tests that closest point searches work for data containing NaNs. |
343 | * | |
344 | * It's intended to catch a regression where a NaN Y value confuses the | |
345 | * closest-point algorithm, treating it as closer as any previous point. | |
346 | */ | |
89fdcedb | 347 | it('testNaNData', function() { |
a937d031 | 348 | var dataNaN = [ |
1069800f | 349 | [9, -1, NaN, NaN], |
a937d031 KW |
350 | [10, -1, 1, 2], |
351 | [11, 0, 3, 1], | |
352 | [12, 1, 4, NaN], | |
353 | [13, 0, 2, 3], | |
354 | [14, -1, 1, 4]]; | |
355 | ||
356 | var h_row; | |
357 | var h_pts; | |
358 | ||
4ee251cb | 359 | var highlightCallback = function(e, x, pts, row) { |
89fdcedb | 360 | assert.equal(g, this); |
a937d031 KW |
361 | h_row = row; |
362 | h_pts = pts; | |
363 | }; | |
364 | ||
a937d031 KW |
365 | var g = new Dygraph(graph, dataNaN, |
366 | { | |
367 | width: 600, | |
368 | height: 400, | |
369 | labels: ['x', 'a', 'b', 'c'], | |
370 | visibility: [false, true, true], | |
371 | highlightCallback: highlightCallback | |
372 | }); | |
373 | ||
374 | DygraphOps.dispatchMouseMove(g, 10.1, 0.9); | |
375 | //check correct row is returned | |
89fdcedb | 376 | assert.equal(1, h_row); |
a937d031 KW |
377 | |
378 | // Explicitly test closest point algorithms | |
379 | var dom = g.toDomCoords(10.1, 0.9); | |
89fdcedb | 380 | assert.equal(1, g.findClosestRow(dom[0])); |
a937d031 KW |
381 | |
382 | var res = g.findClosestPoint(dom[0], dom[1]); | |
89fdcedb DV |
383 | assert.equal(1, res.row); |
384 | assert.equal('b', res.seriesName); | |
a937d031 KW |
385 | |
386 | res = g.findStackedPoint(dom[0], dom[1]); | |
89fdcedb DV |
387 | assert.equal(1, res.row); |
388 | assert.equal('c', res.seriesName); | |
389 | }); | |
04c104d7 | 390 | |
7d463f49 KW |
391 | /** |
392 | * This tests that stacked point searches work for data containing NaNs. | |
393 | */ | |
89fdcedb | 394 | it('testNaNDataStack', function() { |
7d463f49 KW |
395 | var dataNaN = [ |
396 | [9, -1, NaN, NaN], | |
397 | [10, -1, 1, 2], | |
398 | [11, 0, 3, 1], | |
399 | [12, 1, NaN, 2], | |
400 | [13, 0, 2, 3], | |
401 | [14, -1, 1, 4], | |
402 | [15, 0, 2, NaN], | |
403 | [16, 1, 1, 3], | |
404 | [17, 1, NaN, 3], | |
405 | [18, 0, 2, 5], | |
406 | [19, 0, 1, 4]]; | |
407 | ||
408 | var h_row; | |
409 | var h_pts; | |
410 | ||
4ee251cb | 411 | var highlightCallback = function(e, x, pts, row) { |
89fdcedb | 412 | assert.equal(g, this); |
7d463f49 KW |
413 | h_row = row; |
414 | h_pts = pts; | |
415 | }; | |
416 | ||
7d463f49 KW |
417 | var g = new Dygraph(graph, dataNaN, |
418 | { | |
419 | width: 600, | |
420 | height: 400, | |
421 | labels: ['x', 'a', 'b', 'c'], | |
422 | visibility: [false, true, true], | |
423 | stackedGraph: true, | |
424 | highlightCallback: highlightCallback | |
425 | }); | |
426 | ||
427 | DygraphOps.dispatchMouseMove(g, 10.1, 0.9); | |
428 | //check correct row is returned | |
89fdcedb | 429 | assert.equal(1, h_row); |
7d463f49 KW |
430 | |
431 | // Explicitly test stacked point algorithm. | |
432 | var dom = g.toDomCoords(10.1, 0.9); | |
433 | var res = g.findStackedPoint(dom[0], dom[1]); | |
89fdcedb DV |
434 | assert.equal(1, res.row); |
435 | assert.equal('c', res.seriesName); | |
7d463f49 | 436 | |
30a5cfc6 KW |
437 | // All-NaN area at left, should get no points. |
438 | dom = g.toDomCoords(9.1, 0.9); | |
439 | res = g.findStackedPoint(dom[0], dom[1]); | |
89fdcedb DV |
440 | assert.equal(0, res.row); |
441 | assert.equal(undefined, res.seriesName); | |
30a5cfc6 KW |
442 | |
443 | // First gap, get 'c' since it's non-NaN. | |
7d463f49 KW |
444 | dom = g.toDomCoords(12.1, 0.9); |
445 | res = g.findStackedPoint(dom[0], dom[1]); | |
89fdcedb DV |
446 | assert.equal(3, res.row); |
447 | assert.equal('c', res.seriesName); | |
7d463f49 | 448 | |
30a5cfc6 | 449 | // Second gap, get 'b' since 'c' is NaN. |
7d463f49 KW |
450 | dom = g.toDomCoords(15.1, 0.9); |
451 | res = g.findStackedPoint(dom[0], dom[1]); | |
89fdcedb DV |
452 | assert.equal(6, res.row); |
453 | assert.equal('b', res.seriesName); | |
7d463f49 KW |
454 | |
455 | // Isolated points should work, finding series b in this case. | |
456 | dom = g.toDomCoords(15.9, 3.1); | |
457 | res = g.findStackedPoint(dom[0], dom[1]); | |
89fdcedb DV |
458 | assert.equal(7, res.row); |
459 | assert.equal('b', res.seriesName); | |
460 | }); | |
7d463f49 | 461 | |
89fdcedb | 462 | it('testGapHighlight', function() { |
492ea455 | 463 | var dataGap = [ |
04c104d7 KW |
464 | [1, null, 3], |
465 | [2, 2, null], | |
466 | [3, null, 5], | |
467 | [4, 4, null], | |
468 | [5, null, 7], | |
469 | [6, NaN, null], | |
470 | [8, 8, null], | |
471 | [10, 10, null]]; | |
472 | ||
473 | var h_row; | |
474 | var h_pts; | |
475 | ||
4ee251cb | 476 | var highlightCallback = function(e, x, pts, row) { |
89fdcedb | 477 | assert.equal(g, this); |
04c104d7 KW |
478 | h_row = row; |
479 | h_pts = pts; | |
480 | }; | |
481 | ||
04c104d7 KW |
482 | var g = new Dygraph(graph, dataGap, { |
483 | width: 400, | |
484 | height: 300, | |
485 | //stackedGraph: true, | |
486 | connectSeparatedPoints: true, | |
487 | drawPoints: true, | |
488 | labels: ['x', 'A', 'B'], | |
4ee251cb | 489 | highlightCallback: highlightCallback |
04c104d7 KW |
490 | }); |
491 | ||
492 | DygraphOps.dispatchMouseMove(g, 1.1, 10); | |
493 | //point from series B | |
89fdcedb DV |
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); | |
04c104d7 KW |
498 | |
499 | DygraphOps.dispatchMouseMove(g, 6.1, 10); | |
500 | // A is NaN at x=6 | |
89fdcedb | 501 | assert.equal(1, h_pts.length); |
04c104d7 | 502 | assert(isNaN(h_pts[0].yval)); |
89fdcedb | 503 | assert.equal('A', h_pts[0].name); |
04c104d7 KW |
504 | |
505 | DygraphOps.dispatchMouseMove(g, 8.1, 10); | |
506 | //point from series A | |
89fdcedb DV |
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); | |
511 | }); | |
4c10c8d2 | 512 | |
89fdcedb | 513 | it('testFailedResponse', function() { |
4c10c8d2 RK |
514 | |
515 | // Fake out the XMLHttpRequest so it doesn't do anything. | |
516 | XMLHttpRequest = function () {}; | |
517 | XMLHttpRequest.prototype.open = function () {}; | |
518 | XMLHttpRequest.prototype.send = function () {}; | |
519 | ||
520 | var highlightCallback = function(e, x, pts, row) { | |
89fdcedb | 521 | throw "should not reach here"; |
4c10c8d2 RK |
522 | }; |
523 | ||
4c10c8d2 RK |
524 | graph.style.border = "2px solid black"; |
525 | var g = new Dygraph(graph, "data.csv", { // fake name | |
526 | width: 400, | |
527 | height: 300, | |
528 | highlightCallback : highlightCallback | |
529 | }); | |
530 | ||
531 | DygraphOps.dispatchMouseOver_Point(g, 800, 800); | |
532 | DygraphOps.dispatchMouseMove_Point(g, 100, 100); | |
533 | DygraphOps.dispatchMouseMove_Point(g, 800, 800); | |
534 | ||
535 | var oldOnerror = window.onerror; | |
536 | var failed = false; | |
537 | window.onerror = function() { failed = true; return false; } | |
538 | ||
539 | DygraphOps.dispatchMouseOut_Point(g, 800, 800); // This call should not throw an exception. | |
540 | ||
fecbcf34 | 541 | assert.isFalse(failed, "exception thrown during mouseout"); |
89fdcedb | 542 | }); |
870a309c DV |
543 | |
544 | ||
545 | // Regression test for http://code.google.com/p/dygraphs/issues/detail?id=355 | |
89fdcedb | 546 | it('testHighlightCallbackRow', function() { |
870a309c DV |
547 | var highlightRow; |
548 | var highlightCallback = function(e, x, pts, row) { | |
89fdcedb | 549 | assert.equal(g, this); |
870a309c DV |
550 | highlightRow = row; |
551 | }; | |
552 | ||
870a309c DV |
553 | var g = new Dygraph(graph, |
554 | "X,Y,Z\n" + | |
555 | "0,1,2\n" + // 0 | |
556 | "1,2,3\n" + // 100 | |
557 | "2,3,4\n" + // 200 | |
558 | "3,4,5\n" + // 300 | |
559 | "4,5,6\n", // 400 | |
560 | { // fake name | |
561 | width: 400, | |
562 | height: 300, | |
563 | highlightCallback : highlightCallback | |
564 | }); | |
565 | ||
566 | // Mouse over each of the points | |
567 | DygraphOps.dispatchMouseOver_Point(g, 0, 0); | |
568 | DygraphOps.dispatchMouseMove_Point(g, 0, 0); | |
89fdcedb | 569 | assert.equal(0, highlightRow); |
870a309c | 570 | DygraphOps.dispatchMouseMove_Point(g, 100, 0); |
89fdcedb | 571 | assert.equal(1, highlightRow); |
870a309c | 572 | DygraphOps.dispatchMouseMove_Point(g, 200, 0); |
89fdcedb | 573 | assert.equal(2, highlightRow); |
870a309c | 574 | DygraphOps.dispatchMouseMove_Point(g, 300, 0); |
89fdcedb | 575 | assert.equal(3, highlightRow); |
870a309c | 576 | DygraphOps.dispatchMouseMove_Point(g, 400, 0); |
89fdcedb | 577 | assert.equal(4, highlightRow); |
870a309c DV |
578 | |
579 | // Now zoom and verify that the row numbers still refer to rows in the data | |
580 | // array. | |
581 | g.updateOptions({dateWindow: [2, 4]}); | |
582 | DygraphOps.dispatchMouseOver_Point(g, 0, 0); | |
583 | DygraphOps.dispatchMouseMove_Point(g, 0, 0); | |
89fdcedb DV |
584 | assert.equal(2, highlightRow); |
585 | assert.equal('2: Y: 3 Z: 4', Util.getLegend()); | |
586 | }); | |
5fdfe3b1 | 587 | |
588 | /** | |
589 | * Test that underlay callback is called even when there are no series, | |
590 | * and that the y axis ranges are not NaN. | |
591 | */ | |
89fdcedb | 592 | it('testUnderlayCallback_noSeries', function() { |
5fdfe3b1 | 593 | var called = false; |
594 | var yMin, yMax; | |
595 | ||
596 | var callback = function(canvas, area, g) { | |
89fdcedb | 597 | assert.equal(g, this); |
5fdfe3b1 | 598 | called = true; |
599 | yMin = g.yAxisRange(0)[0]; | |
83b552f9 | 600 | yMax = g.yAxisRange(0)[1]; |
5fdfe3b1 | 601 | }; |
602 | ||
5fdfe3b1 | 603 | var g = new Dygraph(graph, "\n", { |
604 | underlayCallback: callback | |
605 | }); | |
606 | ||
89fdcedb DV |
607 | assert.isTrue(called); |
608 | assert.isFalse(isNaN(yMin)); | |
609 | assert.isFalse(isNaN(yMax)); | |
610 | }); | |
113f6e16 | 611 | |
612 | /** | |
613 | * Test that underlay callback receives the correct y-axis range. | |
614 | */ | |
89fdcedb | 615 | it('testUnderlayCallback_yAxisRange', function() { |
113f6e16 | 616 | var called = false; |
617 | var yMin, yMax; | |
618 | ||
619 | var callback = function(canvas, area, g) { | |
89fdcedb | 620 | assert.equal(g, this); |
113f6e16 | 621 | yMin = g.yAxisRange(0)[0]; |
622 | yMax = g.yAxisRange(0)[1]; | |
623 | }; | |
624 | ||
113f6e16 | 625 | var g = new Dygraph(graph, "\n", { |
626 | valueRange: [0,10], | |
627 | underlayCallback: callback | |
628 | }); | |
629 | ||
89fdcedb DV |
630 | assert.equal(0, yMin); |
631 | assert.equal(10, yMax); | |
632 | }); | |
cd3f2b1a US |
633 | |
634 | /** | |
635 | * Test that drawPointCallback is called for isolated points and correct idx for the point is returned. | |
636 | */ | |
89fdcedb | 637 | it('testDrawPointCallback_idx', function() { |
4ee251cb DV |
638 | var indices = []; |
639 | ||
640 | var g; | |
641 | var callback = function(g, seriesName, canvasContext, cx, cy, color, pointSizeParam,idx) { | |
89fdcedb | 642 | assert.equal(g, this); |
4ee251cb | 643 | indices.push(idx); |
e8c70e4e | 644 | utils.Circles.DEFAULT.apply(this, arguments); |
4ee251cb DV |
645 | }; |
646 | ||
4ee251cb DV |
647 | |
648 | var testdata = [[10, 2], [11, 3], [12, NaN], [13, 2], [14, NaN], [15, 3]]; | |
649 | var graphOpts = { | |
650 | labels: ['X', 'Y'], | |
651 | valueRange: [0, 4], | |
652 | drawPoints : false, | |
653 | drawPointCallback : callback, | |
654 | pointSize : 8 | |
655 | }; | |
656 | ||
657 | // Test that correct idx for isolated points are passed to the callback. | |
658 | g = new Dygraph(graph, testdata, graphOpts); | |
89fdcedb DV |
659 | assert.equal(2, indices.length); |
660 | assert.deepEqual([3, 5],indices); | |
4ee251cb DV |
661 | |
662 | // Test that correct indices for isolated points + gap points are passed to the callback when | |
663 | // drawGapEdgePoints is set. This should add one point at the right | |
664 | // edge of the segment at x=11, but not at the graph edge at x=10. | |
665 | indices = []; // Reset for new test | |
666 | graphOpts.drawGapEdgePoints = true; | |
667 | g = new Dygraph(graph, testdata, graphOpts); | |
89fdcedb DV |
668 | assert.equal(3, indices.length); |
669 | assert.deepEqual([1, 3, 5],indices); | |
4ee251cb DV |
670 | |
671 | ||
672 | //Test that correct indices are passed to the callback when zoomed in. | |
673 | indices = []; // Reset for new test | |
674 | graphOpts.dateWindow = [12.5,13.5] | |
675 | graphOpts.drawPoints = true; | |
676 | testdata = [[10, 2], [11, 3], [12, 4], [13, 2], [14, 5], [15, 3]]; | |
677 | g = new Dygraph(graph, testdata, graphOpts); | |
89fdcedb DV |
678 | assert.equal(3, indices.length); |
679 | assert.deepEqual([2, 3, 4],indices); | |
680 | }); | |
cd3f2b1a US |
681 | |
682 | /** | |
683 | * Test that the correct idx is returned for the point in the onHiglightCallback. | |
b617ba25 | 684 | */ |
89fdcedb | 685 | it('testDrawHighlightPointCallback_idx', function() { |
4ee251cb DV |
686 | var idxToCheck = null; |
687 | ||
688 | var drawHighlightPointCallback = function(g, seriesName, canvasContext, cx, cy, color, pointSizeParam,idx) { | |
89fdcedb | 689 | assert.equal(g, this); |
4ee251cb DV |
690 | idxToCheck = idx; |
691 | }; | |
692 | var testdata = [[1, 2], [2, 3], [3, NaN], [4, 2], [5, NaN], [6, 3]]; | |
65129ba8 DV |
693 | var g = new Dygraph(graph, testdata, { |
694 | drawHighlightPointCallback: drawHighlightPointCallback, | |
695 | labels: ['X', 'Y'] | |
4ee251cb DV |
696 | }); |
697 | ||
89fdcedb | 698 | assert.isNull(idxToCheck); |
4ee251cb DV |
699 | DygraphOps.dispatchMouseMove(g, 3, 0); |
700 | // check that NaN point is not highlighted | |
89fdcedb | 701 | assert.isNull(idxToCheck); |
4ee251cb DV |
702 | DygraphOps.dispatchMouseMove(g, 1, 2); |
703 | // check that correct index is returned | |
89fdcedb | 704 | assert.equal(0,idxToCheck); |
4ee251cb | 705 | DygraphOps.dispatchMouseMove(g, 6, 3); |
89fdcedb DV |
706 | assert.equal(5,idxToCheck); |
707 | }); | |
708 | ||
b617ba25 DV |
709 | /** |
710 | * Test that drawCallback is called with the correct value for `this`. | |
711 | */ | |
712 | it('should set this in drawCallback', function() { | |
713 | var g = new Dygraph('graph', data, { | |
714 | drawCallback: function(g, is_initial) { | |
715 | assert.isTrue(is_initial); | |
716 | assert.equal(g, this); | |
717 | } | |
718 | }); | |
719 | }); | |
720 | ||
89fdcedb | 721 | }); |