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