2 * @fileoverview Test cases for how axis labels are chosen and formatted.
4 * @author dan@dygraphs.com (Dan Vanderkam)
6 var AxisLabelsTestCase
= TestCase("axis-labels");
8 AxisLabelsTestCase
.prototype.setUp
= function() {
9 document
.body
.innerHTML
= "<div id='graph'></div>";
12 AxisLabelsTestCase
.prototype.tearDown
= function() {
15 AxisLabelsTestCase
.simpleData
=
23 * Takes in an array of strings and returns an array of floats.
25 function makeNumbers(ary
) {
27 for (var i
= 0; i
< ary
.length
; i
++) {
28 ret
.push(parseFloat(ary
[i
]));
33 AxisLabelsTestCase
.prototype.kCloseFloat
= 1.0e-10;
35 AxisLabelsTestCase
.prototype.testMinusOneToOne
= function() {
47 var graph
= document
.getElementById("graph");
48 var g
= new Dygraph(graph
, data
, opts
);
50 // TODO(danvk): would ['-1.0','-0.5','0.0','0.5','1.0'] be better?
51 assertEquals(['-1','-0.5','0','0.5','1'], Util
.getYLabels());
55 g
.updateOptions({file
: data
});
56 assertEquals(['-1','-0.5','0','0.5','1','1.5','2'], Util
.getYLabels());
60 g
.updateOptions({file
: data
});
61 assertEquals(['-2','0','2','4','6','8','10'], Util
.getYLabels());
65 g
.updateOptions({file
: data
});
66 assertEquals(['0','20','40','60','80','100'], Util
.getYLabels());
69 assertEquals('0: Y:-1', Util
.getLegend());
72 AxisLabelsTestCase
.prototype.testSmallRangeNearZero
= function() {
84 opts
.valueRange
= [-0.1, 0.1];
86 var graph
= document
.getElementById("graph");
87 var g
= new Dygraph(graph
, data
, opts
);
88 assertEqualsDelta(makeNumbers(["-0.1","-0.08","-0.06","-0.04","-0.02","0","0.02","0.04","0.06","0.08"]),
89 makeNumbers(Util
.getYLabels()), this.kCloseFloat
);
91 opts
.valueRange
= [-0.05, 0.05];
92 g
.updateOptions(opts
);
93 // TODO(danvk): why '1.00e-2' and not '0.01'?
94 assertEquals(makeNumbers(["-0.05","-0.04","-0.03","-0.02","-0.01","0","1.00e-2","0.02","0.03","0.04"]),
95 makeNumbers(Util
.getYLabels()));
97 opts
.valueRange
= [-0.01, 0.01];
98 g
.updateOptions(opts
);
99 assertEquals(makeNumbers(["-0.01","-8.00e-3","-6.00e-3","-4.00e-3","-2.00e-3","0","2.00e-3","4.00e-3","6.00e-3","8.00e-3"]), makeNumbers(Util
.getYLabels()));
102 assertEquals('1: Y:0', Util
.getLegend());
105 AxisLabelsTestCase
.prototype.testSmallRangeAwayFromZero
= function() {
116 var graph
= document
.getElementById("graph");
118 opts
.valueRange
= [9.9, 10.1];
119 var g
= new Dygraph(graph
, data
, opts
);
120 assertEquals(["9.9","9.92","9.94","9.96","9.98","10","10.02","10.04","10.06","10.08"], Util
.getYLabels());
122 opts
.valueRange
= [9.99, 10.01];
123 g
.updateOptions(opts
);
124 // TODO(danvk): this is bad
125 assertEquals(["9.99","9.99","9.99","10","10","10","10","10","10.01","10.01"], Util
.getYLabels());
127 opts
.valueRange
= [9.999, 10.001];
128 g
.updateOptions(opts
);
129 // TODO(danvk): this is even worse!
130 assertEquals(["10","10","10","10","10","10","10","10","10","10"], Util
.getYLabels());
133 assertEquals('1: Y:0', Util
.getLegend());
136 AxisLabelsTestCase
.prototype.testXAxisTimeLabelFormatter
= function() {
141 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]];
142 var graph
= document
.getElementById("graph");
143 var g
= new Dygraph(graph
, data
, opts
);
147 axisLabelFormatter
: function (totalMinutes
) {
148 var hours
= Math
.floor( totalMinutes
/ 60);
149 var minutes
= Math
.floor((totalMinutes
- (hours
* 60)));
150 var seconds
= Math
.round((totalMinutes
* 60) - (hours
* 3600) - (minutes
* 60));
152 if (hours
< 10) hours
= "0" + hours
;
153 if (minutes
< 10) minutes
= "0" + minutes
;
154 if (seconds
< 10) seconds
= "0" + seconds
;
156 return hours
+ ':' + minutes
+ ':' + seconds
;
162 assertEquals(["00:05:00","00:05:12","00:05:24","00:05:36","00:05:48"], Util
.getXLabels());
164 // The legend does not use the axisLabelFormatter:
166 assertEquals('5.1: Y1:1', Util
.getLegend());
169 AxisLabelsTestCase
.prototype.testAxisLabelFormatter
= function () {
175 axisLabelFormatter
: function(x
, granularity
, opts
, dg
) {
176 assertEquals('number', typeof(x
));
177 assertEquals('number', typeof(granularity
));
178 assertEquals('function', typeof(opts
));
179 assertEquals('[Dygraph graph]', dg
.toString());
184 axisLabelFormatter
: function(y
, granularity
, opts
, dg
) {
185 assertEquals('number', typeof(y
));
186 assertEquals('number', typeof(granularity
));
187 assertEquals('function', typeof(opts
));
188 assertEquals('[Dygraph graph]', dg
.toString());
196 for (var i
= 0; i
< 10; i
++) {
197 data
.push([i
, 2 * i
]);
199 var graph
= document
.getElementById("graph");
200 var g
= new Dygraph(graph
, data
, opts
);
202 assertEquals(['x0','x2','x4','x6','x8'], Util
.getXLabels());
203 assertEquals(['y0','y2','y4','y6','y8','y10','y12','y14','y16','y18'], Util
.getYLabels());
206 assertEquals("2: y:4", Util
.getLegend());
209 AxisLabelsTestCase
.prototype.testDateAxisLabelFormatter
= function () {
215 axisLabelFormatter
: function(x
, granularity
, opts
, dg
) {
216 assertTrue(Dygraph
.isDateLike(x
));
217 assertEquals('number', typeof(granularity
));
218 assertEquals('function', typeof(opts
));
219 assertEquals('[Dygraph graph]', dg
.toString());
220 return 'x' + x
.strftime('%Y/%m/%d');
224 axisLabelFormatter
: function(y
, granularity
, opts
, dg
) {
225 assertEquals('number', typeof(y
));
226 assertEquals('number', typeof(granularity
));
227 assertEquals('function', typeof(opts
));
228 assertEquals('[Dygraph graph]', dg
.toString());
236 for (var i
= 1; i
< 10; i
++) {
237 data
.push([new Date("2011/01/0" + i
), 2 * i
]);
239 var graph
= document
.getElementById("graph");
240 var g
= new Dygraph(graph
, data
, opts
);
242 assertEquals(["x2011/01/01", "x2011/01/02", "x2011/01/03", "x2011/01/04", "x2011/01/05", "x2011/01/06", "x2011/01/07", "x2011/01/08", "x2011/01/09"], Util
.getXLabels());
243 assertEquals(['y2','y4','y6','y8','y10','y12','y14','y16','y18'], Util
.getYLabels());
246 assertEquals("2011/01/01: y:2", Util
.getLegend());
249 // This test verifies that when a valueFormatter is set (but not an
250 // axisLabelFormatter), then the valueFormatter is used to format the axis
252 AxisLabelsTestCase
.prototype.testValueFormatter
= function () {
258 valueFormatter
: function(x
, opts
, series_name
, dg
) {
259 assertEquals('number', typeof(x
));
260 assertEquals('function', typeof(opts
));
261 assertEquals('string', typeof(series_name
));
262 assertEquals('[Dygraph graph]', dg
.toString());
267 valueFormatter
: function(y
, opts
, series_name
, dg
) {
268 assertEquals('number', typeof(y
));
269 assertEquals('function', typeof(opts
));
270 assertEquals('string', typeof(series_name
));
271 assertEquals('[Dygraph graph]', dg
.toString());
279 for (var i
= 0; i
< 10; i
++) {
280 data
.push([i
, 2 * i
]);
282 var graph
= document
.getElementById("graph");
283 var g
= new Dygraph(graph
, data
, opts
);
285 // the valueFormatter options do not affect the ticks.
286 assertEquals(['0','2','4','6','8'], Util
.getXLabels());
287 assertEquals(['0','2','4','6','8','10','12','14','16','18'],
290 // they do affect the legend, however.
292 assertEquals("x2: y:y4", Util
.getLegend());
295 AxisLabelsTestCase
.prototype.testDateValueFormatter
= function () {
301 valueFormatter
: function(x
, opts
, series_name
, dg
) {
302 assertEquals('number', typeof(x
));
303 assertEquals('function', typeof(opts
));
304 assertEquals('string', typeof(series_name
));
305 assertEquals('[Dygraph graph]', dg
.toString());
306 return 'x' + new Date(x
).strftime('%Y/%m/%d');
310 valueFormatter
: function(y
, opts
, series_name
, dg
) {
311 assertEquals('number', typeof(y
));
312 assertEquals('function', typeof(opts
));
313 assertEquals('string', typeof(series_name
));
314 assertEquals('[Dygraph graph]', dg
.toString());
323 for (var i
= 1; i
< 10; i
++) {
324 data
.push([new Date("2011/01/0" + i
), 2 * i
]);
326 var graph
= document
.getElementById("graph");
327 var g
= new Dygraph(graph
, data
, opts
);
329 // valueFormatters do not affect ticks.
330 assertEquals(['01Jan','02Jan','03Jan','04Jan','05Jan','06Jan','07Jan','08Jan','09Jan'], Util
.getXLabels());
331 assertEquals(['2','4','6','8','10','12','14','16','18'], Util
.getYLabels());
333 // the valueFormatter options also affect the legend.
335 assertEquals('x2011/01/03: y:y6', Util
.getLegend());
338 // This test verifies that when both a valueFormatter and an axisLabelFormatter
339 // are specified, the axisLabelFormatter takes precedence.
340 AxisLabelsTestCase
.prototype.testAxisLabelFormatterPrecedence
= function () {
346 valueFormatter
: function(x
) {
349 axisLabelFormatter
: function(x
, granularity
) {
354 valueFormatter
: function(y
) {
357 axisLabelFormatter
: function(y
) {
365 for (var i
= 0; i
< 10; i
++) {
366 data
.push([i
, 2 * i
]);
368 var graph
= document
.getElementById("graph");
369 var g
= new Dygraph(graph
, data
, opts
);
371 assertEquals(['x0','x2','x4','x6','x8'], Util
.getXLabels());
372 assertEquals(['y0','y2','y4','y6','y8','y10','y12','y14','y16','y18'], Util
.getYLabels());
375 assertEquals("xvf9: y:yvf18", Util
.getLegend());
378 // This is the same as the previous test, except that options are added
380 AxisLabelsTestCase
.prototype.testAxisLabelFormatterIncremental
= function () {
387 for (var i
= 0; i
< 10; i
++) {
388 data
.push([i
, 2 * i
]);
390 var graph
= document
.getElementById("graph");
391 var g
= new Dygraph(graph
, data
, opts
);
395 valueFormatter
: function(x
) {
404 valueFormatter
: function(y
) {
413 axisLabelFormatter
: function(x
, granularity
) {
422 axisLabelFormatter
: function(y
) {
429 assertEquals(["x0","x2","x4","x6","x8"], Util
.getXLabels());
430 assertEquals(['y0','y2','y4','y6','y8','y10','y12','y14','y16','y18'], Util
.getYLabels());
433 assertEquals("xvf9: y:yvf18", Util
.getLegend());
436 AxisLabelsTestCase
.prototype.testGlobalFormatters
= function() {
441 valueFormatter
: function(x
) {
444 axisLabelFormatter
: function(x
) {
449 for (var i
= 0; i
< 10; i
++) {
450 data
.push([i
, 2 * i
]);
452 var graph
= document
.getElementById("graph");
453 var g
= new Dygraph(graph
, data
, opts
);
455 assertEquals(['alf0','alf2','alf4','alf6','alf8'], Util
.getXLabels());
456 assertEquals(['alf0','alf2','alf4','alf6','alf8','alf10','alf12','alf14','alf16','alf18'], Util
.getYLabels());
459 assertEquals("vf9: y:vf18", Util
.getLegend());
462 AxisLabelsTestCase
.prototype.testSeriesOrder
= function() {
467 var data
= "x,00,01,10,11\n" +
468 "0,101,201,301,401\n" +
469 "1,102,202,302,402\n" +
470 "2,103,203,303,403\n" +
471 "3,104,204,304,404\n"
474 var graph
= document
.getElementById("graph");
475 var g
= new Dygraph(graph
, data
, opts
);
478 assertEquals('2: 00:103 01:203 10:303 11:403', Util
.getLegend());
480 // Sanity checks for indexFromSetName
481 assertEquals(0, g
.indexFromSetName("x"));
482 assertEquals(1, g
.indexFromSetName("00"));
483 assertEquals(null, g
.indexFromSetName("abcde"));
485 // Verify that we get the label list back in the right order
486 assertEquals(["x", "00", "01", "10", "11"], g
.getLabels());
489 AxisLabelsTestCase
.prototype.testLabelKMB
= function() {
496 document
.getElementById("graph"),
499 labels
: [ 'X', 'bar' ],
508 assertEquals(["0", "500", "1K", "1.5K", "2K"], Util
.getYLabels());
511 AxisLabelsTestCase
.prototype.testLabelKMG2
= function() {
518 document
.getElementById("graph"),
521 labels
: [ 'X', 'bar' ],
531 ["0","256","512","768","1k","1.25k","1.5k","1.75k","2k"],
535 // Same sa testLabelKMG2 but specifies the option at the
536 // top of the option dictionary.
537 AxisLabelsTestCase
.prototype.testLabelKMG2_top
= function() {
544 document
.getElementById("graph"),
547 labels
: [ 'X', 'bar' ],
553 ["0","256","512","768","1k","1.25k","1.5k","1.75k","2k"],
558 * Verify that log scale axis range is properly specified.
560 AxisLabelsTestCase
.prototype.testLogScale
= function() {
561 var g
= new Dygraph("graph", [[0, 5], [1, 1000]], { logscale
: true });
562 var nonEmptyLabels
= Util
.getYLabels().filter(function(x
) { return x
.length
> 0; });
563 assertEquals(["6","10","30","60","100","300","600","1000"], nonEmptyLabels
);
565 g
.updateOptions({ logscale
: false });
566 assertEquals(['0','200','400','600','800','1000'], Util
.getYLabels());
570 * Verify that include zero range is properly specified.
572 AxisLabelsTestCase
.prototype.testIncludeZero
= function() {
573 var g
= new Dygraph("graph", [[0, 500], [1, 1000]], { includeZero
: true });
574 assertEquals(['0','200','400','600','800','1000'], Util
.getYLabels());
576 g
.updateOptions({ includeZero
: false });
577 assertEquals(['500','600','700','800','900','1000'], Util
.getYLabels());
580 AxisLabelsTestCase
.prototype.testAxisLabelFontSizeNull
= function() {
581 var graph
= document
.getElementById("graph");
582 var g
= new Dygraph(graph
, AxisLabelsTestCase
.simpleData
,
584 axisLabelFontSize
: null
587 // Be sure we're dealing with a 14-point default.
588 assertEquals(14, Dygraph
.DEFAULT_ATTRS
.axisLabelFontSize
);
590 Util
.assertFontSizes(graph
, "dygraph-axis-label-x", 14);
591 Util
.assertFontSizes(graph
, "dygraph-axis-label-y", 14);