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