| Index: chrome/browser/resources/chromeos/power.js
|
| diff --git a/chrome/browser/resources/chromeos/power.js b/chrome/browser/resources/chromeos/power.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ba919cff85b8543199f92abaff81daf3978e2370
|
| --- /dev/null
|
| +++ b/chrome/browser/resources/chromeos/power.js
|
| @@ -0,0 +1,268 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| + /**
|
| + * Plot a line graph of data versus time on a HTML canvas element.
|
| + *
|
| + * @param {HTMLCanvasElement} canvas The canvas on which the line graph is
|
| + * drawn.
|
| + * @param {Array.<number>} tData The time (in seconds) in the past when the
|
| + * corresponding data in plots was sampled.
|
| + * @param {Array.<Object>} plots An array of objects with fields 'data' and
|
| + * 'color'. The field 'data' is an array of samples to be plotted as a
|
| + * line graph with 'color'. The elements in the 'data' array are ordered
|
| + * corresponding to their sampling time in the argument 'tData'. Also,
|
| + * the number of elements in the data array should be the same as in the
|
| + * time array 'tData' above.
|
| + * @param {number} yMin Minimum bound of y-axis
|
| + * @param {number} yMax Maximum bound of y-axis.
|
| + * @param {integer} yPrecision An integer value representing the number of
|
| + * digits of precision the y-axis data should be printed with.
|
| + */
|
| +function plotLineGraph(canvas, tData, plots, yMin, yMax, yPrecision) {
|
| + var textFont = '12px Arial';
|
| + var textHeight = 12;
|
| + var padding = 5; // Pixels
|
| + var errorOffsetPixels = 15;
|
| + var gridColor = '#ccc';
|
| + var ctx = canvas.getContext('2d');
|
| + var size = tData.length;
|
| +
|
| + function drawText(text, x, y) {
|
| + ctx.font = textFont;
|
| + ctx.fillStyle = '#000';
|
| + ctx.fillText(text, x, y);
|
| + }
|
| +
|
| + function printErrorText(text) {
|
| + ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| + drawText(text, errorOffsetPixels, errorOffsetPixels);
|
| + }
|
| +
|
| + if (size < 2) {
|
| + printErrorText(loadTimeData.getString('notEnoughDataAvailableYet'));
|
| + return;
|
| + }
|
| +
|
| + for (var count = 0; count < plots.length; count++) {
|
| + if (plots[count].data.length != size) {
|
| + printErrorText(loadTimeData.getString('timeAndPlotDataMismatch'));
|
| + return;
|
| + }
|
| + }
|
| +
|
| + function valueToString(value) {
|
| + return Number(value).toPrecision(yPrecision);
|
| + }
|
| +
|
| + function getTextWidth(text) {
|
| + ctx.font = textFont;
|
| + // For now, all text is drawn to the left of vertical lines, or centered.
|
| + // Add a 2 pixel padding so that there is some spacing between the text
|
| + // and the vertical line.
|
| + return Math.round(ctx.measureText(text).width) + 2;
|
| + }
|
| +
|
| + function drawHighlightText(text, x, y, color) {
|
| + ctx.strokeStyle = '#000';
|
| + ctx.strokeRect(x, y - textHeight, getTextWidth(text), textHeight);
|
| + ctx.fillStyle = color;
|
| + ctx.fillRect(x, y - textHeight, getTextWidth(text), textHeight);
|
| + ctx.fillStyle = '#fff';
|
| + ctx.fillText(text, x, y);
|
| + }
|
| +
|
| + function drawLine(x1, y1, x2, y2, color) {
|
| + ctx.save();
|
| + ctx.beginPath();
|
| + ctx.moveTo(x1, y1);
|
| + ctx.lineTo(x2, y2);
|
| + ctx.strokeStyle = color;
|
| + ctx.stroke();
|
| + ctx.restore();
|
| + }
|
| +
|
| + // The strokeRect method of the 2d context of a canvas draws a bounding
|
| + // rectangle with an offset origin and greater dimensions. Hence, use this
|
| + // function to draw a rect at the desired location with desired dimensions.
|
| + function drawRect(x, y, width, height, color) {
|
| + drawLine(x, y, x + width - 1, y, color);
|
| + drawLine(x, y, x, y + height - 1, color);
|
| + drawLine(x, y + height - 1, x + width - 1, y + height - 1, color);
|
| + drawLine(x + width - 1, y, x + width - 1, y + height - 1, color);
|
| + }
|
| +
|
| + var yMinStr = valueToString(yMin);
|
| + var yMaxStr = valueToString(yMax);
|
| + var yHalfStr = valueToString((yMax + yMin) / 2);
|
| + var yMinWidth = getTextWidth(yMinStr);
|
| + var yMaxWidth = getTextWidth(yMaxStr);
|
| + var yHalfWidth = getTextWidth(yHalfStr);
|
| +
|
| + var xMinStr = tData[0];
|
| + var xMaxStr = tData[size - 1];
|
| + var xMinWidth = getTextWidth(xMinStr);
|
| + var xMaxWidth = getTextWidth(xMaxStr);
|
| +
|
| + var xOrigin = padding + Math.max(yMinWidth,
|
| + yMaxWidth,
|
| + Math.round(xMinWidth / 2));
|
| + var yOrigin = padding + textHeight;
|
| + var width = canvas.width - xOrigin - Math.floor(xMaxWidth / 2) - padding;
|
| + if (width < size) {
|
| + canvas.width += size - width;
|
| + width = size;
|
| + }
|
| + var height = canvas.height - yOrigin - textHeight - padding;
|
| +
|
| + function drawPlots() {
|
| + // Start fresh.
|
| + ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| +
|
| + // Draw the bounding rectangle.
|
| + drawRect(xOrigin, yOrigin, width, height, gridColor);
|
| +
|
| + // Draw the x and y bound values.
|
| + drawText(yMaxStr, xOrigin - yMaxWidth, yOrigin + textHeight);
|
| + drawText(yMinStr, xOrigin - yMinWidth, yOrigin + height);
|
| + drawText(xMinStr, xOrigin - xMinWidth / 2, yOrigin + height + textHeight);
|
| + drawText(xMaxStr,
|
| + xOrigin + width - xMaxWidth / 2,
|
| + yOrigin + height + textHeight);
|
| +
|
| + // Draw y-level (horizontal) lines.
|
| + drawLine(xOrigin, yOrigin + height / 4,
|
| + xOrigin + width - 1, yOrigin + height / 4,
|
| + gridColor);
|
| + drawLine(xOrigin, yOrigin + height / 2,
|
| + xOrigin + width - 1, yOrigin + height / 2, gridColor);
|
| + drawLine(xOrigin, yOrigin + 3 * height / 4,
|
| + xOrigin + width - 1, yOrigin + 3 * height / 4,
|
| + gridColor);
|
| +
|
| + // Draw half-level value.
|
| + drawText(yHalfStr,
|
| + xOrigin - yHalfWidth,
|
| + yOrigin + height / 2 + textHeight / 2);
|
| +
|
| + // Draw the plots.
|
| + var yValRange = yMax - yMin;
|
| + for (var count = 0; count < plots.length; count++) {
|
| + var plot = plots[count];
|
| + var yData = plot.data;
|
| + ctx.strokeStyle = plot.color;
|
| + ctx.beginPath();
|
| + for (var i = 0; i < size; i++) {
|
| + var xPos = xOrigin + Math.floor(i / (size - 1) * (width - 1));
|
| + var val = yData[i];
|
| + var yPos = yOrigin + height - 1 -
|
| + Math.round((val - yMin) / yValRange * (height - 1));
|
| + if (i == 0) {
|
| + ctx.moveTo(xPos, yPos);
|
| + } else {
|
| + ctx.lineTo(xPos, yPos);
|
| + }
|
| + }
|
| + ctx.stroke();
|
| + }
|
| + }
|
| +
|
| + function drawTimeGuide(tDataIndex) {
|
| + var x = xOrigin + tDataIndex / (size - 1) * (width - 1);
|
| + drawLine(x, yOrigin, x, yOrigin + height - 1, '#000');
|
| + drawText(tData[tDataIndex],
|
| + x - getTextWidth(tData[tDataIndex]) / 2,
|
| + yOrigin - 2);
|
| +
|
| + for (var count = 0; count < plots.length; count++) {
|
| + var yData = plots[count].data;
|
| +
|
| + // Draw small black square on the plot where the time guide intersects
|
| + // it.
|
| + var val = yData[tDataIndex];
|
| + var yPos = yOrigin + height - 1 -
|
| + Math.round((val - yMin) / (yMax - yMin) * (height - 1));
|
| + ctx.fillStyle = '#000';
|
| + ctx.fillRect(x - 2, yPos - 2, 4, 4);
|
| +
|
| + // Draw the val to right of the intersection.
|
| + var valStr = valueToString(val);
|
| + var yLoc;
|
| + if (yPos - textHeight / 2 < yOrigin) {
|
| + yLoc = yOrigin + textHeight;
|
| + } else if (yPos + textHeight / 2 >= yPos + height) {
|
| + yLoc = yOrigin + height - 1;
|
| + } else {
|
| + yLoc = yPos + textHeight / 2;
|
| + }
|
| + drawHighlightText(valStr, x + 5, yLoc, plots[count].color);
|
| + }
|
| + }
|
| +
|
| + function onMouseOverOrMove(event) {
|
| + drawPlots();
|
| +
|
| + var boundingRect = canvas.getBoundingClientRect();
|
| + var x = event.clientX - boundingRect.left;
|
| + var y = event.clientY - boundingRect.top;
|
| + if (x < xOrigin || x >= xOrigin + width ||
|
| + y < yOrigin || y >= yOrigin + height) {
|
| + return;
|
| + }
|
| +
|
| + if (width == size) {
|
| + drawTimeGuide(x - xOrigin);
|
| + } else {
|
| + drawTimeGuide(Math.round((x - xOrigin) / (width - 1) * (size - 1)));
|
| + }
|
| + }
|
| +
|
| + function onMouseOut(event) {
|
| + drawPlots();
|
| + }
|
| +
|
| + drawPlots();
|
| + canvas.addEventListener('mouseover', onMouseOverOrMove);
|
| + canvas.addEventListener('mousemove', onMouseOverOrMove);
|
| + canvas.addEventListener('mouseout', onMouseOut);
|
| +}
|
| +
|
| +/**
|
| + * Display the battery charge vs time on a line graph.
|
| + *
|
| + * @param {Array.<Object>} powerSupplyArray An array of objects with fields
|
| + * representing the battery charge, time when the charge measurement was
|
| + * taken, and whether there was external power connected at that time.
|
| + */
|
| +function showBatteryChargeData(powerSupplyArray) {
|
| + var canvas = $('battery-charge-canvas');
|
| + var tData = [];
|
| + var plot = [];
|
| + for (var i = 0; i < powerSupplyArray.length; i++) {
|
| + var time = new Date(powerSupplyArray[i].time);
|
| + tData[i] = time.toLocaleTimeString();
|
| + plot[i] = powerSupplyArray[i].battery_percent;
|
| + }
|
| +
|
| + var plots = [
|
| + {
|
| + color: '#0000FF',
|
| + data: plot
|
| + }
|
| + ];
|
| + plotLineGraph(canvas, tData, plots, 0.00, 100.00, 3);
|
| +}
|
| +
|
| +function requestBatteryChargeData() {
|
| + chrome.send('requestBatteryChargeData');
|
| +}
|
| +
|
| +var powerUI = {
|
| + showBatteryChargeData: showBatteryChargeData
|
| +};
|
| +
|
| +document.addEventListener('DOMContentLoaded', function() {
|
| + requestBatteryChargeData();
|
| + $('battery-charge-reload-button').onclick = requestBatteryChargeData;
|
| +});
|
|
|