Merge pull request #573 from danvk/coverage-cleanup
[dygraphs.git] / auto_tests / tests / range_selector.js
CommitLineData
ccd9d7c2
PF
1// Copyright 2011 Google Inc. All Rights Reserved.
2
3/**
4 * @fileoverview Regression tests for range selector.
5 * @author paul.eric.felix@gmail.com (Paul Felix)
6 */
89fdcedb 7describe("range-selector", function() {
ccd9d7c2 8
89fdcedb 9beforeEach(function() {
ccd9d7c2 10 document.body.innerHTML = "<div id='graph'></div>";
89fdcedb 11});
ccd9d7c2 12
89fdcedb
DV
13afterEach(function() {
14});
ccd9d7c2 15
89fdcedb 16it('testRangeSelector', function() {
ccd9d7c2
PF
17 var opts = {
18 width: 480,
19 height: 320,
b1a96215
DV
20 showRangeSelector: true,
21 labels: ['X', 'Y']
ccd9d7c2
PF
22 };
23 var data = [
24 [1, 10],
25 [2, 15],
26 [3, 10],
27 [4, 15],
28 [5, 10],
29 [6, 15],
30 [7, 10],
31 [8, 15],
32 [9, 10]
33 ];
34 var graph = document.getElementById("graph");
35 var g = new Dygraph(graph, data, opts);
319d0361 36 assertGraphExistence(g, graph);
89fdcedb 37});
ccd9d7c2 38
89fdcedb 39it('testRangeSelectorWithErrorBars', function() {
ccd9d7c2
PF
40 var opts = {
41 width: 480,
42 height: 320,
43 errorBars: true,
b1a96215
DV
44 showRangeSelector: true,
45 labels: ['X', 'Y']
ccd9d7c2
PF
46 };
47 var data = [
48 [1, [10, 10]],
49 [2, [15, 10]],
50 [3, [10, 10]],
51 [4, [15, 10]],
52 [5, [10, 10]],
53 [6, [15, 20]],
54 [7, [10, 20]],
55 [8, [15, 20]],
56 [9, [10, 20]]
57 ];
58 var graph = document.getElementById("graph");
59 var g = new Dygraph(graph, data, opts);
319d0361 60 assertGraphExistence(g, graph);
89fdcedb 61});
ccd9d7c2 62
89fdcedb 63it('testRangeSelectorWithCustomBars', function() {
ccd9d7c2
PF
64 var opts = {
65 width: 480,
66 height: 320,
67 customBars: true,
b1a96215
DV
68 showRangeSelector: true,
69 labels: ['X', 'Y']
ccd9d7c2
PF
70 };
71 var data = [
72 [1, [10, 10, 100]],
73 [2, [15, 20, 110]],
74 [3, [10, 30, 100]],
75 [4, [15, 40, 110]],
76 [5, [10, 120, 100]],
77 [6, [15, 50, 110]],
78 [7, [10, 70, 100]],
79 [8, [15, 90, 110]],
80 [9, [10, 50, 100]]
81 ];
82 var graph = document.getElementById("graph");
83 var g = new Dygraph(graph, data, opts);
319d0361 84 assertGraphExistence(g, graph);
89fdcedb 85});
ccd9d7c2 86
89fdcedb 87it('testRangeSelectorWithLogScale', function() {
ccd9d7c2
PF
88 var opts = {
89 width: 480,
90 height: 320,
91 logscale: true,
b1a96215
DV
92 showRangeSelector: true,
93 labels: ['X', 'Y']
ccd9d7c2
PF
94 };
95 var data = [
96 [1, 10],
97 [2, 15],
98 [3, 10],
99 [4, 15],
100 [5, 10],
101 [6, 15],
102 [7, 10],
103 [8, 15],
104 [9, 10]
105 ];
106 var graph = document.getElementById("graph");
107 var g = new Dygraph(graph, data, opts);
319d0361 108 assertGraphExistence(g, graph);
89fdcedb 109});
ccd9d7c2 110
89fdcedb 111it('testRangeSelectorOptions', function() {
ccd9d7c2
PF
112 var opts = {
113 width: 480,
114 height: 320,
115 showRangeSelector: true,
116 rangeSelectorHeight: 30,
117 rangeSelectorPlotFillColor: 'lightyellow',
79cb28dd 118 rangeSelectorPlotFillGradientColor: 'rgba(200, 200, 42, 10)',
b1a96215 119 labels: ['X', 'Y']
ccd9d7c2
PF
120 };
121 var data = [
122 [1, 10],
123 [2, 15],
124 [3, 10],
125 [4, 15],
126 [5, 10],
127 [6, 15],
128 [7, 10],
129 [8, 15],
130 [9, 10]
131 ];
132 var graph = document.getElementById("graph");
133 var g = new Dygraph(graph, data, opts);
319d0361 134 assertGraphExistence(g, graph);
89fdcedb 135});
ccd9d7c2 136
89fdcedb 137it('testAdditionalRangeSelectorOptions', function() {
b77d7a56 138 var opts = {
139 width: 480,
140 height: 320,
141 showRangeSelector: true,
142 rangeSelectorHeight: 30,
fb24d32c 143 rangeSelectorBackgroundStrokeColor: 'blue',
144 rangeSelectorBackgroundLineWidth: 3,
b77d7a56 145 rangeSelectorPlotLineWidth: 0.5,
fb24d32c 146 rangeSelectorForegroundStrokeColor: 'red',
147 rangeSelectorForegroundLineWidth: 2,
b77d7a56 148 rangeSelectorAlpha: 0.8,
149 labels: ['X', 'Y']
150 };
151 var data = [
152 [1, 10],
153 [2, 15],
154 [3, 10],
155 [4, 15],
156 [5, 10],
157 [6, 15],
158 [7, 10],
159 [8, 15],
160 [9, 10]
161 ];
162 var graph = document.getElementById("graph");
163 var g = new Dygraph(graph, data, opts);
319d0361 164 assertGraphExistence(g, graph);
89fdcedb 165});
b77d7a56 166
89fdcedb 167it('testRangeSelectorEnablingAfterCreation', function() {
ceb821aa
PF
168 var opts = {
169 width: 480,
b1a96215
DV
170 height: 320,
171 labels: ['X', 'Y']
ceb821aa
PF
172 };
173 var data = [
174 [1, 10],
175 [2, 15],
176 [3, 10],
177 [4, 15],
178 [5, 10],
179 [6, 15],
180 [7, 10],
181 [8, 15],
182 [9, 10]
183 ];
184 var graph = document.getElementById("graph");
185 var g = new Dygraph(graph, data, opts);
44310217 186 var initialChartHeight = g.getArea().h;
ceb821aa 187 g.updateOptions({showRangeSelector: true});
319d0361 188 assertGraphExistence(g, graph);
44310217
DV
189 assert(g.getArea().h < initialChartHeight); // range selector shown
190
191 g.updateOptions({showRangeSelector: false});
192 assert.equal(g.getArea().h, initialChartHeight); // range selector hidden
89fdcedb 193});
ceb821aa
PF
194
195// The animatedZooms option does not work with the range selector. Make sure it gets turned off.
89fdcedb 196it('testRangeSelectorWithAnimatedZoomsOption', function() {
ceb821aa
PF
197 var opts = {
198 width: 480,
199 height: 320,
200 showRangeSelector: true,
b1a96215
DV
201 animatedZooms: true,
202 labels: ['X', 'Y']
ceb821aa
PF
203 };
204 var data = [
205 [1, 10],
206 [2, 15],
207 [3, 10],
208 [4, 15],
209 [5, 10],
210 [6, 15],
211 [7, 10],
212 [8, 15],
213 [9, 10]
214 ];
215 var graph = document.getElementById("graph");
216 var g = new Dygraph(graph, data, opts);
319d0361 217 assertGraphExistence(g, graph);
89fdcedb
DV
218 assert.isFalse(g.getOption('animatedZooms'));
219});
ceb821aa 220
89fdcedb 221it('testRangeSelectorWithAnimatedZoomsOption2', function() {
ceb821aa
PF
222 var opts = {
223 width: 480,
224 height: 320,
b1a96215
DV
225 animatedZooms: true,
226 labels: ['X', 'Y']
ceb821aa
PF
227 };
228 var data = [
229 [1, 10],
230 [2, 15],
231 [3, 10],
232 [4, 15],
233 [5, 10],
234 [6, 15],
235 [7, 10],
236 [8, 15],
237 [9, 10]
238 ];
239 var graph = document.getElementById("graph");
240 var g = new Dygraph(graph, data, opts);
241 g.updateOptions({showRangeSelector: true});
319d0361 242 assertGraphExistence(g, graph);
89fdcedb
DV
243 assert.isFalse(g.getOption('animatedZooms'));
244});
ceb821aa 245
89fdcedb 246it('testRangeSelectorInteraction', function() {
2871344a
PF
247 var opts = {
248 width: 480,
249 height: 320,
b1a96215
DV
250 showRangeSelector: true,
251 labels: ['X', 'Y']
2871344a
PF
252 };
253 var data = [
254 [1, 10],
255 [2, 15],
256 [3, 10],
257 [4, 15],
258 [5, 10],
259 [6, 15],
260 [7, 10],
261 [8, 15],
262 [9, 10]
263 ];
264 var graph = document.getElementById("graph");
265 var g = new Dygraph(graph, data, opts);
319d0361 266 assertGraphExistence(g, graph);
2871344a
PF
267 var zoomhandles = graph.getElementsByClassName('dygraph-rangesel-zoomhandle');
268
269 // Move left zoomhandle in
270 var xRange = g.xAxisRange().slice();
271
272 var mouseDownEvent = DygraphOps.createEvent({
273 type : 'dragstart',
274 detail: 1,
275 clientX : 0,
276 clientY : 0
277 });
278 zoomhandles[0].dispatchEvent(mouseDownEvent);
279
280 var mouseMoveEvent = DygraphOps.createEvent({
281 type : 'mousemove',
282 clientX : 20,
283 clientY : 20
284 });
285 zoomhandles[0].dispatchEvent(mouseMoveEvent);
286
287 var mouseUpEvent = DygraphOps.createEvent({
288 type : 'mouseup',
289 detail: 1,
290 clientX : 20,
291 clientY : 20
292 });
293 zoomhandles[0].dispatchEvent(mouseUpEvent);
294
295 var newXRange = g.xAxisRange().slice();
fecbcf34 296 assert(newXRange[0] > xRange[0], 'left zoomhandle should have moved: '+newXRange[0]+'>'+xRange[0]);
dc910fce 297 assert.equal(xRange[1], newXRange[1], 'right zoomhandle should not have moved');
2871344a
PF
298
299 // Move right zoomhandle in
300 xRange = newXRange;
301
302 mouseDownEvent = DygraphOps.createEvent({
303 type : 'dragstart',
304 detail: 1,
305 clientX : 100,
306 clientY : 100
307 });
308 zoomhandles[1].dispatchEvent(mouseDownEvent);
309
310 mouseMoveEvent = DygraphOps.createEvent({
311 type : 'mousemove',
312 clientX : 80,
313 clientY : 80
314 });
315 zoomhandles[1].dispatchEvent(mouseMoveEvent);
316
317 mouseUpEvent = DygraphOps.createEvent({
318 type : 'mouseup',
319 detail: 1,
320 clientX : 80,
321 clientY : 80
322 });
323 zoomhandles[1].dispatchEvent(mouseUpEvent);
324
325 var newXRange = g.xAxisRange().slice();
dc910fce
DV
326 assert(newXRange[1] < xRange[1], 'right zoomhandle should have moved: '+newXRange[1]+'<'+xRange[1]);
327 assert.equal(xRange[0], newXRange[0], 'left zoomhandle should not have moved');
2871344a
PF
328
329 // Pan left
330 xRange = newXRange;
331 var fgcanvas = graph.getElementsByClassName('dygraph-rangesel-fgcanvas')[0];
332 var x = parseInt(zoomhandles[0].style.left) + 20;
333 var y = parseInt(zoomhandles[0].style.top);
334
335 mouseDownEvent = DygraphOps.createEvent({
336 type : 'mousedown',
337 detail: 1,
338 clientX : x,
339 clientY : y
340 });
341 fgcanvas.dispatchEvent(mouseDownEvent);
342
343 x -= 10;
344
345 mouseMoveEvent = DygraphOps.createEvent({
346 type : 'mousemove',
347 clientX : x,
348 clientY : y
349 });
350 fgcanvas.dispatchEvent(mouseMoveEvent);
351
352 mouseUpEvent = DygraphOps.createEvent({
353 type : 'mouseup',
354 detail: 1,
355 clientX : x,
356 clientY : y
357 });
358 fgcanvas.dispatchEvent(mouseUpEvent);
359
360 var newXRange = g.xAxisRange().slice();
fecbcf34
DV
361 assert(newXRange[0] < xRange[0], newXRange[0]+'<'+xRange[0]);
362 assert(newXRange[1] < xRange[1], newXRange[1]+'<'+xRange[1]);
89fdcedb 363});
2871344a 364
3718778b 365
89fdcedb 366it('testRangeSelectorPositionIfXAxisNotDrawn', function() {
3718778b
DE
367 var opts = {
368 width: 480,
369 height: 100,
370 xAxisHeight: 30,
bfb3e0a4 371 axes : { x : { drawAxis: false }},
3718778b 372 showRangeSelector: true,
b1a96215
DV
373 rangeSelectorHeight: 30,
374 labels: ['X', 'Y']
3718778b
DE
375 };
376 var data = [
377 [0, 1],
378 [10, 1]
379 ];
380 var graph = document.getElementById("graph");
381 var g = new Dygraph(graph, data, opts);
b77d7a56 382
3718778b 383 //assert, that the range selector is at top position 70 since the 30px of the
55cf43c3 384 // xAxis shouldn't be reserved since it isn't drawn.
319d0361 385 assertGraphExistence(g, graph);
3718778b 386 var bgcanvas = graph.getElementsByClassName('dygraph-rangesel-bgcanvas')[0];
dc910fce 387 assert.equal("70px", bgcanvas.style.top, "Range selector is not at the expected position.");
3718778b 388 var fgcanvas = graph.getElementsByClassName('dygraph-rangesel-fgcanvas')[0];
dc910fce 389 assert.equal("70px", fgcanvas.style.top, "Range selector is not at the expected position.");
89fdcedb 390});
3718778b 391
89fdcedb 392it('testMiniPlotDrawn', function() {
b1a96215
DV
393 // Install Proxy to track canvas calls.
394 var origFunc = Dygraph.getContext;
395 var miniHtx;
396 Dygraph.getContext = function(canvas) {
397 if (canvas.className != 'dygraph-rangesel-bgcanvas') {
398 return origFunc(canvas);
399 }
400 miniHtx = new Proxy(origFunc(canvas));
401 return miniHtx;
402 };
403
404 var opts = {
405 width: 480,
406 height: 100,
407 xAxisHeight: 30,
bfb3e0a4 408 axes : { x : { drawAxis: false }},
b1a96215
DV
409 showRangeSelector: true,
410 rangeSelectorHeight: 30,
411 rangeSelectorPlotStrokeColor: '#ff0000',
412 labels: ['X', 'Y']
413 };
414 var data = [
415 [0, 1],
416 [5, 4],
417 [10, 8]
418 ];
419 var graph = document.getElementById("graph");
420 var g = new Dygraph(graph, data, opts);
421
422 // TODO(danvk): more precise tests.
89fdcedb
DV
423 assert.isNotNull(miniHtx);
424 assert.isTrue(0 < CanvasAssertions.numLinesDrawn(miniHtx, '#ff0000'));
b1a96215
DV
425
426 Dygraph.getContext = origFunc;
89fdcedb 427});
b1a96215
DV
428
429// Tests data computation for the mini plot with a single series.
89fdcedb 430it('testSingleCombinedSeries', function() {
b1a96215
DV
431 var opts = {
432 showRangeSelector: true,
433 labels: ['X', 'Y1']
434 };
435 var data = [
436 [0, 1],
437 [5, 4],
438 [10, 8]
439 ];
440 var graph = document.getElementById("graph");
441 var g = new Dygraph(graph, data, opts);
442
443 var rangeSelector = g.getPluginInstance_(Dygraph.Plugins.RangeSelector);
89fdcedb 444 assert.isNotNull(rangeSelector);
b1a96215
DV
445
446 var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
89fdcedb 447 assert.deepEqual({
b1a96215
DV
448 yMin: 1 - 7 * 0.25, // 25% padding
449 yMax: 8 + 7 * 0.25,
450 data: [
451 [0, 1],
452 [5, 4],
453 [10, 8]
454 ]
455 }, combinedSeries);
89fdcedb 456});
b1a96215
DV
457
458
459// Tests that multiple series are averaged for the miniplot.
89fdcedb 460it('testCombinedSeries', function() {
b1a96215
DV
461 var opts = {
462 showRangeSelector: true,
463 labels: ['X', 'Y1', 'Y2']
464 };
465 var data = [
466 [0, 1, 3], // average = 2
467 [5, 4, 6], // average = 5
468 [10, 7, 9] // average = 8
469 ];
470 var graph = document.getElementById("graph");
471 var g = new Dygraph(graph, data, opts);
472
473 var rangeSelector = g.getPluginInstance_(Dygraph.Plugins.RangeSelector);
89fdcedb 474 assert.isNotNull(rangeSelector);
b1a96215
DV
475
476 var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
89fdcedb 477 assert.deepEqual({
b1a96215
DV
478 yMin: 2 - 6 * 0.25, // 25% padding on combined series range.
479 yMax: 8 + 6 * 0.25,
480 data: [
481 [0, 2],
482 [5, 5],
483 [10, 8]
484 ]
485 }, combinedSeries);
89fdcedb 486});
b1a96215 487
1085dbce 488// Tests selection of a specific series to average for the mini plot.
89fdcedb 489it('testSelectedCombinedSeries', function() {
1085dbce
PP
490 var opts = {
491 showRangeSelector: true,
0a0885d1
DV
492 labels: ['X', 'Y1', 'Y2', 'Y3', 'Y4'],
493 series: {
494 'Y1': { showInRangeSelector: true },
495 'Y3': { showInRangeSelector: true }
496 }
1085dbce
PP
497 };
498 var data = [
499 [0, 5, 8, 13, 21], // average (first and third) = 9
500 [5, 1, 3, 7, 14], // average (first and third) = 4
501 [10, 0, 19, 10, 6] // average (first and third) = 5
502 ];
503 var graph = document.getElementById("graph");
504 var g = new Dygraph(graph, data, opts);
505
506 var rangeSelector = g.getPluginInstance_(Dygraph.Plugins.RangeSelector);
89fdcedb 507 assert.isNotNull(rangeSelector);
1085dbce
PP
508
509 var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
89fdcedb 510 assert.deepEqual({
1085dbce
PP
511 yMin: 4 - 5 * 0.25, // 25% padding on combined series range.
512 yMax: 9 + 5 * 0.25,
513 data: [
514 [0, 9],
515 [5, 4],
516 [10, 5]
517 ]
518 }, combinedSeries);
89fdcedb 519});
1085dbce 520
b1a96215 521// Tests data computation for the mini plot with a single error bar series.
89fdcedb 522it('testSingleCombinedSeriesCustomBars', function() {
b1a96215
DV
523 var opts = {
524 customBars: true,
525 showRangeSelector: true,
526 labels: ['X', 'Y1']
527 };
528 var data = [
529 [0, [0, 1, 2]], // [low, value, high]
530 [5, [1, 4, 5]],
531 [10, [7, 8, 9]]
532 ];
533 var graph = document.getElementById("graph");
534 var g = new Dygraph(graph, data, opts);
535
536 var rangeSelector = g.getPluginInstance_(Dygraph.Plugins.RangeSelector);
89fdcedb 537 assert.isNotNull(rangeSelector);
b1a96215
DV
538
539 var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
89fdcedb 540 assert.deepEqual({
b1a96215
DV
541 yMin: 1 - 7 * 0.25, // 25% padding
542 yMax: 8 + 7 * 0.25,
543 data: [
544 [0, 1],
545 [5, 4],
546 [10, 8]
547 ]
548 }, combinedSeries);
89fdcedb 549});
b1a96215 550
89fdcedb 551it('testSingleCombinedSeriesErrorBars', function() {
b1a96215
DV
552 var opts = {
553 errorBars: true,
554 showRangeSelector: true,
555 labels: ['X', 'Y1']
556 };
557 var data = [
558 [0, [1, 1]], // [value, standard deviation]
559 [5, [4, 2]],
560 [10, [8, 1]]
561 ];
562 var graph = document.getElementById("graph");
563 var g = new Dygraph(graph, data, opts);
564
565 var rangeSelector = g.getPluginInstance_(Dygraph.Plugins.RangeSelector);
89fdcedb 566 assert.isNotNull(rangeSelector);
b1a96215
DV
567
568 var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
89fdcedb 569 assert.deepEqual({
b1a96215
DV
570 yMin: 1 - 7 * 0.25, // 25% padding
571 yMax: 8 + 7 * 0.25,
572 data: [
573 [0, 1],
574 [5, 4],
575 [10, 8]
576 ]
577 }, combinedSeries);
89fdcedb 578});
b1a96215
DV
579
580// Tests data computation for the mini plot with two custom bar series.
89fdcedb 581it('testTwoCombinedSeriesCustomBars', function() {
b1a96215
DV
582 var opts = {
583 customBars: true,
584 showRangeSelector: true,
585 labels: ['X', 'Y1', 'Y2']
586 };
587 var data = [
588 [0, [0, 1, 2], [4, 5, 6]], // [low, value, high], avg_val = 3
589 [5, [1, 4, 5], [5, 8, 9]], // avg_val = 6
590 [10, [7, 8, 9], [11, 12, 13]] // avg_val = 10
591 ];
592 var graph = document.getElementById("graph");
593 var g = new Dygraph(graph, data, opts);
594
595 var rangeSelector = g.getPluginInstance_(Dygraph.Plugins.RangeSelector);
89fdcedb 596 assert.isNotNull(rangeSelector);
b1a96215
DV
597
598 var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
89fdcedb 599 assert.deepEqual({
b1a96215
DV
600 yMin: 3 - 7 * 0.25, // 25% padding
601 yMax: 10 + 7 * 0.25,
602 data: [
603 [0, 3],
604 [5, 6],
605 [10, 10]
606 ]
607 }, combinedSeries);
89fdcedb 608});
b1a96215
DV
609
610
319d0361 611var assertGraphExistence = function(g, graph) {
89fdcedb 612 assert.isNotNull(g);
88c4a47e 613 var zoomhandles = graph.getElementsByClassName('dygraph-rangesel-zoomhandle');
89fdcedb 614 assert.equal(2, zoomhandles.length);
88c4a47e 615 var bgcanvas = graph.getElementsByClassName('dygraph-rangesel-bgcanvas');
89fdcedb 616 assert.equal(1, bgcanvas.length);
88c4a47e 617 var fgcanvas = graph.getElementsByClassName('dygraph-rangesel-fgcanvas');
89fdcedb 618 assert.equal(1, fgcanvas.length);
319d0361 619};
89fdcedb
DV
620
621});