| Index: tryconsole/static/graph.js
|
| ===================================================================
|
| --- tryconsole/static/graph.js (revision 0)
|
| +++ tryconsole/static/graph.js (revision 0)
|
| @@ -0,0 +1,217 @@
|
| +// Copyright (c) 2009-2010 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.
|
| +
|
| +/**
|
| + * @fileoverview Add a periodically updated performance graph.
|
| + */
|
| +
|
| +/**
|
| + * Namespace for Performance Graphing related functions.
|
| + */
|
| +var graph = {};
|
| +
|
| +/**
|
| + * Sequence of characters used for GraphAPI encoding.
|
| + * @private
|
| + */
|
| +graph.GRAPH_SCALE_ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
|
| + 'abcdefghijklmnopqrstuvwxyz0123456789';
|
| +
|
| +/**
|
| + * Encode a single graph value as a 'simple point' character.
|
| + * @param {integer} val Value we are graphing (0-61).
|
| + * @return {string} The encoded point.
|
| + */
|
| +graph.simplePoint = function(val) {
|
| + return graph.GRAPH_SCALE_[val];
|
| +};
|
| +
|
| +/**
|
| + * Given data to graph generate a GraphAPI URL.
|
| + * @param {dict} data The data to graph. Containing: 'builders' listing the name
|
| + * of each builder, 'times' containing the times sampled, and data for
|
| + * [time][builder] for each time, builder pair.
|
| + * @return {string} A GraphAPI URL to graph the data.
|
| + */
|
| +graph.graphURL = function(data) {
|
| + // Get the list of builders and reorder it.
|
| + var builders = [];
|
| + for (var b in data['builders']) {
|
| + builders.push(b);
|
| + }
|
| + builders.sort();
|
| +
|
| + // Get the list of times and reorder it.
|
| + var times = [];
|
| + for (var t in data['times']) {
|
| + times.push(t);
|
| + }
|
| + times.sort();
|
| +
|
| + // Convert points to numeric samples.
|
| + var pointsNumeric = [];
|
| + var buildersLen = builders.length;
|
| + for (var b = 0; b < buildersLen; b++) {
|
| + var builder = builders[b];
|
| + var bp = [];
|
| + var timesLen = times.length;
|
| + for (var t = 0; t < timesLen; t++) {
|
| + var tm = times[t];
|
| + if (tm in data && builder in data[tm]) {
|
| + var v = data[tm][builder];
|
| + } else {
|
| + var v = 0;
|
| + }
|
| + bp.push(v);
|
| + }
|
| + pointsNumeric.push(bp);
|
| + }
|
| +
|
| + // Calculate the total.
|
| + total = [];
|
| + var pointsNumeric0Len = 0;
|
| + if (pointsNumeric.length > 0) pointsNumeric0Len = pointsNumeric[0].length;
|
| + for (var vp = 0; vp < pointsNumeric0Len; vp++) {
|
| + total.push(0);
|
| + }
|
| + var pointsNumericLen = pointsNumeric.length;
|
| + for (var ptr = 0; ptr < pointsNumericLen; ptr++) {
|
| + for (var vp = 0; vp < pointsNumeric0Len; vp++) {
|
| + total[vp] += pointsNumeric[ptr][vp];
|
| + }
|
| + }
|
| + builders.unshift('TOTAL|TOTAL');
|
| + pointsNumeric.unshift(total);
|
| +
|
| + // Find the maximum values in all graphs.
|
| + minValue = 9e9;
|
| + maxValue = -9e9;
|
| + for (var b = 0; b < pointsNumericLen; b++) {
|
| + for (var t = 0; t < pointsNumeric0Len; t++) {
|
| + var v = pointsNumeric[b][t];
|
| + if (v < minValue) minValue = v;
|
| + if (v > maxValue) maxValue = v;
|
| + }
|
| + }
|
| + // Force minimum to at least zero.
|
| + if (minValue > 0) minValue = 0;
|
| + // Precomute the gap between smallest and biggest.
|
| + var gap = Math.max(maxValue - minValue, 1);
|
| +
|
| + // Convert numeric samples to simple samples.
|
| + var points = [];
|
| + for (var b = 0; b < pointsNumericLen; b++) {
|
| + var bp = '';
|
| + for (var t = 0; t < pointsNumeric0Len; t++) {
|
| + var v = pointsNumeric[b][t];
|
| + v = Math.floor((v - minValue) * 61 / gap);
|
| + bp += graph.simplePoint(v);
|
| + }
|
| + points.push(bp);
|
| + }
|
| + var pointsPacked = points.join(',');
|
| +
|
| + // Get list of builder names for labels.
|
| + var builderNames = [];
|
| + for (var b in builders) {
|
| + var name = builders[b].split('|')[1];
|
| + builderNames.push(name);
|
| + }
|
| +
|
| + // Get number of points if any.
|
| + var numPoints = 0;
|
| + if (points.length) {
|
| + numPoints = points[0].length;
|
| + }
|
| +
|
| + // Generate URL.
|
| + var url = 'http://chart.apis.google.com/chart?' +
|
| + 'chco=000000,ff0000,ffcc00,ffff00,00ff00,00ffff,0000ff,ff00ff&' +
|
| + //'chxr=0,0,' + numPoints + '|1,' +
|
| + //minValue + ',' + maxValue + '&' +
|
| + 'chxr=0,' + minValue + ',' + maxValue + '&' +
|
| + //'chxt=x,y&' +
|
| + 'chxt=y&' +
|
| + 'chf=c,lg,45,eeeeee,1,888888,0&' +
|
| + 'chdl=' + builderNames.join('|') + '&' +
|
| + 'cht=lc&chs=400x200&' +
|
| + 'chd=s:' + pointsPacked;
|
| + return url;
|
| +};
|
| +
|
| +/**
|
| + * Decode the result of querying the server for performance data.
|
| + * @param {string} text The result of a performance_raw query.
|
| + * @param {dict} data A variable to use for data storage for this graph.
|
| + */
|
| +graph.decodeData = function(text, data) {
|
| + if (!text) return;
|
| + if (!('times' in data)) data['times'] = {};
|
| + if (!('builders' in data)) data['builders'] = {};
|
| + var rows = text.split('\n');
|
| + for (var r in rows) {
|
| + var fields = rows[r].split('|');
|
| + if (fields.length != 5) continue;
|
| + var builder = fields[0] + '|' + fields[1];
|
| + var tm = parseInt(fields[2]);
|
| + var count = parseInt(fields[3]) / parseInt(fields[4]);
|
| + if (!(tm in data)) data[tm] = {};
|
| + data[tm][builder] = count;
|
| + data['times'][tm] = 0;
|
| + data['builders'][builder] = 0;
|
| + }
|
| +
|
| + // Get the list of times and reorder it.
|
| + var times = [];
|
| + for (var t in data['times']) {
|
| + times.push(t);
|
| + }
|
| + times.sort();
|
| +
|
| + // Dump anything older than the first 60 samples.
|
| + if (times.length > 70) {
|
| + var junk = times.slice(times.length - 70, times.length);
|
| + for (var j in junk) {
|
| + var tm = junk[j];
|
| + delete data[tm];
|
| + delete data['times'][tm];
|
| + }
|
| + }
|
| +};
|
| +
|
| +/**
|
| + * Setup everything needed to keep a performance graph up to date.
|
| + * @param {string} id The id of an HTML <div> to receive the graph.
|
| + * @param {dict} data A variable to use for data storage related to this graph.
|
| + * @param {float} interval The update interval in seconds.
|
| + */
|
| +graph.setup = function(id, data, interval) {
|
| + // Init goal if not set.
|
| + if (!('goal' in data)) data['goal'] = interval * 70;
|
| + // Get next item.
|
| + var step = interval * 20;
|
| + var goal = data['goal'];
|
| + var next = goal - step;
|
| + if (next < 0) next = 0;
|
| + data['goal'] = next;
|
| + // Fetch it.
|
| + http.getText(
|
| + '/performance_raw?interval=' + interval +
|
| + '&start=' + goal + '&stop=' + next,
|
| + function(text) {
|
| + graph.decodeData(text, data);
|
| + var e = document.getElementById(id);
|
| + e.src = graph.graphURL(data);
|
| + var timeout;
|
| + if (next == 0) {
|
| + timeout = 20000;
|
| + } else {
|
| + timeout = 0;
|
| + }
|
| + window.setTimeout(function() {
|
| + graph.setup(id, data, interval);
|
| + }, timeout);
|
| + });
|
| +};
|
| +
|
|
|
| Property changes on: tryconsole/static/graph.js
|
| ___________________________________________________________________
|
| Added: svn:mergeinfo
|
|
|
|
|