2 * @fileoverview Test cases for the callbacks.
4 * @author uemit.seren@gmail.com (Ümit Seren)
7 import Dygraph from
'../../src/dygraph';
8 import * as utils from
'../../src/dygraph-utils';
9 import Util from
'./Util';
10 import DygraphOps from
'./DygraphOps';
12 describe("callback", function() {
19 beforeEach(function() {
20 var container
= document
.getElementById('graph');
21 container
.innerHTML
= "<div id='inner-graph'></div><div id='selection'></div>";
22 graph
= container
.querySelector('#inner-graph');
24 styleSheet
= document
.createElement("style");
25 styleSheet
.type
= "text/css";
26 document
.getElementsByTagName("head")[0].appendChild(styleSheet
);
29 afterEach(function() {
30 window
.XMLHttpRequest
= xhr
;
33 var data
= "X,a,b,c\n" +
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)
45 it('testHighlightCallbackIsCalled', function() {
49 var highlightCallback
= function(e
, x
, pts
, row
) {
50 assert
.equal(g
, this);
55 var g
= new Dygraph(graph
, data
,
59 visibility
: [false, true, true],
60 highlightCallback
: highlightCallback
63 DygraphOps
.dispatchMouseMove(g
, 13, 10);
65 //check correct row is returned
66 assert
.equal(3, h_row
);
67 //check there are only two points (because first series is hidden)
68 assert
.equal(2, h_pts
.length
);
73 * Test that drawPointCallback isn't called when drawPoints is false
75 it('testDrawPointCallback_disabled', function() {
78 var callback
= function() {
79 assert
.equal(g
, this);
83 var g
= new Dygraph(graph
, data
, {
84 drawPointCallback
: callback
,
87 assert
.isFalse(called
);
91 * Test that drawPointCallback is called when drawPoints is true
93 it('testDrawPointCallback_enabled', function() {
95 var callbackThis
= null;
97 var callback
= function() {
102 var g
= new Dygraph(graph
, data
, {
104 drawPointCallback
: callback
107 assert
.isTrue(called
);
108 assert
.equal(g
, callbackThis
);
112 * Test that drawPointCallback is called when drawPoints is true
114 it('testDrawPointCallback_pointSize', function() {
118 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
119 assert
.equal(g
, this);
120 pointSize
= pointSizeParam
;
124 var g
= new Dygraph(graph
, data
, {
126 drawPointCallback
: callback
129 assert
.equal(1.5, pointSize
);
130 assert
.equal(12, count
); // one call per data point.
132 var g
= new Dygraph(graph
, data
, {
134 drawPointCallback
: callback
,
138 assert
.equal(8, pointSize
);
142 * Test that drawPointCallback is called for isolated points when
143 * drawPoints is false, and also for gap points if that's enabled.
145 it('testDrawPointCallback_isolated', function() {
149 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
) {
150 assert
.equal(g
, this);
151 var dx
= g
.toDataXCoord(cx
);
153 utils
.Circles
.DEFAULT
.apply(this, arguments
);
156 var testdata
= [[10, 2], [11, 3], [12, NaN
], [13, 2], [14, NaN
], [15, 3]];
161 drawPointCallback
: callback
,
165 // Test that isolated points get drawn
166 g
= new Dygraph(graph
, testdata
, graphOpts
);
167 assert
.equal(2, xvalues
.length
);
168 assert
.equal(13, xvalues
[0]);
169 assert
.equal(15, xvalues
[1]);
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.
174 xvalues
= []; // Reset for new test
175 graphOpts
.drawGapEdgePoints
= true;
176 g
= new Dygraph(graph
, testdata
, graphOpts
);
177 assert
.equal(3, xvalues
.length
);
178 assert
.equal(11, xvalues
[0]);
179 assert
.equal(13, xvalues
[1]);
180 assert
.equal(15, xvalues
[2]);
184 * This tests that when the function idxToRow_ returns the proper row and the onHiglightCallback
185 * is properly called when the first series is hidden (setVisibility = false)
188 it('testDrawHighlightPointCallbackIsCalled', function() {
191 var drawHighlightPointCallback
= function() {
192 assert
.equal(g
, this);
196 var g
= new Dygraph(graph
, data
,
200 drawHighlightPointCallback
: drawHighlightPointCallback
203 assert
.isFalse(called
);
204 DygraphOps
.dispatchMouseMove(g
, 13, 10);
205 assert
.isTrue(called
);
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.
213 var runClosestTest
= function(isStacked
, widthNormal
, widthHighlighted
) {
218 var g
= new Dygraph(graph
, data
,
222 visibility
: [false, true, true],
223 stackedGraph
: isStacked
,
224 strokeWidth
: widthNormal
,
225 strokeBorderWidth
: 2,
226 highlightCircleSize
: widthNormal
* 2,
227 highlightSeriesBackgroundAlpha
: 0.3,
229 highlightSeriesOpts
: {
230 strokeWidth
: widthHighlighted
,
231 highlightCircleSize
: widthHighlighted
* 2
235 var highlightCallback
= function(e
, x
, pts
, row
, set
) {
236 assert
.equal(g
, this);
240 document
.getElementById('selection').innerHTML
='row=' + row
+ ', set=' + set
;
243 g
.updateOptions({highlightCallback
: highlightCallback
}, true);
246 DygraphOps
.dispatchMouseMove(g
, 11.45, 1.4);
247 assert
.equal(1, h_row
);
248 assert
.equal('c', h_series
);
250 //now move up in the same row
251 DygraphOps
.dispatchMouseMove(g
, 11.45, 1.5);
252 assert
.equal(1, h_row
);
253 assert
.equal('b', h_series
);
255 //and a bit to the right
256 DygraphOps
.dispatchMouseMove(g
, 11.55, 1.5);
257 assert
.equal(2, h_row
);
258 assert
.equal('c', h_series
);
260 DygraphOps
.dispatchMouseMove(g
, 11, 1.5);
261 assert
.equal(1, h_row
);
262 assert
.equal('c', h_series
);
264 //now move up in the same row
265 DygraphOps
.dispatchMouseMove(g
, 11, 2.5);
266 assert
.equal(1, h_row
);
267 assert
.equal('b', h_series
);
274 * Test basic closest-point highlighting.
276 it('testClosestPointCallback', function() {
277 runClosestTest(false, 1, 3);
281 * Test setSelection() with series name
283 it('testSetSelection', function() {
284 var g
= runClosestTest(false, 1, 3);
285 assert
.equal(1, g
.attr_('strokeWidth', 'c'));
286 g
.setSelection(false, 'c');
287 assert
.equal(3, g
.attr_('strokeWidth', 'c'));
291 * Test closest-point highlighting for stacked graph
293 it('testClosestPointStackedCallback', function() {
294 runClosestTest(true, 1, 3);
298 * Closest-point highlighting with legend CSS - border around active series.
300 it('testClosestPointCallbackCss1', function() {
301 var css
= "div.dygraph-legend > span { display: block; }\n" +
302 "div.dygraph-legend > span.highlight { border: 1px solid grey; }\n";
303 styleSheet
.innerHTML
= css
;
304 runClosestTest(false, 2, 4);
305 styleSheet
.innerHTML
= '';
309 * Closest-point highlighting with legend CSS - show only closest series.
311 it('testClosestPointCallbackCss2', function() {
312 var css
= "div.dygraph-legend > span { display: none; }\n" +
313 "div.dygraph-legend > span.highlight { display: inline; }\n";
314 styleSheet
.innerHTML
= css
;
315 runClosestTest(false, 10, 15);
316 styleSheet
.innerHTML
= '';
317 // TODO(klausw): verify that the highlighted line is drawn on top?
321 * Closest-point highlighting with locked series.
323 it('testSetSelectionLocking', function() {
324 var g
= runClosestTest(false, 2, 4);
326 // Default behavior, 'b' is closest
327 DygraphOps
.dispatchMouseMove(g
, 11, 4);
328 assert
.equal('b', g
.getHighlightSeries());
330 // Now lock selection to 'c'
331 g
.setSelection(false, 'c', true);
332 DygraphOps
.dispatchMouseMove(g
, 11, 4);
333 assert
.equal('c', g
.getHighlightSeries());
335 // Unlock, should be back to 'b'
337 DygraphOps
.dispatchMouseMove(g
, 11, 4);
338 assert
.equal('b', g
.getHighlightSeries());
342 * This tests that closest point searches work for data containing NaNs.
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.
347 it('testNaNData', function() {
359 var highlightCallback
= function(e
, x
, pts
, row
) {
360 assert
.equal(g
, this);
365 var g
= new Dygraph(graph
, dataNaN
,
369 labels
: ['x', 'a', 'b', 'c'],
370 visibility
: [false, true, true],
371 highlightCallback
: highlightCallback
374 DygraphOps
.dispatchMouseMove(g
, 10.1, 0.9);
375 //check correct row is returned
376 assert
.equal(1, h_row
);
378 // Explicitly test closest point algorithms
379 var dom
= g
.toDomCoords(10.1, 0.9);
380 assert
.equal(1, g
.findClosestRow(dom
[0]));
382 var res
= g
.findClosestPoint(dom
[0], dom
[1]);
383 assert
.equal(1, res
.row
);
384 assert
.equal('b', res
.seriesName
);
386 res
= g
.findStackedPoint(dom
[0], dom
[1]);
387 assert
.equal(1, res
.row
);
388 assert
.equal('c', res
.seriesName
);
392 * This tests that stacked point searches work for data containing NaNs.
394 it('testNaNDataStack', function() {
411 var highlightCallback
= function(e
, x
, pts
, row
) {
412 assert
.equal(g
, this);
417 var g
= new Dygraph(graph
, dataNaN
,
421 labels
: ['x', 'a', 'b', 'c'],
422 visibility
: [false, true, true],
424 highlightCallback
: highlightCallback
427 DygraphOps
.dispatchMouseMove(g
, 10.1, 0.9);
428 //check correct row is returned
429 assert
.equal(1, h_row
);
431 // Explicitly test stacked point algorithm.
432 var dom
= g
.toDomCoords(10.1, 0.9);
433 var res
= g
.findStackedPoint(dom
[0], dom
[1]);
434 assert
.equal(1, res
.row
);
435 assert
.equal('c', res
.seriesName
);
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]);
440 assert
.equal(0, res
.row
);
441 assert
.equal(undefined
, res
.seriesName
);
443 // First gap, get 'c' since it's non-NaN.
444 dom
= g
.toDomCoords(12.1, 0.9);
445 res
= g
.findStackedPoint(dom
[0], dom
[1]);
446 assert
.equal(3, res
.row
);
447 assert
.equal('c', res
.seriesName
);
449 // Second gap, get 'b' since 'c' is NaN.
450 dom
= g
.toDomCoords(15.1, 0.9);
451 res
= g
.findStackedPoint(dom
[0], dom
[1]);
452 assert
.equal(6, res
.row
);
453 assert
.equal('b', res
.seriesName
);
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]);
458 assert
.equal(7, res
.row
);
459 assert
.equal('b', res
.seriesName
);
462 it('testGapHighlight', function() {
476 var highlightCallback
= function(e
, x
, pts
, row
) {
477 assert
.equal(g
, this);
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 graph
.style
.border
= "2px solid black";
525 var g
= new Dygraph(graph
, "data.csv", { // fake name
528 highlightCallback
: highlightCallback
531 DygraphOps
.dispatchMouseOver_Point(g
, 800, 800);
532 DygraphOps
.dispatchMouseMove_Point(g
, 100, 100);
533 DygraphOps
.dispatchMouseMove_Point(g
, 800, 800);
535 var oldOnerror
= window
.onerror
;
537 window
.onerror
= function() { failed
= true; return false; }
539 DygraphOps
.dispatchMouseOut_Point(g
, 800, 800); // This call should not throw an exception.
541 assert
.isFalse(failed
, "exception thrown during mouseout");
545 // Regression test for http://code.google.com/p/dygraphs/issues/detail
?id
=355
546 it('testHighlightCallbackRow', function() {
548 var highlightCallback
= function(e
, x
, pts
, row
) {
549 assert
.equal(g
, this);
553 var g
= new Dygraph(graph
,
563 highlightCallback
: highlightCallback
566 // Mouse over each of the points
567 DygraphOps
.dispatchMouseOver_Point(g
, 0, 0);
568 DygraphOps
.dispatchMouseMove_Point(g
, 0, 0);
569 assert
.equal(0, highlightRow
);
570 DygraphOps
.dispatchMouseMove_Point(g
, 100, 0);
571 assert
.equal(1, highlightRow
);
572 DygraphOps
.dispatchMouseMove_Point(g
, 200, 0);
573 assert
.equal(2, highlightRow
);
574 DygraphOps
.dispatchMouseMove_Point(g
, 300, 0);
575 assert
.equal(3, highlightRow
);
576 DygraphOps
.dispatchMouseMove_Point(g
, 400, 0);
577 assert
.equal(4, highlightRow
);
579 // Now zoom and verify that the row numbers still refer to rows in the data
581 g
.updateOptions({dateWindow
: [2, 4]});
582 DygraphOps
.dispatchMouseOver_Point(g
, 0, 0);
583 DygraphOps
.dispatchMouseMove_Point(g
, 0, 0);
584 assert
.equal(2, highlightRow
);
585 assert
.equal('2: Y: 3 Z: 4', Util
.getLegend());
589 * Test that underlay callback is called even when there are no series,
590 * and that the y axis ranges are not NaN.
592 it('testUnderlayCallback_noSeries', function() {
596 var callback
= function(canvas
, area
, g
) {
597 assert
.equal(g
, this);
599 yMin
= g
.yAxisRange(0)[0];
600 yMax
= g
.yAxisRange(0)[1];
603 var g
= new Dygraph(graph
, "\n", {
604 underlayCallback
: callback
607 assert
.isTrue(called
);
608 assert
.isFalse(isNaN(yMin
));
609 assert
.isFalse(isNaN(yMax
));
613 * Test that underlay callback receives the correct y-axis range.
615 it('testUnderlayCallback_yAxisRange', function() {
619 var callback
= function(canvas
, area
, g
) {
620 assert
.equal(g
, this);
621 yMin
= g
.yAxisRange(0)[0];
622 yMax
= g
.yAxisRange(0)[1];
625 var g
= new Dygraph(graph
, "\n", {
627 underlayCallback
: callback
630 assert
.equal(0, yMin
);
631 assert
.equal(10, yMax
);
635 * Test that drawPointCallback is called for isolated points and correct idx for the point is returned.
637 it('testDrawPointCallback_idx', function() {
641 var callback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
642 assert
.equal(g
, this);
644 utils
.Circles
.DEFAULT
.apply(this, arguments
);
648 var testdata
= [[10, 2], [11, 3], [12, NaN
], [13, 2], [14, NaN
], [15, 3]];
653 drawPointCallback
: callback
,
657 // Test that correct idx for isolated points are passed to the callback.
658 g
= new Dygraph(graph
, testdata
, graphOpts
);
659 assert
.equal(2, indices
.length
);
660 assert
.deepEqual([3, 5],indices
);
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
);
668 assert
.equal(3, indices
.length
);
669 assert
.deepEqual([1, 3, 5],indices
);
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
);
678 assert
.equal(3, indices
.length
);
679 assert
.deepEqual([2, 3, 4],indices
);
683 * Test that the correct idx is returned for the point in the onHiglightCallback.
685 it('testDrawHighlightPointCallback_idx', function() {
686 var idxToCheck
= null;
688 var drawHighlightPointCallback
= function(g
, seriesName
, canvasContext
, cx
, cy
, color
, pointSizeParam
,idx
) {
689 assert
.equal(g
, this);
692 var testdata
= [[1, 2], [2, 3], [3, NaN
], [4, 2], [5, NaN
], [6, 3]];
693 var g
= new Dygraph(graph
, testdata
, {
694 drawHighlightPointCallback
: drawHighlightPointCallback
,
698 assert
.isNull(idxToCheck
);
699 DygraphOps
.dispatchMouseMove(g
, 3, 0);
700 // check that NaN point is not highlighted
701 assert
.isNull(idxToCheck
);
702 DygraphOps
.dispatchMouseMove(g
, 1, 2);
703 // check that correct index is returned
704 assert
.equal(0,idxToCheck
);
705 DygraphOps
.dispatchMouseMove(g
, 6, 3);
706 assert
.equal(5,idxToCheck
);
710 * Test that drawCallback is called with the correct value for `this`.
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);