Merge pull request #271 from danvk/connect-separated-points
[dygraphs.git] / auto_tests / tests / range_tests.js
CommitLineData
718ad8e2 1// Copyright (c) 2011 Google, Inc.
72a74f04
RK
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19// THE SOFTWARE.
20
21
22/**
23 * @fileoverview Test valueRange and dateWindow changes.
24 *
25 * @author konigsberg@google.com (Robert Konigsberg)
26 */
27var ZERO_TO_FIFTY = [[ 10, 0 ] , [ 20, 50 ]];
28var ZERO_TO_FIFTY_STEPS = function() {
29 var a = [];
30 var x = 10;
31 var y = 0;
32 var step = 0;
33 for (step = 0; step <= 50; step++) {
34 a.push([x + (step * .2), y + step]);
35 }
36 return a;
37} ();
b0d3471d
RK
38var FIVE_TO_ONE_THOUSAND = [
39 [ 1, 10 ], [ 2, 20 ], [ 3, 30 ], [ 4, 40 ] , [ 5, 50 ],
40 [ 6, 60 ], [ 7, 70 ], [ 8, 80 ], [ 9, 90 ] , [ 10, 1000 ]];
72a74f04
RK
41
42var RangeTestCase = TestCase("range-tests");
43
44RangeTestCase.prototype.setUp = function() {
45 document.body.innerHTML = "<div id='graph'></div>";
46};
47
fa460473
KW
48RangeTestCase.prototype.createGraph = function(opts, data, expectRangeX, expectRangeY) {
49 if (data === undefined) data = ZERO_TO_FIFTY_STEPS;
50 if (expectRangeX === undefined) expectRangeX = [10, 20];
51 if (expectRangeY === undefined) expectRangeY = [0, 55];
72a74f04 52 var graph = document.getElementById("graph");
fa460473 53 var g = new Dygraph(graph, data, opts);
72a74f04 54
fa460473
KW
55 assertEqualsDelta(expectRangeX, g.xAxisRange(), 0.01);
56 assertEqualsDelta(expectRangeY, g.yAxisRange(0), 0.01);
72a74f04
RK
57
58 return g;
59};
60
61/**
62 * Test that changes to valueRange and dateWindow are reflected
63 * appropriately.
64 */
65RangeTestCase.prototype.testRangeSetOperations = function() {
66 var g = this.createGraph({valueRange : [ 0, 55 ]});
67
68 g.updateOptions({ dateWindow : [ 12, 18 ] });
69 assertEquals([12, 18], g.xAxisRange());
70 assertEquals([0, 55], g.yAxisRange(0));
71
72 g.updateOptions({ valueRange : [ 10, 40 ] });
73 assertEquals([12, 18], g.xAxisRange());
74 assertEquals([10, 40], g.yAxisRange(0));
75
e4ddb639 76 g.updateOptions({ valueRange: [10, NaN] });
77 assertEquals([12, 18], g.xAxisRange());
78 assertEquals([10, 44.2], g.yAxisRange(0));
79
80 g.updateOptions({ valueRange: [10, 40] });
81 assertEquals([12, 18], g.xAxisRange());
82 assertEquals([10, 40], g.yAxisRange(0));
83
30aae41c 84 g.updateOptions({ valueRange: [10, null] });
85 assertEquals([12, 18], g.xAxisRange());
86 assertEquals([10, 44.2], g.yAxisRange(0));
87
88 g.updateOptions({ valueRange: [10, 40] });
89 assertEquals([12, 18], g.xAxisRange());
90 assertEquals([10, 40], g.yAxisRange(0));
91
92 g.updateOptions({ valueRange: [10, undefined] });
93 assertEquals([12, 18], g.xAxisRange());
94 assertEquals([10, 44.2], g.yAxisRange(0));
95
96 g.updateOptions({ valueRange: [10, 40] });
97 assertEquals([12, 18], g.xAxisRange());
98 assertEquals([10, 40], g.yAxisRange(0));
99
72a74f04
RK
100 g.updateOptions({ });
101 assertEquals([12, 18], g.xAxisRange());
102 assertEquals([10, 40], g.yAxisRange(0));
4dd0ac55
RV
103
104 g.updateOptions({valueRange : null, axes: {y:{valueRange : [15, 20]}}});
105 assertEquals([12, 18], g.xAxisRange());
106 assertEquals([15, 20], g.yAxisRange(0));
72a74f04 107
4dd0ac55 108 g.updateOptions({ dateWindow : null, valueRange : null, axes: null });
72a74f04
RK
109 assertEquals([10, 20], g.xAxisRange());
110 assertEquals([0, 55], g.yAxisRange(0));
111};
112
113/**
114 * Verify that when zoomed in by mouse operations, an empty call to
115 * updateOptions doesn't change the displayed ranges.
116 */
117RangeTestCase.prototype.zoom = function(g, xRange, yRange) {
118 var originalXRange = g.xAxisRange();
119 var originalYRange = g.yAxisRange(0);
120
a12f271c 121 DygraphOps.dispatchMouseDown(g, xRange[0], yRange[0]);
72a74f04
RK
122 DygraphOps.dispatchMouseMove(g, xRange[1], yRange[0]); // this is really necessary.
123 DygraphOps.dispatchMouseUp(g, xRange[1], yRange[0]);
124
125 assertEqualsDelta(xRange, g.xAxisRange(), 0.2);
126 // assertEqualsDelta(originalYRange, g.yAxisRange(0), 0.2); // Not true, it's something in the middle.
127
128 var midX = (xRange[1] - xRange[0]) / 2;
a12f271c 129 DygraphOps.dispatchMouseDown(g, midX, yRange[0]);
72a74f04
RK
130 DygraphOps.dispatchMouseMove(g, midX, yRange[1]); // this is really necessary.
131 DygraphOps.dispatchMouseUp(g, midX, yRange[1]);
132
133 assertEqualsDelta(xRange, g.xAxisRange(), 0.2);
134 assertEqualsDelta(yRange, g.yAxisRange(0), 0.2);
135}
136
137
138/**
139 * Verify that when zoomed in by mouse operations, an empty call to
140 * updateOptions doesn't change the displayed ranges.
141 */
142RangeTestCase.prototype.testEmptyUpdateOptions_doesntUnzoom = function() {
143 var g = this.createGraph();
144 this.zoom(g, [ 11, 18 ], [ 35, 40 ]);
145
a12f271c
RK
146 assertEqualsDelta([11, 18], g.xAxisRange(), 0.1);
147 assertEqualsDelta([35, 40], g.yAxisRange(0), 0.2);
148
72a74f04
RK
149 g.updateOptions({});
150
151 assertEqualsDelta([11, 18], g.xAxisRange(), 0.1);
d64b8fea 152 assertEqualsDelta([35, 40], g.yAxisRange(0), 0.2);
72a74f04
RK
153}
154
155/**
156 * Verify that when zoomed in by mouse operations, a call to
157 * updateOptions({ dateWindow : null, valueRange : null }) fully
158 * unzooms.
159 */
160RangeTestCase.prototype.testRestoreOriginalRanges_viaUpdateOptions = function() {
161 var g = this.createGraph();
162 this.zoom(g, [ 11, 18 ], [ 35, 40 ]);
163
164 g.updateOptions({ dateWindow : null, valueRange : null });
165
166 assertEquals([0, 55], g.yAxisRange(0));
167 assertEquals([10, 20], g.xAxisRange());
168}
b0d3471d
RK
169
170/**
171 * Verify that log scale axis range is properly specified.
172 */
173RangeTestCase.prototype.testLogScaleExcludesZero = function() {
174 var g = new Dygraph("graph", FIVE_TO_ONE_THOUSAND, { logscale : true });
175 assertEquals([10, 1099], g.yAxisRange(0));
176
177 g.updateOptions({ logscale : false });
178 assertEquals([0, 1099], g.yAxisRange(0));
179}
478b866b
RK
180
181/**
182 * Verify that includeZero range is properly specified.
183 */
184RangeTestCase.prototype.testIncludeZeroIncludesZero = function() {
185 var g = new Dygraph("graph", [[0, 500], [500, 1000]], { includeZero : true });
186 assertEquals([0, 1100], g.yAxisRange(0));
187
188 g.updateOptions({ includeZero : false });
189 assertEquals([450, 1050], g.yAxisRange(0));
190}
fa0d7ad8 191
c387c823 192
193/**
194 * Verify that includeZero range is properly specified per axis.
195 */
196RangeTestCase.prototype.testIncludeZeroPerAxis = function() {
197 var g = new Dygraph("graph",
198 'X,A,B\n'+
199 '0,50,50\n'+
200 '50,110,110\n',
201 {
202 drawPoints: true,
203 pointSize:5,
204 series:{
205 A: {
206 axis: 'y',
207 pointSize: 10
208 },
209 B: {
210 axis: 'y2'
211 }
212 },
213 axes: {
214 'y2': { includeZero: true }
215 }
216 });
217
218
219 assertEquals([44, 116], g.yAxisRange(0));
220 assertEquals([0, 121], g.yAxisRange(1));
221
222 g.updateOptions({
223 axes: {
224 'y2': { includeZero: false }
225 }
226 });
227
228 assertEquals([44, 116], g.yAxisRange(1));
229}
230
231
232/**
233 * Verify that includeZero range is properly specified per axis with old axis options.
234 */
235RangeTestCase.prototype.testIncludeZeroPerAxisOld = function() {
236 var g = new Dygraph("graph",
237 'X,A,B\n' +
238 '0,50,50\n' +
239 '50,110,110\n',
240 {
241 drawPoints: true,
242 pointSize: 5,
243
244 A: {
245 pointSize: 10
246 },
247 B: {
248 axis: {}
249 },
250 axes: {
251 'y': { includeZero: true },
252 'y2': { includeZero: false }
253 }
254 });
255
256 assertEquals([0, 121], g.yAxisRange(0));
257 assertEquals([44, 116], g.yAxisRange(1));
258
259 g.updateOptions({
260 axes: {
261 'y': { includeZero: false },
262 'y2': { includeZero: true }
263 }
264 });
265
266 assertEquals([44, 116], g.yAxisRange(0));
267 assertEquals([0, 121], g.yAxisRange(1));
268}
269
fa0d7ad8
KW
270/**
271 * Verify that very large Y ranges don't break things.
272 */
273RangeTestCase.prototype.testHugeRange = function() {
274 var g = new Dygraph("graph", [[0, -1e120], [1, 1e230]], { includeZero : true });
275 assertEqualsDelta(1, -1e229 / g.yAxisRange(0)[0], 0.001);
276 assertEqualsDelta(1, 1.1e230 / g.yAxisRange(0)[1], 0.001);
277}
fa460473
KW
278
279/**
280 * Verify old-style avoidMinZero option.
281 */
282RangeTestCase.prototype.testAvoidMinZero = function() {
283 var g = this.createGraph({
284 avoidMinZero: true,
285 }, ZERO_TO_FIFTY_STEPS, [10, 20], [-5, 55]);
286};
287
288/**
289 * Verify ranges with user-specified padding, implicit avoidMinZero.
290 */
291RangeTestCase.prototype.testPaddingAuto = function() {
292 var g = this.createGraph({
293 xRangePad: 42,
294 yRangePad: 30
295 }, ZERO_TO_FIFTY_STEPS, [9, 21], [-5, 55]);
296};
297
298/**
299 * Verify auto range with drawAxesAtZero.
300 */
301RangeTestCase.prototype.testPaddingAutoAxisAtZero = function() {
302 var g = this.createGraph({
303 drawAxesAtZero: true,
304 }, ZERO_TO_FIFTY_STEPS, [10, 20], [0, 55]);
305};
306
307/**
308 * Verify user-specified range with padding and drawAxesAtZero options.
309 * Try explicit range matching the auto range, should have identical results.
310 */
311RangeTestCase.prototype.testPaddingRange1 = function() {
312 var g = this.createGraph({
313 valueRange: [0, 50],
314 xRangePad: 42,
315 yRangePad: 30,
316 drawAxesAtZero: true
317 }, ZERO_TO_FIFTY_STEPS, [9, 21], [-5, 55]);
318};
319
320/**
321 * Verify user-specified range with padding and drawAxesAtZero options.
322 * User-supplied range differs from the auto range.
323 */
324RangeTestCase.prototype.testPaddingRange2 = function() {
325 var g = this.createGraph({
326 valueRange: [10, 60],
327 xRangePad: 42,
328 yRangePad: 30,
329 drawAxesAtZero: true,
330 }, ZERO_TO_FIFTY_STEPS, [9, 21], [5, 65]);
331};
332
333/**
334 * Verify drawAxesAtZero and includeZero.
335 */
336RangeTestCase.prototype.testPaddingYAtZero = function() {
337 var g = this.createGraph({
338 includeZero: true,
339 xRangePad: 42,
340 yRangePad: 30,
341 drawAxesAtZero: true,
342 }, [
343 [-10, 10],
344 [10, 20],
345 [30, 50]
346 ], [-14, 34], [-5, 55]);
347};
348
349/**
350 * Verify logscale, compat mode.
351 */
352RangeTestCase.prototype.testLogscaleCompat = function() {
353 var g = this.createGraph({
354 logscale: true
355 },
356 [[-10, 10], [10, 10], [30, 1000]],
357 [-10, 30], [10, 1099]);
358};
359
360/**
361 * Verify logscale, new mode.
362 */
363RangeTestCase.prototype.testLogscalePad = function() {
364 var g = this.createGraph({
365 logscale: true,
366 yRangePad: 30
367 },
368 [[-10, 10], [10, 10], [30, 1000]],
369 [-10, 30], [5.01691, 1993.25801]);
370};
ccecde93
KW
371
372/**
373 * Verify scrolling all-zero region, traditional.
374 */
375RangeTestCase.prototype.testZeroScroll = function() {
376 g = new Dygraph(
377 document.getElementById("graph"),
378 "X,Y\n" +
379 "1,0\n" +
380 "8,0\n" +
381 "9,0.1\n",
382 {
383 drawAxesAtZero: true,
384 animatedZooms: true,
385 avoidMinZero: true
386 });
387};
388
389/**
390 * Verify scrolling all-zero region, new-style.
391 */
392RangeTestCase.prototype.testZeroScroll2 = function() {
393 g = new Dygraph(
394 document.getElementById("graph"),
395 "X,Y\n" +
396 "1,0\n" +
397 "8,0\n" +
398 "9,0.1\n",
399 {
400 animatedZooms: true,
401 drawAxesAtZero: true,
402 xRangePad: 4,
403 yRangePad: 4
404 });
405};