Commit | Line | Data |
---|---|---|
48e614ac DV |
1 | /** |
2 | * @fileoverview Tests involving multiple y-axes. | |
3 | * | |
4 | * @author danvdk@gmail.com (Dan Vanderkam) | |
5 | */ | |
6 | ||
7 | var MultipleAxesTestCase = TestCase("multiple-axes-tests"); | |
8 | ||
9 | MultipleAxesTestCase.prototype.setUp = function() { | |
10 | document.body.innerHTML = "<div id='graph'></div>"; | |
11 | }; | |
12 | ||
13 | function getYLabelsForAxis(axis_num) { | |
14 | var y_labels = document.getElementsByClassName("dygraph-axis-label-y" + axis_num); | |
15 | var ary = []; | |
16 | for (var i = 0; i < y_labels.length; i++) { | |
17 | ary.push(y_labels[i].innerHTML); | |
18 | } | |
19 | return ary; | |
20 | } | |
21 | ||
22 | function getLegend() { | |
23 | var legend = document.getElementsByClassName("dygraph-legend")[0]; | |
24 | return legend.textContent; | |
25 | } | |
26 | ||
107f9d8e DV |
27 | // returns all text in tags w/ a given css class, sorted. |
28 | function getClassTexts(css_class) { | |
29 | var texts = []; | |
30 | var els = document.getElementsByClassName(css_class); | |
31 | for (var i = 0; i < els.length; i++) { | |
32 | texts[i] = els[i].textContent; | |
33 | } | |
34 | texts.sort(); | |
35 | return texts; | |
36 | } | |
37 | ||
48e614ac DV |
38 | MultipleAxesTestCase.getData = function() { |
39 | var data = []; | |
40 | for (var i = 1; i <= 100; i++) { | |
41 | var m = "01", d = i; | |
42 | if (d > 31) { m = "02"; d -= 31; } | |
43 | if (m == "02" && d > 28) { m = "03"; d -= 28; } | |
44 | if (m == "03" && d > 31) { m = "04"; d -= 31; } | |
45 | if (d < 10) d = "0" + d; | |
46 | // two series, one with range 1-100, one with range 1-2M | |
47 | data.push([new Date("2010/" + m + "/" + d), | |
48 | i, | |
49 | 100 - i, | |
50 | 1e6 * (1 + i * (100 - i) / (50 * 50)), | |
51 | 1e6 * (2 - i * (100 - i) / (50 * 50))]); | |
52 | } | |
53 | return data; | |
54 | }; | |
55 | ||
56 | MultipleAxesTestCase.prototype.testBasicMultipleAxes = function() { | |
57 | var data = MultipleAxesTestCase.getData(); | |
58 | ||
107f9d8e | 59 | var g = new Dygraph( |
48e614ac DV |
60 | document.getElementById("graph"), |
61 | data, | |
62 | { | |
63 | labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ], | |
64 | width: 640, | |
65 | height: 350, | |
66 | 'Y3': { | |
67 | axis: { | |
68 | // set axis-related properties here | |
69 | labelsKMB: true | |
70 | } | |
71 | }, | |
72 | 'Y4': { | |
73 | axis: 'Y3' // use the same y-axis as series Y3 | |
74 | } | |
75 | } | |
76 | ); | |
77 | ||
78 | assertEquals(["0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"], getYLabelsForAxis("1")); | |
79 | assertEquals(["900K", "1.01M", "1.12M", "1.23M", "1.34M", "1.45M", "1.55M", "1.66M", "1.77M", "1.88M", "1.99M"], getYLabelsForAxis("2")); | |
80 | }; | |
81 | ||
82 | MultipleAxesTestCase.prototype.testNewStylePerAxisOptions = function() { | |
83 | var data = MultipleAxesTestCase.getData(); | |
84 | ||
107f9d8e | 85 | var g = new Dygraph( |
48e614ac DV |
86 | document.getElementById("graph"), |
87 | data, | |
88 | { | |
89 | labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ], | |
90 | width: 640, | |
91 | height: 350, | |
92 | 'Y3': { | |
93 | axis: { } | |
94 | }, | |
95 | 'Y4': { | |
96 | axis: 'Y3' // use the same y-axis as series Y3 | |
97 | }, | |
98 | axes: { | |
99 | y2: { | |
100 | labelsKMB: true | |
101 | } | |
102 | } | |
103 | } | |
104 | ); | |
105 | ||
106 | assertEquals(["0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"], getYLabelsForAxis("1")); | |
107 | assertEquals(["900K", "1.01M", "1.12M", "1.23M", "1.34M", "1.45M", "1.55M", "1.66M", "1.77M", "1.88M", "1.99M"], getYLabelsForAxis("2")); | |
108 | }; | |
015b31df AV |
109 | |
110 | MultipleAxesTestCase.prototype.testMultiAxisLayout = function() { | |
111 | var data = MultipleAxesTestCase.getData(); | |
112 | ||
113 | var el = document.getElementById("graph"); | |
114 | ||
107f9d8e | 115 | var g = new Dygraph( |
015b31df AV |
116 | el, |
117 | data, | |
118 | { | |
119 | labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ], | |
120 | width: 640, | |
121 | height: 350, | |
122 | 'Y3': { | |
123 | axis: { } | |
124 | }, | |
125 | 'Y4': { | |
126 | axis: 'Y3' // use the same y-axis as series Y3 | |
127 | }, | |
128 | axes: { | |
129 | y2: { | |
130 | labelsKMB: true | |
131 | } | |
132 | } | |
133 | } | |
134 | ); | |
135 | ||
136 | // Test that all elements are inside the bounds of the graph, set above | |
137 | var innerDiv = el.firstChild; | |
138 | for (var child = innerDiv.firstChild; child != null; child = child.nextSibling) { | |
139 | assertTrue(child.offsetLeft >= 0); | |
140 | assertTrue((child.offsetLeft + child.offsetWidth) <= 640); | |
141 | assertTrue(child.offsetTop >= 0); | |
142 | // TODO(flooey@google.com): Text sometimes linebreaks, | |
143 | // causing the labels to appear outside the allocated area. | |
144 | // assertTrue((child.offsetTop + child.offsetHeight) <= 350); | |
145 | } | |
146 | }; | |
a2da3777 DV |
147 | |
148 | MultipleAxesTestCase.prototype.testTwoAxisVisibility = function() { | |
149 | var data = []; | |
150 | data.push([0,0,0]); | |
151 | data.push([1,2,2000]); | |
152 | data.push([2,4,1000]); | |
153 | ||
395e98a3 | 154 | var g = new Dygraph( |
a2da3777 DV |
155 | document.getElementById("graph"), |
156 | data, | |
157 | { | |
158 | labels: [ 'X', 'bar', 'zot' ], | |
159 | 'zot': { | |
160 | axis: { | |
161 | labelsKMB: true | |
162 | } | |
163 | } | |
164 | } | |
165 | ); | |
166 | ||
167 | assertTrue(document.getElementsByClassName("dygraph-axis-label-y").length > 0); | |
168 | assertTrue(document.getElementsByClassName("dygraph-axis-label-y2").length > 0); | |
169 | ||
170 | g.setVisibility(0, false); | |
171 | ||
172 | assertTrue(document.getElementsByClassName("dygraph-axis-label-y").length > 0); | |
173 | assertTrue(document.getElementsByClassName("dygraph-axis-label-y2").length > 0); | |
174 | ||
175 | g.setVisibility(0, true); | |
176 | g.setVisibility(1, false); | |
177 | ||
178 | assertTrue(document.getElementsByClassName("dygraph-axis-label-y").length > 0); | |
179 | assertTrue(document.getElementsByClassName("dygraph-axis-label-y2").length > 0); | |
180 | }; | |
d0c39108 DV |
181 | |
182 | // verifies that all four chart labels (title, x-, y-, y2-axis label) can be | |
183 | // used simultaneously. | |
184 | MultipleAxesTestCase.prototype.testMultiChartLabels = function() { | |
185 | var data = MultipleAxesTestCase.getData(); | |
186 | ||
187 | var el = document.getElementById("graph"); | |
188 | el.style.border = '1px solid black'; | |
189 | el.style.marginLeft = '200px'; | |
190 | el.style.marginTop = '200px'; | |
191 | ||
107f9d8e | 192 | var g = new Dygraph( |
d0c39108 DV |
193 | el, |
194 | data, | |
195 | { | |
196 | labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ], | |
197 | width: 640, | |
198 | height: 350, | |
199 | 'Y3': { | |
200 | axis: { } | |
201 | }, | |
202 | 'Y4': { | |
203 | axis: 'Y3' // use the same y-axis as series Y3 | |
204 | }, | |
205 | xlabel: 'x-axis', | |
206 | ylabel: 'y-axis', | |
207 | y2label: 'y2-axis', | |
208 | title: 'Chart title' | |
209 | } | |
210 | ); | |
211 | ||
d0c39108 | 212 | assertEquals(["Chart title", "x-axis", "y-axis", "y2-axis"], |
107f9d8e DV |
213 | getClassTexts("dygraph-label")); |
214 | assertEquals(["Chart title"], getClassTexts("dygraph-title")); | |
215 | assertEquals(["x-axis"], getClassTexts("dygraph-xlabel")); | |
216 | assertEquals(["y-axis"], getClassTexts("dygraph-ylabel")); | |
217 | assertEquals(["y2-axis"], getClassTexts("dygraph-y2label")); | |
d0c39108 DV |
218 | |
219 | // TODO(danvk): check relative positioning here: title on top, y left of y2. | |
220 | }; | |
107f9d8e DV |
221 | |
222 | // Check that a chart w/o a secondary y-axis will not get a y2label, even if one | |
223 | // is specified. | |
224 | MultipleAxesTestCase.prototype.testNoY2LabelWithoutSecondaryAxis = function() { | |
225 | var g = new Dygraph( | |
226 | document.getElementById("graph"), | |
227 | MultipleAxesTestCase.getData(), | |
228 | { | |
229 | labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ], | |
230 | width: 640, | |
231 | height: 350, | |
232 | xlabel: 'x-axis', | |
233 | ylabel: 'y-axis', | |
234 | y2label: 'y2-axis', | |
235 | title: 'Chart title' | |
236 | } | |
237 | ); | |
238 | ||
239 | assertEquals(["Chart title", "x-axis", "y-axis"], | |
240 | getClassTexts("dygraph-label")); | |
241 | assertEquals(["Chart title"], getClassTexts("dygraph-title")); | |
242 | assertEquals(["x-axis"], getClassTexts("dygraph-xlabel")); | |
243 | assertEquals(["y-axis"], getClassTexts("dygraph-ylabel")); | |
244 | assertEquals([], getClassTexts("dygraph-y2label")); | |
245 | }; | |
4dd0ac55 RV |
246 | |
247 | MultipleAxesTestCase.prototype.testValueRangePerAxisOptions = function() { | |
248 | var data = MultipleAxesTestCase.getData(); | |
249 | ||
250 | g = new Dygraph( | |
251 | document.getElementById("graph"), | |
252 | data, | |
253 | { | |
254 | labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ], | |
255 | 'Y3': { | |
256 | axis: { | |
257 | } | |
258 | }, | |
259 | 'Y4': { | |
260 | axis: 'Y3' // use the same y-axis as series Y3 | |
261 | }, | |
262 | axes: { | |
263 | y: { | |
264 | valueRange: [40, 70] | |
265 | }, | |
266 | y2: { | |
267 | // set axis-related properties here | |
268 | labelsKMB: true | |
269 | } | |
270 | }, | |
271 | ylabel: 'Primary y-axis', | |
272 | y2label: 'Secondary y-axis', | |
273 | yAxisLabelWidth: 60 | |
274 | } | |
275 | ); | |
276 | assertEquals(["40", "45", "50", "55", "60", "65"], getYLabelsForAxis("1")); | |
277 | assertEquals(["900K","1.1M","1.3M","1.5M","1.7M","1.9M"], getYLabelsForAxis("2")); | |
278 | ||
279 | g.updateOptions( | |
280 | { | |
281 | axes: { | |
282 | y: { | |
283 | valueRange: [40, 80] | |
284 | }, | |
285 | y2: { | |
286 | valueRange: [1e6, 1.2e6] | |
287 | } | |
288 | } | |
289 | } | |
290 | ); | |
291 | assertEquals(["40", "45", "50", "55", "60", "65", "70", "75"], getYLabelsForAxis("1")); | |
292 | assertEquals(["1M", "1.02M", "1.05M", "1.08M", "1.1M", "1.13M", "1.15M", "1.18M"], getYLabelsForAxis("2")); | |
289e5e99 RK |
293 | }; |
294 | ||
295 | MultipleAxesTestCase.prototype.testDrawPointCallback = function() { | |
296 | var data = MultipleAxesTestCase.getData(); | |
297 | ||
298 | var results = { y : {}, y2 : {}}; | |
121e43ff | 299 | var firstCallback = function(g, seriesName, ctx, canvasx, canvasy, color, radius) { |
289e5e99 | 300 | results.y[seriesName] = 1; |
121e43ff RK |
301 | Dygraph.Circles.DEFAULT(g, seriesName, ctx, canvasx, canvasy, color, radius); |
302 | ||
289e5e99 | 303 | }; |
121e43ff | 304 | var secondCallback = function(g, seriesName, ctx, canvasx, canvasy, color, radius) { |
289e5e99 | 305 | results.y2[seriesName] = 1; |
121e43ff | 306 | Dygraph.Circles.TRIANGLE(g, seriesName, ctx, canvasx, canvasy, color, radius); |
289e5e99 RK |
307 | }; |
308 | ||
309 | g = new Dygraph( | |
310 | document.getElementById("graph"), | |
311 | data, | |
312 | { | |
313 | labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ], | |
314 | drawPoints : true, | |
121e43ff | 315 | pointSize : 3, |
289e5e99 RK |
316 | 'Y3': { |
317 | axis: { | |
318 | } | |
319 | }, | |
320 | 'Y4': { | |
321 | axis: 'Y3' // use the same y-axis as series Y3 | |
322 | }, | |
323 | axes: { | |
324 | y2: { | |
325 | drawPointCallback: secondCallback | |
326 | } | |
327 | }, | |
328 | drawPointCallback: firstCallback | |
329 | } | |
330 | ); | |
331 | ||
332 | assertEquals(1, results.y["Y1"]); | |
333 | assertEquals(1, results.y["Y2"]); | |
334 | assertEquals(1, results.y2["Y3"]); | |
335 | assertEquals(1, results.y2["Y4"]); | |
336 | }; |