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