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