OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Plot a line graph of data versus time on a HTML canvas element. | 6 * Plot a line graph of data versus time on a HTML canvas element. |
7 * | 7 * |
8 * @param {HTMLCanvasElement} plotCanvas The canvas on which the line graph is | 8 * @param {HTMLCanvasElement} plotCanvas The canvas on which the line graph is |
9 * drawn. | 9 * drawn. |
10 * @param {HTMLCanvasElement} legendCanvas The canvas on which the legend for | 10 * @param {HTMLCanvasElement} legendCanvas The canvas on which the legend for |
(...skipping 27 matching lines...) Expand all Loading... |
38 ctx.fillStyle = '#000'; | 38 ctx.fillStyle = '#000'; |
39 ctx.fillText(text, x, y); | 39 ctx.fillText(text, x, y); |
40 } | 40 } |
41 | 41 |
42 function printErrorText(ctx, text) { | 42 function printErrorText(ctx, text) { |
43 ctx.clearRect(0, 0, plotCanvas.width, plotCanvas.height); | 43 ctx.clearRect(0, 0, plotCanvas.width, plotCanvas.height); |
44 drawText(ctx, text, errorOffsetPixels, errorOffsetPixels); | 44 drawText(ctx, text, errorOffsetPixels, errorOffsetPixels); |
45 } | 45 } |
46 | 46 |
47 if (size < 2) { | 47 if (size < 2) { |
48 printErrorText(plotCtx, | 48 printErrorText( |
49 loadTimeData.getString('notEnoughDataAvailableYet')); | 49 plotCtx, loadTimeData.getString('notEnoughDataAvailableYet')); |
50 return; | 50 return; |
51 } | 51 } |
52 | 52 |
53 for (var count = 0; count < plots.length; count++) { | 53 for (var count = 0; count < plots.length; count++) { |
54 if (plots[count].data.length != size) { | 54 if (plots[count].data.length != size) { |
55 throw new Error('Mismatch in time and plot data.'); | 55 throw new Error('Mismatch in time and plot data.'); |
56 } | 56 } |
57 } | 57 } |
58 | 58 |
59 function valueToString(value) { | 59 function valueToString(value) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 ctx.restore(); | 96 ctx.restore(); |
97 } | 97 } |
98 | 98 |
99 // The strokeRect method of the 2d context of a plotCanvas draws a bounding | 99 // The strokeRect method of the 2d context of a plotCanvas draws a bounding |
100 // rectangle with an offset origin and greater dimensions. Hence, use this | 100 // rectangle with an offset origin and greater dimensions. Hence, use this |
101 // function to draw a rect at the desired location with desired dimensions. | 101 // function to draw a rect at the desired location with desired dimensions. |
102 function drawRect(ctx, x, y, width, height, color) { | 102 function drawRect(ctx, x, y, width, height, color) { |
103 var offset = 1 * devicePixelRatio; | 103 var offset = 1 * devicePixelRatio; |
104 drawLine(ctx, x, y, x + width - offset, y, color); | 104 drawLine(ctx, x, y, x + width - offset, y, color); |
105 drawLine(ctx, x, y, x, y + height - offset, color); | 105 drawLine(ctx, x, y, x, y + height - offset, color); |
106 drawLine(ctx, x, y + height - offset, x + width - offset, | 106 drawLine( |
107 y + height - offset, color); | 107 ctx, x, y + height - offset, x + width - offset, y + height - offset, |
108 drawLine(ctx, x + width - offset, y, x + width - offset, | 108 color); |
109 y + height - offset, color); | 109 drawLine( |
| 110 ctx, x + width - offset, y, x + width - offset, y + height - offset, |
| 111 color); |
110 } | 112 } |
111 | 113 |
112 function drawLegend() { | 114 function drawLegend() { |
113 // Show a legend only if at least one individual plot has a name. | 115 // Show a legend only if at least one individual plot has a name. |
114 var valid = false; | 116 var valid = false; |
115 for (var i = 0; i < plots.length; i++) { | 117 for (var i = 0; i < plots.length; i++) { |
116 if (plots[i].name != null) { | 118 if (plots[i].name != null) { |
117 valid = true; | 119 valid = true; |
118 break; | 120 break; |
119 } | 121 } |
120 } | 122 } |
121 if (!valid) { | 123 if (!valid) { |
122 legendCanvas.hidden = true; | 124 legendCanvas.hidden = true; |
123 return; | 125 return; |
124 } | 126 } |
125 | 127 |
126 | 128 |
127 var padding = 2 * devicePixelRatio; | 129 var padding = 2 * devicePixelRatio; |
128 var legendSquareSide = 12 * devicePixelRatio; | 130 var legendSquareSide = 12 * devicePixelRatio; |
129 var legendCtx = legendCanvas.getContext('2d'); | 131 var legendCtx = legendCanvas.getContext('2d'); |
130 var xLoc = padding; | 132 var xLoc = padding; |
131 var yLoc = padding; | 133 var yLoc = padding; |
132 // Adjust the height of the canvas before drawing on it. | 134 // Adjust the height of the canvas before drawing on it. |
133 for (var i = 0; i < plots.length; i++) { | 135 for (var i = 0; i < plots.length; i++) { |
134 if (plots[i].name == null) { | 136 if (plots[i].name == null) { |
135 continue; | 137 continue; |
136 } | 138 } |
137 var legendText = getLegend(plots[i].name); | 139 var legendText = getLegend(plots[i].name); |
138 xLoc += legendSquareSide + getTextWidth(legendCtx, legendText) + | 140 xLoc += |
139 2 * padding; | 141 legendSquareSide + getTextWidth(legendCtx, legendText) + 2 * padding; |
140 if (i < plots.length - 1) { | 142 if (i < plots.length - 1) { |
141 var xLocNext = xLoc + | 143 var xLocNext = xLoc + |
142 getTextWidth(legendCtx, getLegend(plots[i + 1].name)) + | 144 getTextWidth(legendCtx, getLegend(plots[i + 1].name)) + |
143 legendSquareSide; | 145 legendSquareSide; |
144 if (xLocNext >= legendCanvas.width) { | 146 if (xLocNext >= legendCanvas.width) { |
145 xLoc = padding; | 147 xLoc = padding; |
146 yLoc = yLoc + 2 * padding + textHeight; | 148 yLoc = yLoc + 2 * padding + textHeight; |
147 } | 149 } |
148 } | 150 } |
149 } | 151 } |
150 | 152 |
151 legendCanvas.height = yLoc + textHeight + padding; | 153 legendCanvas.height = yLoc + textHeight + padding; |
152 legendCanvas.style.height = | 154 legendCanvas.style.height = legendCanvas.height / devicePixelRatio + 'px'; |
153 legendCanvas.height / devicePixelRatio + 'px'; | |
154 | 155 |
155 xLoc = padding; | 156 xLoc = padding; |
156 yLoc = padding; | 157 yLoc = padding; |
157 // Go over the plots again, this time drawing the legends. | 158 // Go over the plots again, this time drawing the legends. |
158 for (var i = 0; i < plots.length; i++) { | 159 for (var i = 0; i < plots.length; i++) { |
159 legendCtx.fillStyle = plots[i].color; | 160 legendCtx.fillStyle = plots[i].color; |
160 legendCtx.fillRect(xLoc, yLoc, legendSquareSide, legendSquareSide); | 161 legendCtx.fillRect(xLoc, yLoc, legendSquareSide, legendSquareSide); |
161 xLoc += legendSquareSide; | 162 xLoc += legendSquareSide; |
162 | 163 |
163 var legendText = getLegend(plots[i].name); | 164 var legendText = getLegend(plots[i].name); |
164 drawText(legendCtx, legendText, xLoc, yLoc + textHeight - 1); | 165 drawText(legendCtx, legendText, xLoc, yLoc + textHeight - 1); |
165 xLoc += getTextWidth(legendCtx, legendText) + 2 * padding; | 166 xLoc += getTextWidth(legendCtx, legendText) + 2 * padding; |
166 | 167 |
167 if (i < plots.length - 1) { | 168 if (i < plots.length - 1) { |
168 var xLocNext = xLoc + | 169 var xLocNext = xLoc + |
169 getTextWidth(legendCtx, getLegend(plots[i + 1].name)) + | 170 getTextWidth(legendCtx, getLegend(plots[i + 1].name)) + |
170 legendSquareSide; | 171 legendSquareSide; |
171 if (xLocNext >= legendCanvas.width) { | 172 if (xLocNext >= legendCanvas.width) { |
172 xLoc = padding; | 173 xLoc = padding; |
173 yLoc = yLoc + 2 * padding + textHeight; | 174 yLoc = yLoc + 2 * padding + textHeight; |
174 } | 175 } |
175 } | 176 } |
176 } | 177 } |
177 } | 178 } |
178 | 179 |
179 var yMinStr = valueToString(yMin); | 180 var yMinStr = valueToString(yMin); |
180 var yMaxStr = valueToString(yMax); | 181 var yMaxStr = valueToString(yMax); |
181 var yHalfStr = valueToString((yMax + yMin) / 2); | 182 var yHalfStr = valueToString((yMax + yMin) / 2); |
182 var yMinWidth = getTextWidth(plotCtx, yMinStr); | 183 var yMinWidth = getTextWidth(plotCtx, yMinStr); |
183 var yMaxWidth = getTextWidth(plotCtx, yMaxStr); | 184 var yMaxWidth = getTextWidth(plotCtx, yMaxStr); |
184 var yHalfWidth = getTextWidth(plotCtx, yHalfStr); | 185 var yHalfWidth = getTextWidth(plotCtx, yHalfStr); |
185 | 186 |
186 var xMinStr = tData[0]; | 187 var xMinStr = tData[0]; |
187 var xMaxStr = tData[size - 1]; | 188 var xMaxStr = tData[size - 1]; |
188 var xMinWidth = getTextWidth(plotCtx, xMinStr); | 189 var xMinWidth = getTextWidth(plotCtx, xMinStr); |
189 var xMaxWidth = getTextWidth(plotCtx, xMaxStr); | 190 var xMaxWidth = getTextWidth(plotCtx, xMaxStr); |
190 | 191 |
191 var xOrigin = padding + Math.max(yMinWidth, | 192 var xOrigin = |
192 yMaxWidth, | 193 padding + Math.max(yMinWidth, yMaxWidth, Math.round(xMinWidth / 2)); |
193 Math.round(xMinWidth / 2)); | |
194 var yOrigin = padding + textHeight; | 194 var yOrigin = padding + textHeight; |
195 var width = plotCanvas.width - xOrigin - Math.floor(xMaxWidth / 2) - padding; | 195 var width = plotCanvas.width - xOrigin - Math.floor(xMaxWidth / 2) - padding; |
196 if (width < size) { | 196 if (width < size) { |
197 plotCanvas.width += size - width; | 197 plotCanvas.width += size - width; |
198 width = size; | 198 width = size; |
199 } | 199 } |
200 var height = plotCanvas.height - yOrigin - textHeight - padding; | 200 var height = plotCanvas.height - yOrigin - textHeight - padding; |
201 var linePlotEndMarkerWidth = 3; | 201 var linePlotEndMarkerWidth = 3; |
202 | 202 |
203 function drawPlots() { | 203 function drawPlots() { |
204 // Start fresh. | 204 // Start fresh. |
205 plotCtx.clearRect(0, 0, plotCanvas.width, plotCanvas.height); | 205 plotCtx.clearRect(0, 0, plotCanvas.width, plotCanvas.height); |
206 | 206 |
207 // Draw the bounding rectangle. | 207 // Draw the bounding rectangle. |
208 drawRect(plotCtx, xOrigin, yOrigin, width, height, gridColor); | 208 drawRect(plotCtx, xOrigin, yOrigin, width, height, gridColor); |
209 | 209 |
210 // Draw the x and y bound values. | 210 // Draw the x and y bound values. |
211 drawText(plotCtx, yMaxStr, xOrigin - yMaxWidth, yOrigin + textHeight); | 211 drawText(plotCtx, yMaxStr, xOrigin - yMaxWidth, yOrigin + textHeight); |
212 drawText(plotCtx, yMinStr, xOrigin - yMinWidth, yOrigin + height); | 212 drawText(plotCtx, yMinStr, xOrigin - yMinWidth, yOrigin + height); |
213 drawText(plotCtx, | 213 drawText( |
214 xMinStr, | 214 plotCtx, xMinStr, xOrigin - xMinWidth / 2, |
215 xOrigin - xMinWidth / 2, | 215 yOrigin + height + textHeight); |
216 yOrigin + height + textHeight); | 216 drawText( |
217 drawText(plotCtx, | 217 plotCtx, xMaxStr, xOrigin + width - xMaxWidth / 2, |
218 xMaxStr, | 218 yOrigin + height + textHeight); |
219 xOrigin + width - xMaxWidth / 2, | |
220 yOrigin + height + textHeight); | |
221 | 219 |
222 // Draw y-level (horizontal) lines. | 220 // Draw y-level (horizontal) lines. |
223 drawLine(plotCtx, | 221 drawLine( |
224 xOrigin + 1, yOrigin + height / 4, | 222 plotCtx, xOrigin + 1, yOrigin + height / 4, xOrigin + width - 2, |
225 xOrigin + width - 2, yOrigin + height / 4, | 223 yOrigin + height / 4, gridColor); |
226 gridColor); | 224 drawLine( |
227 drawLine(plotCtx, | 225 plotCtx, xOrigin + 1, yOrigin + height / 2, xOrigin + width - 2, |
228 xOrigin + 1, yOrigin + height / 2, | 226 yOrigin + height / 2, gridColor); |
229 xOrigin + width - 2, yOrigin + height / 2, gridColor); | 227 drawLine( |
230 drawLine(plotCtx, | 228 plotCtx, xOrigin + 1, yOrigin + 3 * height / 4, xOrigin + width - 2, |
231 xOrigin + 1, yOrigin + 3 * height / 4, | 229 yOrigin + 3 * height / 4, gridColor); |
232 xOrigin + width - 2, yOrigin + 3 * height / 4, | |
233 gridColor); | |
234 | 230 |
235 // Draw half-level value. | 231 // Draw half-level value. |
236 drawText(plotCtx, | 232 drawText( |
237 yHalfStr, | 233 plotCtx, yHalfStr, xOrigin - yHalfWidth, |
238 xOrigin - yHalfWidth, | 234 yOrigin + height / 2 + textHeight / 2); |
239 yOrigin + height / 2 + textHeight / 2); | |
240 | 235 |
241 // Draw the plots. | 236 // Draw the plots. |
242 var yValRange = yMax - yMin; | 237 var yValRange = yMax - yMin; |
243 for (var count = 0; count < plots.length; count++) { | 238 for (var count = 0; count < plots.length; count++) { |
244 var plot = plots[count]; | 239 var plot = plots[count]; |
245 var yData = plot.data; | 240 var yData = plot.data; |
246 plotCtx.strokeStyle = plot.color; | 241 plotCtx.strokeStyle = plot.color; |
247 plotCtx.lineWidth = 2; | 242 plotCtx.lineWidth = 2; |
248 plotCtx.beginPath(); | 243 plotCtx.beginPath(); |
249 var beginPath = true; | 244 var beginPath = true; |
250 for (var i = 0; i < size; i++) { | 245 for (var i = 0; i < size; i++) { |
251 var val = yData[i]; | 246 var val = yData[i]; |
252 if (typeof val === 'string') { | 247 if (typeof val === 'string') { |
253 // Stroke the plot drawn so far and begin a fresh plot. | 248 // Stroke the plot drawn so far and begin a fresh plot. |
254 plotCtx.stroke(); | 249 plotCtx.stroke(); |
255 plotCtx.beginPath(); | 250 plotCtx.beginPath(); |
256 beginPath = true; | 251 beginPath = true; |
257 continue; | 252 continue; |
258 } | 253 } |
259 var xPos = xOrigin + Math.floor(i / (size - 1) * (width - 1)); | 254 var xPos = xOrigin + Math.floor(i / (size - 1) * (width - 1)); |
260 var yPos = yOrigin + height - 1 - | 255 var yPos = yOrigin + height - 1 - |
261 Math.round((val - yMin) / yValRange * (height - 1)); | 256 Math.round((val - yMin) / yValRange * (height - 1)); |
262 if (beginPath) { | 257 if (beginPath) { |
263 plotCtx.moveTo(xPos, yPos); | 258 plotCtx.moveTo(xPos, yPos); |
264 // A simple move to does not print anything. Hence, draw a little | 259 // A simple move to does not print anything. Hence, draw a little |
265 // square here to mark a beginning. | 260 // square here to mark a beginning. |
266 plotCtx.fillStyle = '#000'; | 261 plotCtx.fillStyle = '#000'; |
267 plotCtx.fillRect(xPos - linePlotEndMarkerWidth, | 262 plotCtx.fillRect( |
268 yPos - linePlotEndMarkerWidth, | 263 xPos - linePlotEndMarkerWidth, yPos - linePlotEndMarkerWidth, |
269 linePlotEndMarkerWidth * devicePixelRatio, | 264 linePlotEndMarkerWidth * devicePixelRatio, |
270 linePlotEndMarkerWidth * devicePixelRatio); | 265 linePlotEndMarkerWidth * devicePixelRatio); |
271 beginPath = false; | 266 beginPath = false; |
272 } else { | 267 } else { |
273 plotCtx.lineTo(xPos, yPos); | 268 plotCtx.lineTo(xPos, yPos); |
274 if (i === size - 1 || typeof yData[i + 1] === 'string') { | 269 if (i === size - 1 || typeof yData[i + 1] === 'string') { |
275 // Draw a little square to mark an end to go with the start | 270 // Draw a little square to mark an end to go with the start |
276 // markers from above. | 271 // markers from above. |
277 plotCtx.fillStyle = '#000'; | 272 plotCtx.fillStyle = '#000'; |
278 plotCtx.fillRect(xPos - linePlotEndMarkerWidth, | 273 plotCtx.fillRect( |
279 yPos - linePlotEndMarkerWidth, | 274 xPos - linePlotEndMarkerWidth, yPos - linePlotEndMarkerWidth, |
280 linePlotEndMarkerWidth * devicePixelRatio, | 275 linePlotEndMarkerWidth * devicePixelRatio, |
281 linePlotEndMarkerWidth * devicePixelRatio); | 276 linePlotEndMarkerWidth * devicePixelRatio); |
282 } | 277 } |
283 } | 278 } |
284 } | 279 } |
285 plotCtx.stroke(); | 280 plotCtx.stroke(); |
286 } | 281 } |
287 | 282 |
288 // Paint the missing time intervals with |gridColor|. | 283 // Paint the missing time intervals with |gridColor|. |
289 // Pick one of the plots to look for missing time intervals. | 284 // Pick one of the plots to look for missing time intervals. |
290 function drawMissingRect(start, end) { | 285 function drawMissingRect(start, end) { |
291 var xLeft = xOrigin + Math.floor(start / (size - 1) * (width - 1)); | 286 var xLeft = xOrigin + Math.floor(start / (size - 1) * (width - 1)); |
(...skipping 21 matching lines...) Expand all Loading... |
313 } else if (inMissingInterval) { | 308 } else if (inMissingInterval) { |
314 inMissingInterval = false; | 309 inMissingInterval = false; |
315 drawMissingRect(intervalStart, i); | 310 drawMissingRect(intervalStart, i); |
316 } | 311 } |
317 } | 312 } |
318 } | 313 } |
319 | 314 |
320 function drawTimeGuide(tDataIndex) { | 315 function drawTimeGuide(tDataIndex) { |
321 var x = xOrigin + tDataIndex / (size - 1) * (width - 1); | 316 var x = xOrigin + tDataIndex / (size - 1) * (width - 1); |
322 drawLine(plotCtx, x, yOrigin, x, yOrigin + height - 1, '#000'); | 317 drawLine(plotCtx, x, yOrigin, x, yOrigin + height - 1, '#000'); |
323 drawText(plotCtx, | 318 drawText( |
324 tData[tDataIndex], | 319 plotCtx, tData[tDataIndex], |
325 x - getTextWidth(plotCtx, tData[tDataIndex]) / 2, | 320 x - getTextWidth(plotCtx, tData[tDataIndex]) / 2, yOrigin - 2); |
326 yOrigin - 2); | |
327 | 321 |
328 for (var count = 0; count < plots.length; count++) { | 322 for (var count = 0; count < plots.length; count++) { |
329 var yData = plots[count].data; | 323 var yData = plots[count].data; |
330 | 324 |
331 // Draw small black square on the plot where the time guide intersects | 325 // Draw small black square on the plot where the time guide intersects |
332 // it. | 326 // it. |
333 var val = yData[tDataIndex]; | 327 var val = yData[tDataIndex]; |
334 var yPos, valStr; | 328 var yPos, valStr; |
335 if (typeof val === 'string') { | 329 if (typeof val === 'string') { |
336 yPos = yOrigin + Math.round(height / 2); | 330 yPos = yOrigin + Math.round(height / 2); |
(...skipping 18 matching lines...) Expand all Loading... |
355 drawHighlightText(plotCtx, valStr, x + 5, yLoc, plots[count].color); | 349 drawHighlightText(plotCtx, valStr, x + 5, yLoc, plots[count].color); |
356 } | 350 } |
357 } | 351 } |
358 | 352 |
359 function onMouseOverOrMove(event) { | 353 function onMouseOverOrMove(event) { |
360 drawPlots(); | 354 drawPlots(); |
361 | 355 |
362 var boundingRect = plotCanvas.getBoundingClientRect(); | 356 var boundingRect = plotCanvas.getBoundingClientRect(); |
363 var x = Math.round((event.clientX - boundingRect.left) * devicePixelRatio); | 357 var x = Math.round((event.clientX - boundingRect.left) * devicePixelRatio); |
364 var y = Math.round((event.clientY - boundingRect.top) * devicePixelRatio); | 358 var y = Math.round((event.clientY - boundingRect.top) * devicePixelRatio); |
365 if (x < xOrigin || x >= xOrigin + width || | 359 if (x < xOrigin || x >= xOrigin + width || y < yOrigin || |
366 y < yOrigin || y >= yOrigin + height) { | 360 y >= yOrigin + height) { |
367 return; | 361 return; |
368 } | 362 } |
369 | 363 |
370 if (width == size) { | 364 if (width == size) { |
371 drawTimeGuide(x - xOrigin); | 365 drawTimeGuide(x - xOrigin); |
372 } else { | 366 } else { |
373 drawTimeGuide(Math.round((x - xOrigin) / (width - 1) * (size - 1))); | 367 drawTimeGuide(Math.round((x - xOrigin) / (width - 1) * (size - 1))); |
374 } | 368 } |
375 } | 369 } |
376 | 370 |
377 function onMouseOut(event) { | 371 function onMouseOut(event) { |
378 drawPlots(); | 372 drawPlots(); |
379 } | 373 } |
380 | 374 |
381 drawLegend(); | 375 drawLegend(); |
382 drawPlots(); | 376 drawPlots(); |
383 plotCanvas.addEventListener('mouseover', onMouseOverOrMove); | 377 plotCanvas.addEventListener('mouseover', onMouseOverOrMove); |
384 plotCanvas.addEventListener('mousemove', onMouseOverOrMove); | 378 plotCanvas.addEventListener('mousemove', onMouseOverOrMove); |
385 plotCanvas.addEventListener('mouseout', onMouseOut); | 379 plotCanvas.addEventListener('mouseout', onMouseOut); |
386 } | 380 } |
387 | 381 |
388 var sleepSampleInterval = 30 * 1000; // in milliseconds. | 382 var sleepSampleInterval = 30 * 1000; // in milliseconds. |
389 var sleepText = loadTimeData.getString('systemSuspended'); | 383 var sleepText = loadTimeData.getString('systemSuspended'); |
390 var invalidDataText = loadTimeData.getString('invalidData'); | 384 var invalidDataText = loadTimeData.getString('invalidData'); |
391 var offlineText = loadTimeData.getString('offlineText'); | 385 var offlineText = loadTimeData.getString('offlineText'); |
392 | 386 |
393 var plotColors = ['Red', 'Blue', 'Green', 'Gold', 'CadetBlue', 'LightCoral', | 387 var plotColors = [ |
394 'LightSlateGray', 'Peru', 'DarkRed', 'LawnGreen', 'Tan']; | 388 'Red', 'Blue', 'Green', 'Gold', 'CadetBlue', 'LightCoral', 'LightSlateGray', |
| 389 'Peru', 'DarkRed', 'LawnGreen', 'Tan' |
| 390 ]; |
395 | 391 |
396 /** | 392 /** |
397 * Add canvases for plotting to |plotsDiv|. For every header in |headerArray|, | 393 * Add canvases for plotting to |plotsDiv|. For every header in |headerArray|, |
398 * one canvas for the plot and one for its legend are added. | 394 * one canvas for the plot and one for its legend are added. |
399 * | 395 * |
400 * @param {Array<string>} headerArray Headers for the different plots to be | 396 * @param {Array<string>} headerArray Headers for the different plots to be |
401 * added to |plotsDiv|. | 397 * added to |plotsDiv|. |
402 * @param {HTMLDivElement} plotsDiv The div element into which the canvases | 398 * @param {HTMLDivElement} plotsDiv The div element into which the canvases |
403 * are added. | 399 * are added. |
404 * @return {<string>: {plotCanvas: <HTMLCanvasElement>, | 400 * @return {<string>: {plotCanvas: <HTMLCanvasElement>, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 * @param {number} sampleTime Time in milliseconds since the epoch when the | 454 * @param {number} sampleTime Time in milliseconds since the epoch when the |
459 * samples in |sampleArray| were captured. | 455 * samples in |sampleArray| were captured. |
460 * @param {number} previousSampleTime Time in milliseconds since the epoch | 456 * @param {number} previousSampleTime Time in milliseconds since the epoch |
461 * when the sample prior to the current sample was captured. | 457 * when the sample prior to the current sample was captured. |
462 * @param {Array<{time: number, sleepDuration: number}>} systemResumedArray An | 458 * @param {Array<{time: number, sleepDuration: number}>} systemResumedArray An |
463 * array objects corresponding to system resume events. The 'time' field is | 459 * array objects corresponding to system resume events. The 'time' field is |
464 * for the time in milliseconds since the epoch when the system resumed. The | 460 * for the time in milliseconds since the epoch when the system resumed. The |
465 * 'sleepDuration' field is for the time in milliseconds the system spent | 461 * 'sleepDuration' field is for the time in milliseconds the system spent |
466 * in sleep/suspend state. | 462 * in sleep/suspend state. |
467 */ | 463 */ |
468 function addTimeDataSample(plots, tData, absTime, sampleArray, | 464 function addTimeDataSample( |
469 sampleTime, previousSampleTime, | 465 plots, tData, absTime, sampleArray, sampleTime, previousSampleTime, |
470 systemResumedArray) { | 466 systemResumedArray) { |
471 for (var i = 0; i < plots.length; i++) { | 467 for (var i = 0; i < plots.length; i++) { |
472 if (plots[i].data.length != tData.length) { | 468 if (plots[i].data.length != tData.length) { |
473 throw new Error('Mismatch in time and plot data.'); | 469 throw new Error('Mismatch in time and plot data.'); |
474 } | 470 } |
475 } | 471 } |
476 | 472 |
477 var time; | 473 var time; |
478 if (tData.length == 0) { | 474 if (tData.length == 0) { |
479 time = new Date(sampleTime); | 475 time = new Date(sampleTime); |
480 absTime[0] = sampleTime; | 476 absTime[0] = sampleTime; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 * @param {Array<{time: ?, sleepDuration: ?}>} systemResumedArray An array | 526 * @param {Array<{time: ?, sleepDuration: ?}>} systemResumedArray An array |
531 * objects with fields 'time' and 'sleepDuration'. Each object corresponds | 527 * objects with fields 'time' and 'sleepDuration'. Each object corresponds |
532 * to a system resume event. The 'time' field is for the time in | 528 * to a system resume event. The 'time' field is for the time in |
533 * milliseconds since the epoch when the system resumed. The 'sleepDuration' | 529 * milliseconds since the epoch when the system resumed. The 'sleepDuration' |
534 * field is for the time in milliseconds the system spent in sleep/suspend | 530 * field is for the time in milliseconds the system spent in sleep/suspend |
535 * state. | 531 * state. |
536 */ | 532 */ |
537 function showBatteryChargeData(powerSupplyArray, systemResumedArray) { | 533 function showBatteryChargeData(powerSupplyArray, systemResumedArray) { |
538 var chargeTimeData = []; | 534 var chargeTimeData = []; |
539 var chargeAbsTime = []; | 535 var chargeAbsTime = []; |
540 var chargePlot = [ | 536 var chargePlot = [{ |
541 { | 537 name: loadTimeData.getString('batteryChargePercentageHeader'), |
542 name: loadTimeData.getString('batteryChargePercentageHeader'), | 538 color: 'Blue', |
543 color: 'Blue', | 539 data: [] |
544 data: [] | 540 }]; |
545 } | |
546 ]; | |
547 var dischargeRateTimeData = []; | 541 var dischargeRateTimeData = []; |
548 var dischargeRateAbsTime = []; | 542 var dischargeRateAbsTime = []; |
549 var dischargeRatePlot = [ | 543 var dischargeRatePlot = [ |
550 { | 544 { |
551 name: loadTimeData.getString('dischargeRateLegendText'), | 545 name: loadTimeData.getString('dischargeRateLegendText'), |
552 color: 'Red', | 546 color: 'Red', |
553 data: [] | 547 data: [] |
554 }, | 548 }, |
555 { | 549 { |
556 name: loadTimeData.getString('movingAverageLegendText'), | 550 name: loadTimeData.getString('movingAverageLegendText'), |
557 color: 'Green', | 551 color: 'Green', |
558 data: [] | 552 data: [] |
559 }, | 553 }, |
560 { | 554 { |
561 name: loadTimeData.getString('binnedAverageLegendText'), | 555 name: loadTimeData.getString('binnedAverageLegendText'), |
562 color: 'Blue', | 556 color: 'Blue', |
563 data: [] | 557 data: [] |
564 } | 558 } |
565 ]; | 559 ]; |
566 var minDischargeRate = 1000; // A high unrealistic number to begin with. | 560 var minDischargeRate = 1000; // A high unrealistic number to begin with. |
567 var maxDischargeRate = -1000; // A low unrealistic number to begin with. | 561 var maxDischargeRate = -1000; // A low unrealistic number to begin with. |
568 for (var i = 0; i < powerSupplyArray.length; i++) { | 562 for (var i = 0; i < powerSupplyArray.length; i++) { |
569 var j = Math.max(i - 1, 0); | 563 var j = Math.max(i - 1, 0); |
570 | 564 |
571 addTimeDataSample(chargePlot, | 565 addTimeDataSample( |
572 chargeTimeData, | 566 chargePlot, chargeTimeData, chargeAbsTime, |
573 chargeAbsTime, | 567 [powerSupplyArray[i].batteryPercent], powerSupplyArray[i].time, |
574 [powerSupplyArray[i].batteryPercent], | 568 powerSupplyArray[j].time, systemResumedArray); |
575 powerSupplyArray[i].time, | |
576 powerSupplyArray[j].time, | |
577 systemResumedArray); | |
578 | 569 |
579 var dischargeRate = powerSupplyArray[i].batteryDischargeRate; | 570 var dischargeRate = powerSupplyArray[i].batteryDischargeRate; |
580 var inputSampleCount = $('sample-count-input').value; | 571 var inputSampleCount = $('sample-count-input').value; |
581 | 572 |
582 var movingAverage = 0; | 573 var movingAverage = 0; |
583 var k = 0; | 574 var k = 0; |
584 for (k = 0; k < inputSampleCount && i - k >= 0; k++) { | 575 for (k = 0; k < inputSampleCount && i - k >= 0; k++) { |
585 movingAverage += powerSupplyArray[i - k].batteryDischargeRate; | 576 movingAverage += powerSupplyArray[i - k].batteryDischargeRate; |
586 } | 577 } |
587 // |k| will be atleast 1 because the 'min' value of the input field is 1. | 578 // |k| will be atleast 1 because the 'min' value of the input field is 1. |
588 movingAverage /= k; | 579 movingAverage /= k; |
589 | 580 |
590 var binnedAverage = 0; | 581 var binnedAverage = 0; |
591 for (k = 0; k < inputSampleCount; k++) { | 582 for (k = 0; k < inputSampleCount; k++) { |
592 var currentSampleIndex = i - i % inputSampleCount + k; | 583 var currentSampleIndex = i - i % inputSampleCount + k; |
593 if (currentSampleIndex >= powerSupplyArray.length) { | 584 if (currentSampleIndex >= powerSupplyArray.length) { |
594 break; | 585 break; |
595 } | 586 } |
596 | 587 |
597 binnedAverage += | 588 binnedAverage += |
598 powerSupplyArray[currentSampleIndex].batteryDischargeRate; | 589 powerSupplyArray[currentSampleIndex].batteryDischargeRate; |
599 } | 590 } |
600 binnedAverage /= k; | 591 binnedAverage /= k; |
601 | 592 |
602 minDischargeRate = Math.min(dischargeRate, minDischargeRate); | 593 minDischargeRate = Math.min(dischargeRate, minDischargeRate); |
603 maxDischargeRate = Math.max(dischargeRate, maxDischargeRate); | 594 maxDischargeRate = Math.max(dischargeRate, maxDischargeRate); |
604 addTimeDataSample(dischargeRatePlot, | 595 addTimeDataSample( |
605 dischargeRateTimeData, | 596 dischargeRatePlot, dischargeRateTimeData, dischargeRateAbsTime, |
606 dischargeRateAbsTime, | 597 [dischargeRate, movingAverage, binnedAverage], powerSupplyArray[i].time, |
607 [dischargeRate, movingAverage, binnedAverage], | 598 powerSupplyArray[j].time, systemResumedArray); |
608 powerSupplyArray[i].time, | |
609 powerSupplyArray[j].time, | |
610 systemResumedArray); | |
611 } | 599 } |
612 if (minDischargeRate == maxDischargeRate) { | 600 if (minDischargeRate == maxDischargeRate) { |
613 // This means that all the samples had the same value. Hence, offset the | 601 // This means that all the samples had the same value. Hence, offset the |
614 // extremes by a bit so that the plot looks good. | 602 // extremes by a bit so that the plot looks good. |
615 minDischargeRate -= 1; | 603 minDischargeRate -= 1; |
616 maxDischargeRate += 1; | 604 maxDischargeRate += 1; |
617 } | 605 } |
618 | 606 |
619 plotsDiv = $('battery-charge-plots-div'); | 607 plotsDiv = $('battery-charge-plots-div'); |
620 | 608 |
621 canvases = addCanvases( | 609 canvases = addCanvases( |
622 [loadTimeData.getString('batteryChargePercentageHeader'), | 610 [ |
623 loadTimeData.getString('batteryDischargeRateHeader')], | 611 loadTimeData.getString('batteryChargePercentageHeader'), |
| 612 loadTimeData.getString('batteryDischargeRateHeader') |
| 613 ], |
624 plotsDiv); | 614 plotsDiv); |
625 | 615 |
626 batteryChargeCanvases = canvases[ | 616 batteryChargeCanvases = |
627 loadTimeData.getString('batteryChargePercentageHeader')]; | 617 canvases[loadTimeData.getString('batteryChargePercentageHeader')]; |
628 plotLineGraph( | 618 plotLineGraph( |
629 batteryChargeCanvases['plot'], | 619 batteryChargeCanvases['plot'], batteryChargeCanvases['legend'], |
630 batteryChargeCanvases['legend'], | 620 chargeTimeData, chargePlot, 0.00, 100.00, 3); |
631 chargeTimeData, | |
632 chargePlot, | |
633 0.00, | |
634 100.00, | |
635 3); | |
636 | 621 |
637 dischargeRateCanvases = canvases[ | 622 dischargeRateCanvases = |
638 loadTimeData.getString('batteryDischargeRateHeader')]; | 623 canvases[loadTimeData.getString('batteryDischargeRateHeader')]; |
639 plotLineGraph( | 624 plotLineGraph( |
640 dischargeRateCanvases['plot'], | 625 dischargeRateCanvases['plot'], dischargeRateCanvases['legend'], |
641 dischargeRateCanvases['legend'], | 626 dischargeRateTimeData, dischargeRatePlot, minDischargeRate, |
642 dischargeRateTimeData, | 627 maxDischargeRate, 3); |
643 dischargeRatePlot, | |
644 minDischargeRate, | |
645 maxDischargeRate, | |
646 3); | |
647 } | 628 } |
648 | 629 |
649 /** | 630 /** |
650 * Shows state occupancy data (CPU idle or CPU freq state occupancy) on a set of | 631 * Shows state occupancy data (CPU idle or CPU freq state occupancy) on a set of |
651 * plots on the about:power UI. | 632 * plots on the about:power UI. |
652 * | 633 * |
653 * @param {Array<Array<{ | 634 * @param {Array<Array<{ |
654 * time: number, | 635 * time: number, |
655 * cpuOnline: boolean, | 636 * cpuOnline: boolean, |
656 * timeInState: Object<number>}>} timeInStateData Array of arrays | 637 * timeInState: Object<number>}>} timeInStateData Array of arrays |
657 * where each array corresponds to a CPU on the system. The elements of the | 638 * where each array corresponds to a CPU on the system. The elements of the |
658 * individual arrays contain state occupancy samples. | 639 * individual arrays contain state occupancy samples. |
659 * @param {Array<{time: ?, sleepDuration: ?}>} systemResumedArray An array | 640 * @param {Array<{time: ?, sleepDuration: ?}>} systemResumedArray An array |
660 * objects with fields 'time' and 'sleepDuration'. Each object corresponds | 641 * objects with fields 'time' and 'sleepDuration'. Each object corresponds |
661 * to a system resume event. The 'time' field is for the time in | 642 * to a system resume event. The 'time' field is for the time in |
662 * milliseconds since the epoch when the system resumed. The 'sleepDuration' | 643 * milliseconds since the epoch when the system resumed. The 'sleepDuration' |
663 * field is for the time in milliseconds the system spent in sleep/suspend | 644 * field is for the time in milliseconds the system spent in sleep/suspend |
664 * state. | 645 * state. |
665 * @param {string} i18nHeaderString The header string to be displayed with each | 646 * @param {string} i18nHeaderString The header string to be displayed with each |
666 * plot. For example, CPU idle data will have its own header format, and CPU | 647 * plot. For example, CPU idle data will have its own header format, and CPU |
667 * freq data will have its header format. | 648 * freq data will have its header format. |
668 * @param {string} unitString This is the string capturing the unit, if any, | 649 * @param {string} unitString This is the string capturing the unit, if any, |
669 * for the different states. Note that this is not the unit of the data | 650 * for the different states. Note that this is not the unit of the data |
670 * being plotted. | 651 * being plotted. |
671 * @param {HTMLDivElement} plotsDivId The div element in which the plots should | 652 * @param {HTMLDivElement} plotsDivId The div element in which the plots should |
672 * be added. | 653 * be added. |
673 */ | 654 */ |
674 function showStateOccupancyData(timeInStateData, | 655 function showStateOccupancyData( |
675 systemResumedArray, | 656 timeInStateData, systemResumedArray, i18nHeaderString, unitString, |
676 i18nHeaderString, | 657 plotsDivId) { |
677 unitString, | |
678 plotsDivId) { | |
679 var cpuPlots = []; | 658 var cpuPlots = []; |
680 for (var cpu = 0; cpu < timeInStateData.length; cpu++) { | 659 for (var cpu = 0; cpu < timeInStateData.length; cpu++) { |
681 var cpuData = timeInStateData[cpu]; | 660 var cpuData = timeInStateData[cpu]; |
682 if (cpuData.length == 0) { | 661 if (cpuData.length == 0) { |
683 cpuPlots[cpu] = {plots: [], tData: []}; | 662 cpuPlots[cpu] = {plots: [], tData: []}; |
684 continue; | 663 continue; |
685 } | 664 } |
686 tData = []; | 665 tData = []; |
687 absTime = []; | 666 absTime = []; |
688 // Each element of |plots| is an array of samples, one for each of the CPU | 667 // Each element of |plots| is an array of samples, one for each of the CPU |
689 // states. The number of states is dicovered by looking at the first | 668 // states. The number of states is dicovered by looking at the first |
690 // sample for which the CPU is online. | 669 // sample for which the CPU is online. |
691 var plots = []; | 670 var plots = []; |
692 var stateIndexMap = []; | 671 var stateIndexMap = []; |
693 var stateCount = 0; | 672 var stateCount = 0; |
694 for (var i = 0; i < cpuData.length; i++) { | 673 for (var i = 0; i < cpuData.length; i++) { |
695 if (cpuData[i].cpuOnline) { | 674 if (cpuData[i].cpuOnline) { |
696 for (var state in cpuData[i].timeInState) { | 675 for (var state in cpuData[i].timeInState) { |
697 var stateName = state; | 676 var stateName = state; |
698 if (unitString != null) { | 677 if (unitString != null) { |
699 stateName += ' ' + unitString; | 678 stateName += ' ' + unitString; |
700 } | 679 } |
701 plots.push({ | 680 plots.push( |
702 name: stateName, | 681 {name: stateName, data: [], color: plotColors[stateCount]}); |
703 data: [], | |
704 color: plotColors[stateCount] | |
705 }); | |
706 stateIndexMap.push(state); | 682 stateIndexMap.push(state); |
707 stateCount += 1; | 683 stateCount += 1; |
708 } | 684 } |
709 break; | 685 break; |
710 } | 686 } |
711 } | 687 } |
712 // If stateCount is 0, then it means the CPU has been offline | 688 // If stateCount is 0, then it means the CPU has been offline |
713 // throughout. Just add a single plot for such a case. | 689 // throughout. Just add a single plot for such a case. |
714 if (stateCount == 0) { | 690 if (stateCount == 0) { |
715 plots.push({ | 691 plots.push({name: null, data: [], color: null}); |
716 name: null, | 692 stateCount = 1; // Some invalid state! |
717 data: [], | |
718 color: null | |
719 }); | |
720 stateCount = 1; // Some invalid state! | |
721 } | 693 } |
722 | 694 |
723 // Pass the samples through the function addTimeDataSample to add 'sleep' | 695 // Pass the samples through the function addTimeDataSample to add 'sleep' |
724 // samples. | 696 // samples. |
725 for (var i = 0; i < cpuData.length; i++) { | 697 for (var i = 0; i < cpuData.length; i++) { |
726 var sample = cpuData[i]; | 698 var sample = cpuData[i]; |
727 var valArray = []; | 699 var valArray = []; |
728 for (var j = 0; j < stateCount; j++) { | 700 for (var j = 0; j < stateCount; j++) { |
729 if (sample.cpuOnline) { | 701 if (sample.cpuOnline) { |
730 valArray[j] = sample.timeInState[stateIndexMap[j]]; | 702 valArray[j] = sample.timeInState[stateIndexMap[j]]; |
731 } else { | 703 } else { |
732 valArray[j] = offlineText; | 704 valArray[j] = offlineText; |
733 } | 705 } |
734 } | 706 } |
735 | 707 |
736 var k = Math.max(i - 1, 0); | 708 var k = Math.max(i - 1, 0); |
737 addTimeDataSample(plots, | 709 addTimeDataSample( |
738 tData, | 710 plots, tData, absTime, valArray, sample.time, cpuData[k].time, |
739 absTime, | 711 systemResumedArray); |
740 valArray, | |
741 sample.time, | |
742 cpuData[k].time, | |
743 systemResumedArray); | |
744 } | 712 } |
745 | 713 |
746 // Calculate the percentage occupancy of each state. A valid number is | 714 // Calculate the percentage occupancy of each state. A valid number is |
747 // possible only if two consecutive samples are valid/numbers. | 715 // possible only if two consecutive samples are valid/numbers. |
748 for (var k = 0; k < stateCount; k++) { | 716 for (var k = 0; k < stateCount; k++) { |
749 var stateData = plots[k].data; | 717 var stateData = plots[k].data; |
750 // Skip the first sample as there is no previous sample. | 718 // Skip the first sample as there is no previous sample. |
751 for (var i = stateData.length - 1; i > 0; i--) { | 719 for (var i = stateData.length - 1; i > 0; i--) { |
752 if (typeof stateData[i] === 'number') { | 720 if (typeof stateData[i] === 'number') { |
753 if (typeof stateData[i - 1] === 'number') { | 721 if (typeof stateData[i - 1] === 'number') { |
754 stateData[i] = (stateData[i] - stateData[i - 1]) / | 722 stateData[i] = (stateData[i] - stateData[i - 1]) / |
755 (absTime[i] - absTime[i - 1]) * 100; | 723 (absTime[i] - absTime[i - 1]) * 100; |
756 } else { | 724 } else { |
757 stateData[i] = invalidDataText; | 725 stateData[i] = invalidDataText; |
758 } | 726 } |
759 } | 727 } |
760 } | 728 } |
761 } | 729 } |
762 | 730 |
763 // Remove the first sample from the time and data arrays. | 731 // Remove the first sample from the time and data arrays. |
764 tData.shift(); | 732 tData.shift(); |
765 for (var k = 0; k < stateCount; k++) { | 733 for (var k = 0; k < stateCount; k++) { |
766 plots[k].data.shift(); | 734 plots[k].data.shift(); |
767 } | 735 } |
768 cpuPlots[cpu] = {plots: plots, tData: tData}; | 736 cpuPlots[cpu] = {plots: plots, tData: tData}; |
769 } | 737 } |
770 | 738 |
771 headers = []; | 739 headers = []; |
772 for (var cpu = 0; cpu < timeInStateData.length; cpu++) { | 740 for (var cpu = 0; cpu < timeInStateData.length; cpu++) { |
773 headers[cpu] = | 741 headers[cpu] = |
774 'CPU ' + cpu + ' ' + loadTimeData.getString(i18nHeaderString); | 742 'CPU ' + cpu + ' ' + loadTimeData.getString(i18nHeaderString); |
775 } | 743 } |
776 | 744 |
777 canvases = addCanvases(headers, $(plotsDivId)); | 745 canvases = addCanvases(headers, $(plotsDivId)); |
778 for (var cpu = 0; cpu < timeInStateData.length; cpu++) { | 746 for (var cpu = 0; cpu < timeInStateData.length; cpu++) { |
779 cpuCanvases = canvases[headers[cpu]]; | 747 cpuCanvases = canvases[headers[cpu]]; |
780 plotLineGraph(cpuCanvases['plot'], | 748 plotLineGraph( |
781 cpuCanvases['legend'], | 749 cpuCanvases['plot'], cpuCanvases['legend'], cpuPlots[cpu]['tData'], |
782 cpuPlots[cpu]['tData'], | 750 cpuPlots[cpu]['plots'], 0, 100, 3); |
783 cpuPlots[cpu]['plots'], | |
784 0, | |
785 100, | |
786 3); | |
787 } | 751 } |
788 } | 752 } |
789 | 753 |
790 function showCpuIdleData(idleStateData, systemResumedArray) { | 754 function showCpuIdleData(idleStateData, systemResumedArray) { |
791 showStateOccupancyData(idleStateData, | 755 showStateOccupancyData( |
792 systemResumedArray, | 756 idleStateData, systemResumedArray, 'idleStateOccupancyPercentageHeader', |
793 'idleStateOccupancyPercentageHeader', | 757 null, 'cpu-idle-plots-div'); |
794 null, | |
795 'cpu-idle-plots-div'); | |
796 } | 758 } |
797 | 759 |
798 function showCpuFreqData(freqStateData, systemResumedArray) { | 760 function showCpuFreqData(freqStateData, systemResumedArray) { |
799 showStateOccupancyData(freqStateData, | 761 showStateOccupancyData( |
800 systemResumedArray, | 762 freqStateData, systemResumedArray, |
801 'frequencyStateOccupancyPercentageHeader', | 763 'frequencyStateOccupancyPercentageHeader', 'MHz', 'cpu-freq-plots-div'); |
802 'MHz', | |
803 'cpu-freq-plots-div'); | |
804 } | 764 } |
805 | 765 |
806 function requestBatteryChargeData() { | 766 function requestBatteryChargeData() { |
807 chrome.send('requestBatteryChargeData'); | 767 chrome.send('requestBatteryChargeData'); |
808 } | 768 } |
809 | 769 |
810 function requestCpuIdleData() { | 770 function requestCpuIdleData() { |
811 chrome.send('requestCpuIdleData'); | 771 chrome.send('requestCpuIdleData'); |
812 } | 772 } |
813 | 773 |
(...skipping 27 matching lines...) Expand all Loading... |
841 | 801 |
842 var powerUI = { | 802 var powerUI = { |
843 showBatteryChargeData: showBatteryChargeData, | 803 showBatteryChargeData: showBatteryChargeData, |
844 showCpuIdleData: showCpuIdleData, | 804 showCpuIdleData: showCpuIdleData, |
845 showCpuFreqData: showCpuFreqData | 805 showCpuFreqData: showCpuFreqData |
846 }; | 806 }; |
847 | 807 |
848 document.addEventListener('DOMContentLoaded', function() { | 808 document.addEventListener('DOMContentLoaded', function() { |
849 $('battery-charge-section').hidden = true; | 809 $('battery-charge-section').hidden = true; |
850 $('battery-charge-show-button').onclick = showHideCallback( | 810 $('battery-charge-show-button').onclick = showHideCallback( |
851 'battery-charge-section', | 811 'battery-charge-section', 'battery-charge-show-button', |
852 'battery-charge-show-button', | |
853 requestBatteryChargeData); | 812 requestBatteryChargeData); |
854 $('battery-charge-reload-button').onclick = requestBatteryChargeData; | 813 $('battery-charge-reload-button').onclick = requestBatteryChargeData; |
855 $('sample-count-input').onclick = requestBatteryChargeData; | 814 $('sample-count-input').onclick = requestBatteryChargeData; |
856 | 815 |
857 $('cpu-idle-section').hidden = true; | 816 $('cpu-idle-section').hidden = true; |
858 $('cpu-idle-show-button').onclick = showHideCallback( | 817 $('cpu-idle-show-button').onclick = showHideCallback( |
859 'cpu-idle-section', 'cpu-idle-show-button', requestCpuIdleData); | 818 'cpu-idle-section', 'cpu-idle-show-button', requestCpuIdleData); |
860 $('cpu-idle-reload-button').onclick = requestCpuIdleData; | 819 $('cpu-idle-reload-button').onclick = requestCpuIdleData; |
861 | 820 |
862 $('cpu-freq-section').hidden = true; | 821 $('cpu-freq-section').hidden = true; |
863 $('cpu-freq-show-button').onclick = showHideCallback( | 822 $('cpu-freq-show-button').onclick = showHideCallback( |
864 'cpu-freq-section', 'cpu-freq-show-button', requestCpuFreqData); | 823 'cpu-freq-section', 'cpu-freq-show-button', requestCpuFreqData); |
865 $('cpu-freq-reload-button').onclick = requestCpuFreqData; | 824 $('cpu-freq-reload-button').onclick = requestCpuFreqData; |
866 }); | 825 }); |
OLD | NEW |