13de031d87974ea747f2ed4307e9255546850ef9
[dygraphs.git] / auto_tests / tests / axis_labels.js
1 /**
2 * @fileoverview Test cases for how axis labels are chosen and formatted.
3 *
4 * @author dan@dygraphs.com (Dan Vanderkam)
5 */
6 var AxisLabelsTestCase = TestCase("axis-labels");
7
8 AxisLabelsTestCase.prototype.setUp = function() {
9 document.body.innerHTML = "<div id='graph'></div>";
10 };
11
12 AxisLabelsTestCase.prototype.tearDown = function() {
13 };
14
15 AxisLabelsTestCase.simpleData =
16 "X,Y,Y2\n" +
17 "0,-1,.5\n" +
18 "1,0,.7\n" +
19 "2,1,.4\n" +
20 "3,0,.98\n";
21
22 AxisLabelsTestCase.prototype.kCloseFloat = 1.0e-10;
23
24 AxisLabelsTestCase.prototype.testMinusOneToOne = function() {
25 var opts = {
26 width: 480,
27 height: 320
28 };
29 var data = "X,Y\n" +
30 "0,-1\n" +
31 "1,0\n" +
32 "2,1\n" +
33 "3,0\n"
34 ;
35
36 var graph = document.getElementById("graph");
37 var g = new Dygraph(graph, data, opts);
38
39 // TODO(danvk): would ['-1.0','-0.5','0.0','0.5','1.0'] be better?
40 assertEquals(['-1','-0.5','0','0.5','1'], Util.getYLabels());
41
42 // Go up to 2
43 data += "4,2\n";
44 g.updateOptions({file: data});
45 assertEquals(['-1','-0.5','0','0.5','1','1.5','2'], Util.getYLabels());
46
47 // Now 10
48 data += "5,10\n";
49 g.updateOptions({file: data});
50 assertEquals(['-2','0','2','4','6','8','10'], Util.getYLabels());
51
52 // Now 100
53 data += "6,100\n";
54 g.updateOptions({file: data});
55 assertEquals(['0','20','40','60','80','100'], Util.getYLabels());
56
57 g.setSelection(0);
58 assertEquals('0: Y: -1', Util.getLegend());
59 };
60
61 AxisLabelsTestCase.prototype.testSmallRangeNearZero = function() {
62 var opts = {
63 drawAxesAtZero: true,
64 width: 480,
65 height: 320
66 };
67 var data = "X,Y\n" +
68 "0,-1\n" +
69 "1,0\n" +
70 "2,1\n" +
71 "3,0\n"
72 ;
73 opts.valueRange = [-0.1, 0.1];
74
75 var graph = document.getElementById("graph");
76 var g = new Dygraph(graph, data, opts);
77 assertEqualsDelta([-0.1,-0.05,0,0.05],
78 Util.makeNumbers(Util.getYLabels()), this.kCloseFloat);
79
80 opts.valueRange = [-0.05, 0.05];
81 g.updateOptions(opts);
82 assertEquals([-0.04,-0.02,0,0.02,0.04],
83 Util.makeNumbers(Util.getYLabels()));
84
85 opts.valueRange = [-0.01, 0.01];
86 g.updateOptions(opts);
87 assertEquals([-0.01,-0.005,0,0.005],
88 Util.makeNumbers(Util.getYLabels()));
89
90 g.setSelection(1);
91 assertEquals('1: Y: 0', Util.getLegend());
92 };
93
94 AxisLabelsTestCase.prototype.testSmallRangeAwayFromZero = function() {
95 var opts = {
96 width: 480,
97 height: 320
98 };
99 var data = "X,Y\n" +
100 "0,-1\n" +
101 "1,0\n" +
102 "2,1\n" +
103 "3,0\n"
104 ;
105 var graph = document.getElementById("graph");
106
107 opts.valueRange = [9.9, 10.1];
108 var g = new Dygraph(graph, data, opts);
109 assertEquals(["9.9","9.92","9.94","9.96","9.98","10","10.02","10.04","10.06","10.08"], Util.getYLabels());
110
111 opts.valueRange = [9.99, 10.01];
112 g.updateOptions(opts);
113 // TODO(danvk): this is bad
114 assertEquals(["9.99","9.99","9.99","10","10","10","10","10","10.01","10.01"], Util.getYLabels());
115
116 opts.valueRange = [9.999, 10.001];
117 g.updateOptions(opts);
118 // TODO(danvk): this is even worse!
119 assertEquals(["10","10","10","10"], Util.getYLabels());
120
121 g.setSelection(1);
122 assertEquals('1: Y: 0', Util.getLegend());
123 };
124
125 AxisLabelsTestCase.prototype.testXAxisTimeLabelFormatter = function() {
126 var opts = {
127 width: 480,
128 height: 320
129 };
130 var data = [[5.0,0],[5.1,1],[5.2,2],[5.3,3],[5.4,4],[5.5,5],[5.6,6],[5.7,7],[5.8,8],[5.9,9]];
131 var graph = document.getElementById("graph");
132 var g = new Dygraph(graph, data, opts);
133 g.updateOptions({
134 axes : {
135 x : {
136 axisLabelFormatter : function (totalMinutes) {
137 var hours = Math.floor( totalMinutes / 60);
138 var minutes = Math.floor((totalMinutes - (hours * 60)));
139 var seconds = Math.round((totalMinutes * 60) - (hours * 3600) - (minutes * 60));
140
141 if (hours < 10) hours = "0" + hours;
142 if (minutes < 10) minutes = "0" + minutes;
143 if (seconds < 10) seconds = "0" + seconds;
144
145 return hours + ':' + minutes + ':' + seconds;
146 }
147 }
148 }
149 });
150
151 assertEquals(["00:05:00","00:05:12","00:05:24","00:05:36","00:05:48"], Util.getXLabels());
152
153 // The legend does not use the axisLabelFormatter:
154 g.setSelection(1);
155 assertEquals('5.1: Y1: 1', Util.getLegend());
156 };
157
158 AxisLabelsTestCase.prototype.testAxisLabelFormatter = function () {
159 var opts = {
160 width: 480,
161 height: 320,
162 axes : {
163 x : {
164 axisLabelFormatter : function(x, granularity, opts, dg) {
165 assertEquals('number', typeof(x));
166 assertEquals('number', typeof(granularity));
167 assertEquals('function', typeof(opts));
168 assertEquals('[Dygraph graph]', dg.toString());
169 return 'x' + x;
170 }
171 },
172 y : {
173 axisLabelFormatter : function(y, granularity, opts, dg) {
174 assertEquals('number', typeof(y));
175 assertEquals('number', typeof(granularity));
176 assertEquals('function', typeof(opts));
177 assertEquals('[Dygraph graph]', dg.toString());
178 return 'y' + y;
179 }
180 }
181 },
182 labels: ['x', 'y']
183 };
184 var data = [];
185 for (var i = 0; i < 10; i++) {
186 data.push([i, 2 * i]);
187 }
188 var graph = document.getElementById("graph");
189 var g = new Dygraph(graph, data, opts);
190
191 assertEquals(['x0','x2','x4','x6','x8'], Util.getXLabels());
192 assertEquals(["y0","y5","y10","y15"], Util.getYLabels());
193
194 g.setSelection(2);
195 assertEquals("2: y: 4", Util.getLegend());
196 };
197
198 AxisLabelsTestCase.prototype.testDateAxisLabelFormatter = function () {
199 var opts = {
200 width: 480,
201 height: 320,
202 axes : {
203 x : {
204 pixelsPerLabel: 60,
205 axisLabelFormatter : function(x, granularity, opts, dg) {
206 assertTrue(Dygraph.isDateLike(x));
207 assertEquals('number', typeof(granularity));
208 assertEquals('function', typeof(opts));
209 assertEquals('[Dygraph graph]', dg.toString());
210 return 'x' + Util.formatDate(x);
211 }
212 },
213 y : {
214 axisLabelFormatter : function(y, granularity, opts, dg) {
215 assertEquals('number', typeof(y));
216 assertEquals('number', typeof(granularity));
217 assertEquals('function', typeof(opts));
218 assertEquals('[Dygraph graph]', dg.toString());
219 return 'y' + y;
220 }
221 }
222 },
223 labels: ['x', 'y']
224 };
225 var data = [];
226 for (var i = 1; i < 10; i++) {
227 data.push([new Date("2011/01/0" + i), 2 * i]);
228 }
229 var graph = document.getElementById("graph");
230 var g = new Dygraph(graph, data, opts);
231
232 assertEquals(["x2011/01/02","x2011/01/04","x2011/01/06","x2011/01/08"], Util.getXLabels());
233 assertEquals(["y5","y10","y15"], Util.getYLabels());
234
235 g.setSelection(0);
236 assertEquals("2011/01/01: y: 2", Util.getLegend());
237 };
238
239 // This test verifies that when a valueFormatter is set (but not an
240 // axisLabelFormatter), then the valueFormatter is used to format the axis
241 // labels.
242 AxisLabelsTestCase.prototype.testValueFormatter = function () {
243 var opts = {
244 width: 480,
245 height: 320,
246 axes : {
247 x : {
248 valueFormatter: function(x, opts, series_name, dg) {
249 assertEquals('number', typeof(x));
250 assertEquals('function', typeof(opts));
251 assertEquals('string', typeof(series_name));
252 assertEquals('[Dygraph graph]', dg.toString());
253 return 'x' + x;
254 }
255 },
256 y : {
257 valueFormatter: function(y, opts, series_name, dg) {
258 assertEquals('number', typeof(y));
259 assertEquals('function', typeof(opts));
260 assertEquals('string', typeof(series_name));
261 assertEquals('[Dygraph graph]', dg.toString());
262 return 'y' + y;
263 }
264 }
265 },
266 labels: ['x', 'y']
267 };
268 var data = [];
269 for (var i = 0; i < 10; i++) {
270 data.push([i, 2 * i]);
271 }
272 var graph = document.getElementById("graph");
273 var g = new Dygraph(graph, data, opts);
274
275 // the valueFormatter options do not affect the ticks.
276 assertEquals(['0','2','4','6','8'], Util.getXLabels());
277 assertEquals(["0","5","10","15"],
278 Util.getYLabels());
279
280 // they do affect the legend, however.
281 g.setSelection(2);
282 assertEquals("x2: y: y4", Util.getLegend());
283 };
284
285 AxisLabelsTestCase.prototype.testDateValueFormatter = function () {
286 var opts = {
287 width: 480,
288 height: 320,
289 axes : {
290 x : {
291 pixelsPerLabel: 60,
292 valueFormatter: function(x, opts, series_name, dg) {
293 assertEquals('number', typeof(x));
294 assertEquals('function', typeof(opts));
295 assertEquals('string', typeof(series_name));
296 assertEquals('[Dygraph graph]', dg.toString());
297 return 'x' + Util.formatDate(x);
298 }
299 },
300 y : {
301 valueFormatter: function(y, opts, series_name, dg) {
302 assertEquals('number', typeof(y));
303 assertEquals('function', typeof(opts));
304 assertEquals('string', typeof(series_name));
305 assertEquals('[Dygraph graph]', dg.toString());
306 return 'y' + y;
307 }
308 }
309 },
310 labels: ['x', 'y']
311 };
312
313 var data = [];
314 for (var i = 1; i < 10; i++) {
315 data.push([new Date("2011/01/0" + i), 2 * i]);
316 }
317 var graph = document.getElementById("graph");
318 var g = new Dygraph(graph, data, opts);
319
320 // valueFormatters do not affect ticks.
321 assertEquals(["02 Jan","04 Jan","06 Jan","08 Jan"], Util.getXLabels());
322 assertEquals(["5","10","15"], Util.getYLabels());
323
324 // the valueFormatter options also affect the legend.
325 g.setSelection(2);
326 assertEquals('x2011/01/03: y: y6', Util.getLegend());
327 };
328
329 // This test verifies that when both a valueFormatter and an axisLabelFormatter
330 // are specified, the axisLabelFormatter takes precedence.
331 AxisLabelsTestCase.prototype.testAxisLabelFormatterPrecedence = function () {
332 var opts = {
333 width: 480,
334 height: 320,
335 axes : {
336 x : {
337 valueFormatter: function(x) {
338 return 'xvf' + x;
339 },
340 axisLabelFormatter: function(x, granularity) {
341 return 'x' + x;
342 }
343 },
344 y : {
345 valueFormatter: function(y) {
346 return 'yvf' + y;
347 },
348 axisLabelFormatter: function(y) {
349 return 'y' + y;
350 }
351 }
352 },
353 labels: ['x', 'y']
354 };
355 var data = [];
356 for (var i = 0; i < 10; i++) {
357 data.push([i, 2 * i]);
358 }
359 var graph = document.getElementById("graph");
360 var g = new Dygraph(graph, data, opts);
361
362 assertEquals(['x0','x2','x4','x6','x8'], Util.getXLabels());
363 assertEquals(["y0","y5","y10","y15"], Util.getYLabels());
364
365 g.setSelection(9);
366 assertEquals("xvf9: y: yvf18", Util.getLegend());
367 };
368
369 // This is the same as the previous test, except that options are added
370 // one-by-one.
371 AxisLabelsTestCase.prototype.testAxisLabelFormatterIncremental = function () {
372 var opts = {
373 width: 480,
374 height: 320,
375 labels: ['x', 'y']
376 };
377 var data = [];
378 for (var i = 0; i < 10; i++) {
379 data.push([i, 2 * i]);
380 }
381 var graph = document.getElementById("graph");
382 var g = new Dygraph(graph, data, opts);
383 g.updateOptions({
384 axes : {
385 x : {
386 valueFormatter: function(x) {
387 return 'xvf' + x;
388 }
389 }
390 }
391 });
392 g.updateOptions({
393 axes : {
394 y : {
395 valueFormatter: function(y) {
396 return 'yvf' + y;
397 }
398 }
399 }
400 });
401 g.updateOptions({
402 axes : {
403 x : {
404 axisLabelFormatter: function(x, granularity) {
405 return 'x' + x;
406 }
407 }
408 }
409 });
410 g.updateOptions({
411 axes : {
412 y : {
413 axisLabelFormatter: function(y) {
414 return 'y' + y;
415 }
416 }
417 }
418 });
419
420 assertEquals(["x0","x2","x4","x6","x8"], Util.getXLabels());
421 assertEquals(["y0","y5","y10","y15"], Util.getYLabels());
422
423 g.setSelection(9);
424 assertEquals("xvf9: y: yvf18", Util.getLegend());
425 };
426
427 AxisLabelsTestCase.prototype.testGlobalFormatters = function() {
428 var opts = {
429 width: 480,
430 height: 320,
431 labels: ['x', 'y'],
432 valueFormatter: function(x) {
433 return 'vf' + x;
434 },
435 axisLabelFormatter: function(x) {
436 return 'alf' + x;
437 }
438 };
439 var data = [];
440 for (var i = 0; i < 10; i++) {
441 data.push([i, 2 * i]);
442 }
443 var graph = document.getElementById("graph");
444 var g = new Dygraph(graph, data, opts);
445
446 assertEquals(['alf0','alf2','alf4','alf6','alf8'], Util.getXLabels());
447 assertEquals(["alf0","alf5","alf10","alf15"], Util.getYLabels());
448
449 g.setSelection(9);
450 assertEquals("vf9: y: vf18", Util.getLegend());
451 };
452
453 AxisLabelsTestCase.prototype.testSeriesOrder = function() {
454 var opts = {
455 width: 480,
456 height: 320
457 };
458 var data = "x,00,01,10,11\n" +
459 "0,101,201,301,401\n" +
460 "1,102,202,302,402\n" +
461 "2,103,203,303,403\n" +
462 "3,104,204,304,404\n"
463 ;
464
465 var graph = document.getElementById("graph");
466 var g = new Dygraph(graph, data, opts);
467
468 g.setSelection(2);
469 assertEquals('2: 00: 103 01: 203 10: 303 11: 403', Util.getLegend());
470
471 // Sanity checks for indexFromSetName
472 assertEquals(0, g.indexFromSetName("x"));
473 assertEquals(1, g.indexFromSetName("00"));
474 assertEquals(null, g.indexFromSetName("abcde"));
475
476 // Verify that we get the label list back in the right order
477 assertEquals(["x", "00", "01", "10", "11"], g.getLabels());
478 };
479
480 AxisLabelsTestCase.prototype.testLabelKMB = function() {
481 var data = [];
482 data.push([0,0]);
483 data.push([1,2000]);
484 data.push([2,1000]);
485
486 var g = new Dygraph(
487 document.getElementById("graph"),
488 data,
489 {
490 labels: [ 'X', 'bar' ],
491 axes : {
492 y: {
493 labelsKMB: true
494 }
495 }
496 }
497 );
498
499 assertEquals(["0", "500", "1K", "1.5K", "2K"], Util.getYLabels());
500 };
501
502 AxisLabelsTestCase.prototype.testLabelKMG2 = function() {
503 var data = [];
504 data.push([0,0]);
505 data.push([1,2000]);
506 data.push([2,1000]);
507
508 var g = new Dygraph(
509 document.getElementById("graph"),
510 data,
511 {
512 labels: [ 'X', 'bar' ],
513 axes : {
514 y: {
515 labelsKMG2: true
516 }
517 }
518 }
519 );
520
521 assertEquals(
522 ["0","256","512","768","1k","1.25k","1.5k","1.75k","2k"],
523 Util.getYLabels());
524 };
525
526 // Same as testLabelKMG2 but specifies the option at the
527 // top of the option dictionary.
528 AxisLabelsTestCase.prototype.testLabelKMG2_top = function() {
529 var data = [];
530 data.push([0,0]);
531 data.push([1,2000]);
532 data.push([2,1000]);
533
534 var g = new Dygraph(
535 document.getElementById("graph"),
536 data,
537 {
538 labels: [ 'X', 'bar' ],
539 labelsKMG2: true
540 }
541 );
542
543 assertEquals(
544 ["0","256","512","768","1k","1.25k","1.5k","1.75k","2k"],
545 Util.getYLabels());
546 };
547
548 /**
549 * Verify that log scale axis range is properly specified.
550 */
551 AxisLabelsTestCase.prototype.testLogScale = function() {
552 var g = new Dygraph("graph", [[0, 5], [1, 1000]], { logscale : true });
553 var nonEmptyLabels = Util.getYLabels().filter(function(x) { return x.length > 0; });
554 assertEquals(["5","10","20","50","100","200","500","1000"], nonEmptyLabels);
555
556 g.updateOptions({ logscale : false });
557 assertEquals(['0','200','400','600','800','1000'], Util.getYLabels());
558 }
559
560 /**
561 * Verify that include zero range is properly specified.
562 */
563 AxisLabelsTestCase.prototype.testIncludeZero = function() {
564 var g = new Dygraph("graph", [[0, 500], [1, 1000]], { includeZero : true });
565 assertEquals(['0','200','400','600','800','1000'], Util.getYLabels());
566
567 g.updateOptions({ includeZero : false });
568 assertEquals(['500','600','700','800','900','1000'], Util.getYLabels());
569 }
570
571 AxisLabelsTestCase.prototype.testAxisLabelFontSize = function() {
572 var graph = document.getElementById("graph");
573 var g = new Dygraph(graph, AxisLabelsTestCase.simpleData, {});
574
575 // Be sure we're dealing with a 14-point default.
576 assertEquals(14, Dygraph.DEFAULT_ATTRS.axisLabelFontSize);
577
578 var assertFontSize = function(selector, expected) {
579 Util.assertStyleOfChildren(selector, "font-size", expected);
580 }
581
582 assertFontSize($(".dygraph-axis-label-x"), "14px");
583 assertFontSize($(".dygraph-axis-label-y") , "14px");
584
585 g.updateOptions({ axisLabelFontSize : 8});
586 assertFontSize($(".dygraph-axis-label-x"), "8px");
587 assertFontSize($(".dygraph-axis-label-y"), "8px");
588
589 g.updateOptions({
590 axisLabelFontSize : null,
591 axes : {
592 x : { axisLabelFontSize : 5 },
593 }
594 });
595
596 assertFontSize($(".dygraph-axis-label-x"), "5px");
597 assertFontSize($(".dygraph-axis-label-y"), "14px");
598
599 g.updateOptions({
600 axes : {
601 y : { axisLabelFontSize : 20 },
602 }
603 });
604
605 assertFontSize($(".dygraph-axis-label-x"), "5px");
606 assertFontSize($(".dygraph-axis-label-y"), "20px");
607
608 g.updateOptions({
609 series : {
610 Y2 : { axis : "y2" } // copy y2 series to y2 axis.
611 },
612 axes : {
613 y2 : { axisLabelFontSize : 12 },
614 }
615 });
616
617 assertFontSize($(".dygraph-axis-label-x"), "5px");
618 assertFontSize($(".dygraph-axis-label-y1"), "20px");
619 assertFontSize($(".dygraph-axis-label-y2"), "12px");
620 }
621
622 AxisLabelsTestCase.prototype.testAxisLabelFontSizeNull = function() {
623 var graph = document.getElementById("graph");
624 var g = new Dygraph(graph, AxisLabelsTestCase.simpleData,
625 {
626 axisLabelFontSize: null
627 });
628
629 var assertFontSize = function(selector, expected) {
630 Util.assertStyleOfChildren(selector, "font-size", expected);
631 };
632
633 // Be sure we're dealing with a 14-point default.
634 assertEquals(14, Dygraph.DEFAULT_ATTRS.axisLabelFontSize);
635
636 assertFontSize($(".dygraph-axis-label-x"), "14px");
637 assertFontSize($(".dygraph-axis-label-y"), "14px");
638 }
639
640 AxisLabelsTestCase.prototype.testAxisLabelColor = function() {
641 var graph = document.getElementById("graph");
642 var g = new Dygraph(graph, AxisLabelsTestCase.simpleData, {});
643
644 // Be sure we're dealing with a black default.
645 assertEquals("black", Dygraph.DEFAULT_ATTRS.axisLabelColor);
646
647 var assertColor = function(selector, expected) {
648 Util.assertStyleOfChildren(selector, "color", expected);
649 }
650
651 assertColor($(".dygraph-axis-label-x"), "rgb(0, 0, 0)");
652 assertColor($(".dygraph-axis-label-y"), "rgb(0, 0, 0)");
653
654 g.updateOptions({ axisLabelColor : "red"});
655 assertColor($(".dygraph-axis-label-x"), "rgb(255, 0, 0)");
656 assertColor($(".dygraph-axis-label-y"), "rgb(255, 0, 0)");
657
658 g.updateOptions({
659 axisLabelColor : null,
660 axes : {
661 x : { axisLabelColor : "blue" },
662 }
663 });
664
665 assertColor($(".dygraph-axis-label-x"), "rgb(0, 0, 255)");
666 assertColor($(".dygraph-axis-label-y"), "rgb(0, 0, 0)");
667
668 g.updateOptions({
669 axes : {
670 y : { axisLabelColor : "green" },
671 }
672 });
673
674 assertColor($(".dygraph-axis-label-x"), "rgb(0, 0, 255)");
675 assertColor($(".dygraph-axis-label-y"), "rgb(0, 128, 0)");
676
677 g.updateOptions({
678 series : {
679 Y2 : { axis : "y2" } // copy y2 series to y2 axis.
680 },
681 axes : {
682 y2 : { axisLabelColor : "yellow" },
683 }
684 });
685
686 assertColor($(".dygraph-axis-label-x"), "rgb(0, 0, 255)");
687 assertColor($(".dygraph-axis-label-y1"), "rgb(0, 128, 0)");
688 assertColor($(".dygraph-axis-label-y2"), "rgb(255, 255, 0)");
689 }
690
691 AxisLabelsTestCase.prototype.testAxisLabelColorNull = function() {
692 var graph = document.getElementById("graph");
693 var g = new Dygraph(graph, AxisLabelsTestCase.simpleData,
694 {
695 axisLabelColor: null
696 });
697
698 var assertColor = function(selector, expected) {
699 Util.assertStyleOfChildren(selector, "color", expected);
700 }
701
702 // Be sure we're dealing with a 14-point default.
703 assertEquals(14, Dygraph.DEFAULT_ATTRS.axisLabelFontSize);
704
705 assertColor($(".dygraph-axis-label-x"), "rgb(0, 0, 0)");
706 assertColor($(".dygraph-axis-label-y"), "rgb(0, 0, 0)");
707 }
708
709 /*
710 * This test shows that the label formatter overrides labelsKMB for all values.
711 */
712 AxisLabelsTestCase.prototype.testLabelFormatterOverridesLabelsKMB = function() {
713 var g = new Dygraph(
714 document.getElementById("graph"),
715 "X,a,b\n" +
716 "1,0,2000\n" +
717 "2,500,1500\n" +
718 "3,1000,1000\n" +
719 "4,2000,0\n", {
720 labelsKMB: true,
721 axisLabelFormatter: function (v) {
722 return v + ":X";
723 }
724 });
725 assertEquals(["0:X","500:X","1000:X","1500:X","2000:X"], Util.getYLabels());
726 assertEquals(["1:X","2:X","3:X"], Util.getXLabels());
727 }
728
729 /*
730 * This test shows that you can override labelsKMB on the axis level.
731 */
732 AxisLabelsTestCase.prototype.testLabelsKMBPerAxis = function() {
733 var g = new Dygraph(
734 document.getElementById("graph"),
735 "x,a,b\n" +
736 "1000,0,2000\n" +
737 "2000,500,1500\n" +
738 "3000,1000,1000\n" +
739 "4000,2000,0\n", {
740 labelsKMB: false,
741 axes: {
742 y2: { labelsKMB: true },
743 x: { labelsKMB: true }
744 },
745 series: {
746 b: { axis: "y2" }
747 }
748 });
749
750 // labelsKMB doesn't apply to the x axis. This value should be different.
751 // BUG : https://code.google.com/p/dygraphs/issues/detail?id=488
752 assertEquals(["1000","2000","3000"], Util.getXLabels());
753 assertEquals( ["0","500","1000","1500","2000"], Util.getYLabels(1));
754 assertEquals(["0","500","1K","1.5K","2K"], Util.getYLabels(2));
755 };
756
757 /*
758 * This test shows that you can override labelsKMG2 on the axis level.
759 */
760 AxisLabelsTestCase.prototype.testLabelsKMBG2IPerAxis = function() {
761 var g = new Dygraph(
762 document.getElementById("graph"),
763 "x,a,b\n" +
764 "1000,0,2000\n" +
765 "2000,500,1500\n" +
766 "3000,1000,1000\n" +
767 "4000,2000,0\n", {
768 labelsKMG2: false,
769 axes: {
770 y2: { labelsKMG2: true },
771 x: { labelsKMG2: true, pixelsPerLabel: 60 }
772 },
773 series: {
774 b: { axis: "y2" }
775 }
776 });
777
778 // It is weird that labelsKMG2 does something on the x axis but KMB does not.
779 // Plus I can't be sure they're doing the same thing as they're done in different
780 // bits of code.
781 // BUG : https://code.google.com/p/dygraphs/issues/detail?id=488
782 assertEquals(["1024","2048","3072"], Util.getXLabels());
783 assertEquals( ["0","500","1000","1500","2000"], Util.getYLabels(1));
784 assertEquals(["0","500","1000","1.46k","1.95k"], Util.getYLabels(2));
785 };
786
787 /**
788 * This test shows you can override sigFigs on the axis level.
789 */
790 AxisLabelsTestCase.prototype.testSigFigsPerAxis = function() {
791 var g = new Dygraph(
792 document.getElementById("graph"),
793 "x,a,b\n" +
794 "1000,0,2000\n" +
795 "2000,500,1500\n" +
796 "3000,1000,1000\n" +
797 "4000,2000,0\n", {
798 sigFigs: 2,
799 axes: {
800 y2: { sigFigs: 6 },
801 x: { sigFigs: 8 }
802 },
803 series: {
804 b: { axis: "y2" }
805 }
806
807 });
808 // sigFigs doesn't apply to the x axis. This value should be different.
809 // BUG : https://code.google.com/p/dygraphs/issues/detail?id=488
810 assertEquals(["1000","2000","3000"], Util.getXLabels());
811 assertEquals(["0.0","5.0e+2","1.0e+3","1.5e+3","2.0e+3"], Util.getYLabels(1));
812 assertEquals(["0.00000","500.000","1000.00","1500.00","2000.00"], Util.getYLabels(2));
813 }
814
815 /**
816 * This test shows you can override digitsAfterDecimal on the axis level.
817 */
818 AxisLabelsTestCase.prototype.testDigitsAfterDecimalPerAxis = function() {
819 var g = new Dygraph(
820 document.getElementById("graph"),
821 "x,a,b\n" +
822 "0.006,0.001,0.008\n" +
823 "0.007,0.002,0.007\n" +
824 "0.008,0.003,0.006\n" +
825 "0.009,0.004,0.005\n", {
826 digitsAfterDecimal: 1,
827 series: {
828 b: { axis: "y2" }
829 }
830
831 });
832
833 g.updateOptions({ axes: { y: { digitsAfterDecimal: 3 }}});
834 assertEquals(["0.001","0.002","0.002","0.003","0.003","0.004","0.004"], Util.getYLabels(1));
835 g.updateOptions({ axes: { y: { digitsAfterDecimal: 4 }}});
836 assertEquals(["0.001","0.0015","0.002","0.0025","0.003","0.0035","0.004"], Util.getYLabels(1));
837 g.updateOptions({ axes: { y: { digitsAfterDecimal: 5 }}});
838 assertEquals(["0.001","0.0015","0.002","0.0025","0.003","0.0035","0.004"], Util.getYLabels(1));
839 g.updateOptions({ axes: { y: { digitsAfterDecimal: null }}});
840 assertEquals(["1e-3","2e-3","2e-3","3e-3","3e-3","4e-3","4e-3"], Util.getYLabels(1));
841
842 g.updateOptions({ axes: { y2: { digitsAfterDecimal: 3 }}});
843 assertEquals(["0.005","0.006","0.006","0.007","0.007","0.008","0.008"], Util.getYLabels(2));
844 g.updateOptions({ axes: { y2: { digitsAfterDecimal: 4 }}});
845 assertEquals(["0.005","0.0055","0.006","0.0065","0.007","0.0075","0.008"], Util.getYLabels(2));
846 g.updateOptions({ axes: { y2: { digitsAfterDecimal: 5 }}});
847 assertEquals(["0.005","0.0055","0.006","0.0065","0.007","0.0075","0.008"], Util.getYLabels(2));
848 g.updateOptions({ axes: { y2: { digitsAfterDecimal: null }}});
849 assertEquals(["5e-3","6e-3","6e-3","7e-3","7e-3","7e-3","8e-3"], Util.getYLabels(2));
850
851
852 // digitsAfterDecimal is ignored for the x-axis.
853 // BUG : https://code.google.com/p/dygraphs/issues/detail?id=488
854 g.updateOptions({ axes: { x: { digitsAfterDecimal: 3 }}});
855 assertEquals(["0.006","0.007","0.008"], Util.getXLabels());
856 g.updateOptions({ axes: { x: { digitsAfterDecimal: 4 }}});
857 assertEquals(["0.006","0.007","0.008"], Util.getXLabels());
858 g.updateOptions({ axes: { x: { digitsAfterDecimal: 5 }}});
859 assertEquals(["0.006","0.007","0.008"], Util.getXLabels());
860 g.updateOptions({ axes: { x: { digitsAfterDecimal: null }}});
861 assertEquals(["0.006","0.007","0.008"], Util.getXLabels());
862 }
863
864 /**
865 * This test shows you can override digitsAfterDecimal on the axis level.
866 */
867 AxisLabelsTestCase.prototype.testMaxNumberWidthPerAxis = function() {
868 var g = new Dygraph(
869 document.getElementById("graph"),
870 "x,a,b\n" +
871 "12401,12601,12804\n" +
872 "12402,12602,12803\n" +
873 "12403,12603,12802\n" +
874 "12404,12604,12801\n", {
875 maxNumberWidth: 1,
876 series: {
877 b: { axis: "y2" }
878 }
879 });
880
881 g.updateOptions({ axes: { y: { maxNumberWidth: 4 }}});
882 assertEquals(["1.26e+4","1.26e+4","1.26e+4","1.26e+4","1.26e+4","1.26e+4","1.26e+4"] , Util.getYLabels(1));
883 g.updateOptions({ axes: { y: { maxNumberWidth: 5 }}});
884 assertEquals(["12601","12601.5","12602","12602.5","12603","12603.5","12604"] , Util.getYLabels(1));
885 g.updateOptions({ axes: { y: { maxNumberWidth: null }}});
886 assertEquals(["1.26e+4","1.26e+4","1.26e+4","1.26e+4","1.26e+4","1.26e+4","1.26e+4"] , Util.getYLabels(1));
887
888 g.updateOptions({ axes: { y2: { maxNumberWidth: 4 }}});
889 assertEquals(["1.28e+4","1.28e+4","1.28e+4","1.28e+4","1.28e+4","1.28e+4","1.28e+4"], Util.getYLabels(2));
890 g.updateOptions({ axes: { y2: { maxNumberWidth: 5 }}});
891 assertEquals(["12801","12801.5","12802","12802.5","12803","12803.5","12804"], Util.getYLabels(2));
892 g.updateOptions({ axes: { y2: { maxNumberWidth: null }}});
893 assertEquals(["1.28e+4","1.28e+4","1.28e+4","1.28e+4","1.28e+4","1.28e+4","1.28e+4"], Util.getYLabels(2));
894
895 // maxNumberWidth is ignored for the x-axis.
896 // BUG : https://code.google.com/p/dygraphs/issues/detail?id=488
897 g.updateOptions({ axes: { x: { maxNumberWidth: 4 }}});
898 assertEquals(["12401","12402","12403"], Util.getXLabels());
899 g.updateOptions({ axes: { x: { maxNumberWidth: 5 }}});
900 assertEquals(["12401","12402","12403"], Util.getXLabels());
901 g.updateOptions({ axes: { x: { maxNumberWidth: null }}});
902 assertEquals(["12401","12402","12403"], Util.getXLabels());
903 }
904
905 /*
906 // Regression test for http://code.google.com/p/dygraphs/issues/detail?id=147
907 // Checks that axis labels stay sane across a DST change.
908 AxisLabelsTestCase.prototype.testLabelsCrossDstChange = function() {
909 // (From tests/daylight-savings.html)
910 var g = new Dygraph(
911 document.getElementById("graph"),
912 "Date/Time,Purchases\n" +
913 "2010-11-05 00:00:00,167082\n" +
914 "2010-11-06 00:00:00,168571\n" +
915 "2010-11-07 00:00:00,177796\n" +
916 "2010-11-08 00:00:00,165587\n" +
917 "2010-11-09 00:00:00,164380\n",
918 { width: 1024 }
919 );
920
921 // Dates and "nice" hours: 6AM/PM and noon, not 5AM/11AM/...
922 var okLabels = {
923 '05Nov': true,
924 '06Nov': true,
925 '07Nov': true,
926 '08Nov': true,
927 '09Nov': true,
928 '06:00': true,
929 '12:00': true,
930 '18:00': true
931 };
932
933 var xLabels = Util.getXLabels();
934 for (var i = 0; i < xLabels.length; i++) {
935 assertTrue(okLabels[xLabels[i]]);
936 }
937
938 // This range had issues of its own on tests/daylight-savings.html.
939 g.updateOptions({
940 dateWindow: [1289109997722.8127, 1289261208937.7659]
941 });
942 xLabels = Util.getXLabels();
943 for (var i = 0; i < xLabels.length; i++) {
944 assertTrue(okLabels[xLabels[i]]);
945 }
946 };
947
948
949 // Tests data which crosses a "fall back" at a high enough frequency that you
950 // can see both 1:00 A.M.s.
951 AxisLabelsTestCase.prototype.testLabelsCrossDstChangeHighFreq = function() {
952 // Generate data which crosses the EST/EDT boundary.
953 var dst_data = [];
954 var base_ms = 1383454200000;
955 for (var x = base_ms; x < base_ms + 1000 * 60 * 80; x += 1000) {
956 dst_data.push([new Date(x), x]);
957 }
958
959 var g = new Dygraph(
960 document.getElementById("graph"),
961 dst_data,
962 { width: 1024, labels: ['Date', 'Value'] }
963 );
964
965 assertEquals([
966 '00:50', '00:55',
967 '01:00', '01:05', '01:10', '01:15', '01:20', '01:25',
968 '01:30', '01:35', '01:40', '01:45', '01:50', '01:55',
969 '01:00', '01:05' // 1 AM number two!
970 ], Util.getXLabels());
971
972 // Now zoom past the initial 1 AM. This used to cause trouble.
973 g.updateOptions({
974 dateWindow: [1383454200000 + 15*60*1000, g.xAxisExtremes()[1]]}
975 );
976 assertEquals([
977 '01:05', '01:10', '01:15', '01:20', '01:25',
978 '01:30', '01:35', '01:40', '01:45', '01:50', '01:55',
979 '01:00', '01:05' // 1 AM number two!
980 ], Util.getXLabels());
981 };
982
983
984 // Tests data which crosses a "spring forward" at a low frequency.
985 // Regression test for http://code.google.com/p/dygraphs/issues/detail?id=433
986 AxisLabelsTestCase.prototype.testLabelsCrossSpringForward = function() {
987 var g = new Dygraph(
988 document.getElementById("graph"),
989 "Date/Time,Purchases\n" +
990 "2011-03-11 00:00:00,167082\n" +
991 "2011-03-12 00:00:00,168571\n" +
992 "2011-03-13 00:00:00,177796\n" +
993 "2011-03-14 00:00:00,165587\n" +
994 "2011-03-15 00:00:00,164380\n",
995 {
996 width: 1024,
997 dateWindow: [1299989043119.4365, 1300080693627.4866]
998 });
999
1000 var okLabels = {
1001 '13Mar': true,
1002 // '02:00': true, // not a real time!
1003 '04:00': true,
1004 '06:00': true,
1005 '08:00': true,
1006 '10:00': true,
1007 '12:00': true,
1008 '14:00': true,
1009 '16:00': true,
1010 '18:00': true,
1011 '20:00': true,
1012 '22:00': true,
1013 '14Mar': true
1014 };
1015
1016 var xLabels = Util.getXLabels();
1017 for (var i = 0; i < xLabels.length; i++) {
1018 assertTrue(okLabels[xLabels[i]]);
1019 }
1020 };
1021
1022 AxisLabelsTestCase.prototype.testLabelsCrossSpringForwardHighFreq = function() {
1023 var base_ms_spring = 1299999000000;
1024 var dst_data_spring = [];
1025 for (var x = base_ms_spring; x < base_ms_spring + 1000 * 60 * 80; x += 1000) {
1026 dst_data_spring.push([new Date(x), x]);
1027 }
1028
1029 var g = new Dygraph(
1030 document.getElementById("graph"),
1031 dst_data_spring,
1032 { width: 1024, labels: ['Date', 'Value'] }
1033 );
1034
1035 assertEquals([
1036 '01:50', '01:55',
1037 '03:00', '03:05', '03:10', '03:15', '03:20', '03:25',
1038 '03:30', '03:35', '03:40', '03:45', '03:50', '03:55',
1039 '04:00', '04:05'
1040 ], Util.getXLabels());
1041 };
1042 */