Factor out ticker functions and clean up their semantics/usage.
[dygraphs.git] / auto_tests / tests / axis_labels.js
CommitLineData
48e614ac 1/**
f3cbe61e
DV
2 * @fileoverview Test cases for how axis labels are chosen and formatted.
3 *
4 * @author dan@dygraphs.com (Dan Vanderkam)
5 */
6var AxisLabelsTestCase = TestCase("axis-labels");
7
8AxisLabelsTestCase.prototype.setUp = function() {
9 document.body.innerHTML = "<div id='graph'></div>";
10};
11
12AxisLabelsTestCase.prototype.tearDown = function() {
13};
14
15function getYLabels() {
16 var y_labels = document.getElementsByClassName("dygraph-axis-label-y");
17 var ary = [];
18 for (var i = 0; i < y_labels.length; i++) {
19 ary.push(y_labels[i].innerHTML);
20 }
21 return ary;
22}
23
97889da4 24function getXLabels() {
25 var x_labels = document.getElementsByClassName("dygraph-axis-label-x");
26 var ary = [];
27 for (var i = 0; i < x_labels.length; i++) {
28 ary.push(x_labels[i].innerHTML);
29 }
30 return ary;
31}
32
48e614ac
DV
33function getLegend() {
34 var legend = document.getElementsByClassName("dygraph-legend")[0];
35 return legend.textContent;
36}
37
f3cbe61e
DV
38AxisLabelsTestCase.prototype.testMinusOneToOne = function() {
39 var opts = {
40 width: 480,
41 height: 320
42 };
43 var data = "X,Y\n" +
44 "0,-1\n" +
45 "1,0\n" +
46 "2,1\n" +
47 "3,0\n"
48 ;
49
50 var graph = document.getElementById("graph");
51 var g = new Dygraph(graph, data, opts);
52
53 // TODO(danvk): would ['-1.0','-0.5','0.0','0.5','1.0'] be better?
54 assertEquals(['-1','-0.5','0','0.5','1'], getYLabels());
55
56 // Go up to 2
57 data += "4,2\n";
58 g.updateOptions({file: data});
59 assertEquals(['-1','-0.5','0','0.5','1','1.5','2'], getYLabels());
60
61 // Now 10
62 data += "5,10\n";
63 g.updateOptions({file: data});
64 assertEquals(['-2','0','2','4','6','8','10'], getYLabels());
65
66 // Now 100
67 data += "6,100\n";
68 g.updateOptions({file: data});
69 assertEquals(['0','20','40','60','80','100'], getYLabels());
48e614ac
DV
70
71 g.setSelection(0);
72 assertEquals('0: Y:-1', getLegend());
f3cbe61e
DV
73};
74
75AxisLabelsTestCase.prototype.testSmallRangeNearZero = function() {
76 var opts = {
77 width: 480,
78 height: 320
79 };
80 var data = "X,Y\n" +
81 "0,-1\n" +
82 "1,0\n" +
83 "2,1\n" +
84 "3,0\n"
85 ;
86 opts.valueRange = [-0.1, 0.1];
87
88 var graph = document.getElementById("graph");
89 var g = new Dygraph(graph, data, opts);
90 assertEquals(["-0.1","-0.08","-0.06","-0.04","-0.02","0","0.02","0.04","0.06","0.08"], getYLabels());
91
92 opts.valueRange = [-0.05, 0.05];
93 g.updateOptions(opts);
94 // TODO(danvk): why '1.00e-2' and not '0.01'?
95 assertEquals(["-0.05","-0.04","-0.03","-0.02","-0.01","0","1.00e-2","0.02","0.03","0.04"], getYLabels());
96
97 opts.valueRange = [-0.01, 0.01];
98 g.updateOptions(opts);
99 assertEquals(["-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"], getYLabels());
48e614ac
DV
100
101 g.setSelection(1);
102 assertEquals('1: Y:0', getLegend());
f3cbe61e
DV
103};
104
105AxisLabelsTestCase.prototype.testSmallRangeAwayFromZero = function() {
106 var opts = {
107 width: 480,
108 height: 320
109 };
110 var data = "X,Y\n" +
111 "0,-1\n" +
112 "1,0\n" +
113 "2,1\n" +
114 "3,0\n"
115 ;
116 var graph = document.getElementById("graph");
117
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"], getYLabels());
121
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"], getYLabels());
126
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"], getYLabels());
48e614ac
DV
131
132 g.setSelection(1);
133 assertEquals('1: Y:0', getLegend());
f3cbe61e 134};
97889da4 135
ad69cb8a
DV
136AxisLabelsTestCase.prototype.testXAxisTimeLabelFormatter = function() {
137 var opts = {
138 width: 480,
139 height: 320
140 };
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);
144 g.updateOptions({
145 xAxisLabelFormatter: function (totalMinutes) {
146 var hours = Math.floor( totalMinutes / 60);
147 var minutes = Math.floor((totalMinutes - (hours * 60)));
148 var seconds = Math.round((totalMinutes * 60) - (hours * 3600) - (minutes * 60));
149
150 if (hours < 10) hours = "0" + hours;
151 if (minutes < 10) minutes = "0" + minutes;
152 if (seconds < 10) seconds = "0" + seconds;
153
154 return hours + ':' + minutes + ':' + seconds;
155 }
156 });
97889da4 157
48e614ac
DV
158 assertEquals(["00:05:00","00:05:12","00:05:24","00:05:36","00:05:48"], getXLabels());
159
160 // The legend does not use the xAxisLabelFormatter:
161 g.setSelection(1);
162 assertEquals('5.1: Y1:1', getLegend());
163};
164
165AxisLabelsTestCase.prototype.testAxisLabelFormatter = function () {
166 var opts = {
167 width: 480,
168 height: 320,
169 xAxisLabelFormatter: function(x, granularity, opts, dg) {
170 assertEquals('number', typeof(x));
171 assertEquals('number', typeof(granularity));
172 assertEquals('function', typeof(opts));
173 assertEquals('[Dygraph graph]', dg.toString());
174 return 'x' + x;
175 },
176 yAxisLabelFormatter: function(y, granularity, opts, dg) {
177 assertEquals('number', typeof(y));
178 assertEquals('number', typeof(granularity));
179 assertEquals('function', typeof(opts));
180 assertEquals('[Dygraph graph]', dg.toString());
181 return 'y' + y;
182 },
183 labels: ['x', 'y']
184 };
185 var data = [];
186 for (var i = 0; i < 10; i++) {
187 data.push([i, 2 * i]);
188 }
189 var graph = document.getElementById("graph");
190 var g = new Dygraph(graph, data, opts);
191
192 assertEquals(['x0','x2','x4','x6','x8'], getXLabels());
193 assertEquals(['y0','y2','y4','y6','y8','y10','y12','y14','y16','y18'], getYLabels());
194
195 g.setSelection(2);
196 assertEquals("2: y:4", getLegend());
197};
198
199AxisLabelsTestCase.prototype.testDateAxisLabelFormatter = function () {
200 var opts = {
201 width: 480,
202 height: 320,
203 xAxisLabelFormatter: function(x, granularity, opts, dg) {
204 assertTrue(Dygraph.isDateLike(x));
205 assertEquals('number', typeof(granularity));
206 assertEquals('function', typeof(opts));
207 assertEquals('[Dygraph graph]', dg.toString());
208 return 'x' + x.strftime('%Y/%m/%d');
209 },
210 yAxisLabelFormatter: function(y, granularity, opts, dg) {
211 assertEquals('number', typeof(y));
212 assertEquals('number', typeof(granularity));
213 assertEquals('function', typeof(opts));
214 assertEquals('[Dygraph graph]', dg.toString());
215 return 'y' + y;
216 },
217 labels: ['x', 'y']
218 };
219 var data = [];
220 for (var i = 1; i < 10; i++) {
221 data.push([new Date("2011/01/0" + i), 2 * i]);
222 }
223 var graph = document.getElementById("graph");
224 var g = new Dygraph(graph, data, opts);
225
226 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"], getXLabels());
227 assertEquals(['y2','y4','y6','y8','y10','y12','y14','y16','y18'], getYLabels());
228
229 g.setSelection(0);
230 assertEquals("2011/01/01: y:2", getLegend());
231};
232
233// This test verifies that when a valueFormatter is set (but not an
234// axisLabelFormatter), then the valueFormatter is used to format the axis
235// labels.
236AxisLabelsTestCase.prototype.testValueFormatter = function () {
237 var opts = {
238 width: 480,
239 height: 320,
240 xValueFormatter: function(x, opts, series_name, dg) {
241 assertEquals('number', typeof(x));
242 assertEquals('function', typeof(opts));
243 assertEquals('string', typeof(series_name));
244 assertEquals('[Dygraph graph]', dg.toString());
245 return 'x' + x;
246 },
247 yValueFormatter: function(y, opts, series_name, dg) {
248 assertEquals('number', typeof(y));
249 assertEquals('function', typeof(opts));
250 assertEquals('string', typeof(series_name));
251 assertEquals('[Dygraph graph]', dg.toString());
252 return 'y' + y;
253 },
254 labels: ['x', 'y']
255 };
256 var data = [];
257 for (var i = 0; i < 10; i++) {
258 data.push([i, 2 * i]);
259 }
260 var graph = document.getElementById("graph");
261 var g = new Dygraph(graph, data, opts);
262
263 // the valueFormatter options do not affect the ticks.
264 assertEquals(['0','2','4','6','8'], getXLabels());
265 assertEquals(['0','2','4','6','8','10','12','14','16','18'],
266 getYLabels());
267
268 // they do affect the legend, however.
269 g.setSelection(2);
270 assertEquals("x2: y:y4", getLegend());
271};
272
273AxisLabelsTestCase.prototype.testDateValueFormatter = function () {
274 var opts = {
275 width: 480,
276 height: 320,
277 xValueFormatter: function(x, opts, series_name, dg) {
278 assertEquals('number', typeof(x));
279 assertEquals('function', typeof(opts));
280 assertEquals('string', typeof(series_name));
281 assertEquals('[Dygraph graph]', dg.toString());
282 return 'x' + new Date(x).strftime('%Y/%m/%d');
283 },
284 yValueFormatter: function(y, opts, series_name, dg) {
285 assertEquals('number', typeof(y));
286 assertEquals('function', typeof(opts));
287 assertEquals('string', typeof(series_name));
288 assertEquals('[Dygraph graph]', dg.toString());
289 return 'y' + y;
290 },
291 labels: ['x', 'y']
292 };
293
294 var data = [];
295 for (var i = 1; i < 10; i++) {
296 data.push([new Date("2011/01/0" + i), 2 * i]);
297 }
298 var graph = document.getElementById("graph");
299 var g = new Dygraph(graph, data, opts);
300
301 // valueFormatters do not affect ticks.
302 assertEquals(['01Jan','02Jan','03Jan','04Jan','05Jan','06Jan','07Jan','08Jan','09Jan'], getXLabels());
303 assertEquals(['2','4','6','8','10','12','14','16','18'], getYLabels());
304
305 // the valueFormatter options also affect the legend.
306 g.setSelection(2);
307 assertEquals('x2011/01/03: y:y6', getLegend());
308};
309
310// This test verifies that when both a valueFormatter and an axisLabelFormatter
311// are specified, the axisLabelFormatter takes precedence.
312AxisLabelsTestCase.prototype.testAxisLabelFormatterPrecedence = function () {
313 var opts = {
314 width: 480,
315 height: 320,
316 xValueFormatter: function(x) {
317 return 'xvf' + x;
318 },
319 yValueFormatter: function(y) {
320 return 'yvf' + y;
321 },
322 xAxisLabelFormatter: function(x, granularity) {
323 return 'x' + x;
324 },
325 yAxisLabelFormatter: function(y) {
326 return 'y' + y;
327 },
328 labels: ['x', 'y']
329 };
330 var data = [];
331 for (var i = 0; i < 10; i++) {
332 data.push([i, 2 * i]);
333 }
334 var graph = document.getElementById("graph");
335 var g = new Dygraph(graph, data, opts);
336
337 assertEquals(['x0','x2','x4','x6','x8'], getXLabels());
338 assertEquals(['y0','y2','y4','y6','y8','y10','y12','y14','y16','y18'], getYLabels());
339
340 g.setSelection(9);
341 assertEquals("xvf9: y:yvf18", getLegend());
342};
343
344// This is the same as the previous test, except that options are added
345// one-by-one.
346AxisLabelsTestCase.prototype.testAxisLabelFormatterIncremental = function () {
347 var opts = {
348 width: 480,
349 height: 320,
350 labels: ['x', 'y']
351 };
352 var data = [];
353 for (var i = 0; i < 10; i++) {
354 data.push([i, 2 * i]);
355 }
356 var graph = document.getElementById("graph");
357 var g = new Dygraph(graph, data, opts);
358 g.updateOptions({
359 xValueFormatter: function(x) {
360 return 'xvf' + x;
361 }
362 });
363 g.updateOptions({
364 yValueFormatter: function(y) {
365 return 'yvf' + y;
366 }
367 });
368 g.updateOptions({
369 xAxisLabelFormatter: function(x, granularity) {
370 return 'x' + x;
371 }
372 });
373 g.updateOptions({
374 yAxisLabelFormatter: function(y) {
375 return 'y' + y;
376 }
377 });
378
379 assertEquals(["x0","x2","x4","x6","x8"], getXLabels());
380 assertEquals(['y0','y2','y4','y6','y8','y10','y12','y14','y16','y18'], getYLabels());
ad69cb8a 381
48e614ac
DV
382 g.setSelection(9);
383 assertEquals("xvf9: y:yvf18", getLegend());
ad69cb8a 384};
97889da4 385
48e614ac
DV
386AxisLabelsTestCase.prototype.testGlobalFormatters = function() {
387 var opts = {
388 width: 480,
389 height: 320,
390 labels: ['x', 'y'],
391 valueFormatter: function(x) {
392 return 'vf' + x;
393 },
394 axisLabelFormatter: function(x) {
395 return 'alf' + x;
396 }
397 };
398 var data = [];
399 for (var i = 0; i < 10; i++) {
400 data.push([i, 2 * i]);
401 }
402 var graph = document.getElementById("graph");
403 var g = new Dygraph(graph, data, opts);
404
405 assertEquals(['alf0','alf2','alf4','alf6','alf8'], getXLabels());
406 assertEquals(['alf0','alf2','alf4','alf6','alf8','alf10','alf12','alf14','alf16','alf18'], getYLabels());
407
408 g.setSelection(9);
409 assertEquals("vf9: y:vf18", getLegend());
410};