Add Chrome Endure graph plotting code.

Chrome Endure refers to an endurance testing effort to study the effect
of memory bloat in webapps running in chrome.

This code is a fork of chrome's existing code for displaying performance
graphs.  It has become very specific to Chrome Endure, containing features
requested by users of Chrome Endure, and having the ability to display
performance results across time within a given test run (as compared to
the existing chrome perf graphs, which display data across test runs).

In addition to adding new features specific to Chrome Endure, the current
code removes some features that originally existed from chrome's perf
graphing code, which haven't been used for Chrome Endure.

This code has been running for awhile to display Chrome Endure perf
graphs, but hasn't been checked in until now.  Other users want to build on
top of this codebase to add new graphing features specific to Chrome Endure.

BUG=chromium-os:32302
TEST=Verified that graphs work well enough for current Chrome Endure purposes.


Review URL: https://chromiumcodereview.appspot.com/10832403

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@153612 0039d316-1c4b-4281-b951-d872f2087c98
parent b3c019b9
<!--
Copyright (c) 2012 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.
-->
<!--
HTML for a general Chrome Endure graph.
-->
<html>
<head>
<style>
body {
font-family: sans-serif;
}
div#output {
cursor: pointer;
}
div#switcher * {
border: 1px solid black;
border-radius: 4px 4px 0 0;
padding-left: 0.5em;
padding-right: 0.5em;
}
div#switcher a {
background: #ddd;
cursor: pointer;
}
canvas.plot {
border: 1px solid black;
}
div.plot-coordinates {
font-family: monospace;
}
iframe {
display: none;
width: 100%;
height: 100%;
border: none;
}
div.selected {
border-left: none;
}
#explain {
font-size: 0.75em;
font-style: italic;
color: rgb(100,100,100);
}
</style>
<script src="js/common.js"></script>
<script src="js/plotter.js"></script>
<script src="js/coordinates.js"></script>
<script src="config.js"></script>
<script src="endure_plotter.js"></script>
</head>
<body>
<div id="header_lookout" align="center">
<font style='color: #0066FF; font-family: Arial, serif;
font-size: 12pt; font-weight: bold;'>
<script>
document.write("<a target=\"_blank\" href=\"");
document.write(get_url());
document.write("\">");
if ('graph' in params && params.graph != '')
document.write(escape(params.graph));
else
document.write(Config.title);
document.write("</a>");
</script>
</font>
</div>
<div id="header_text">
Builds generated by the <i>
<script>
document.write(Config.buildslave);
</script>
</i> are run through <b>
<script>
document.write(Config.title);
</script>
</b> and the results of that test are charted here.
</div>
<div id="explain">
More information about Chrome Endure can be found here:
<a href="http://go/endure">go/endure</a>
</div>
<p></p>
<div id="switcher"></div>
<div id="output"></div> <br>
<div id="revisions"></div> <br>
<div id="comparisons"></div> <br>
<div id="events"></div>
<script>
if ('lookout' in params) {
document.getElementById("switcher").style.display = "none";
document.getElementById("header_text").style.display = "none";
document.getElementById("explain").style.display = "none";
} else {
document.getElementById("header_lookout").style.display = "none";
}
</script>
</body>
</html>
This diff is collapsed.
/*
Copyright (c) 2012 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 Common methods for performance-plotting Javascript.
*/
/**
* Fetches a URL asynchronously and invokes a callback when complete.
*
* @param {string} url URL to fetch.
* @param {Function(string, string)} callback The function to invoke when the
* results of the URL fetch are complete. The function should accept two
* strings representing the URL data, and any errors, respectively.
*/
function Fetch(url, callback) {
var r = new XMLHttpRequest();
r.open('GET', url, true);
r.setRequestHeader('pragma', 'no-cache');
r.setRequestHeader('cache-control', 'no-cache');
r.onreadystatechange = function() {
if (r.readyState == 4) {
var text = r.responseText;
var error;
if (r.status != 200)
error = url + ': ' + r.status + ': ' + r.statusText;
else if (!text)
error = url + ': null response';
callback(text, error);
}
}
r.send(null);
}
/**
* Parses the parameters of the current page's URL.
*
* @return {Object} An object with properties given by the parameters specified
* in the URL's query string.
*/
function ParseParams() {
var result = new Object();
var query = window.location.search.substring(1)
if (query.charAt(query.length - 1) == '/')
query = query.substring(0, query.length - 1) // Strip trailing slash.
var s = query.split('&');
for (i = 0; i < s.length; ++i) {
var v = s[i].split('=');
var key = v[0];
var value = unescape(v[1]);
result[key] = value;
}
if ('history' in result) {
result['history'] = parseInt(result['history']);
result['history'] = Math.max(result['history'], 2);
}
if ('rev' in result) {
result['rev'] = parseInt(result['rev']);
result['rev'] = Math.max(result['rev'], -1);
}
return result;
}
/**
* Creates the URL constructed from the current pathname and the given params.
*
* @param {Object} An object containing parameters for a URL query string.
* @return {string} The URL constructed from the given params.
*/
function MakeURL(params) {
var url = window.location.pathname;
var sep = '?';
for (p in params) {
if (!p)
continue;
url += sep + p + '=' + params[p];
sep = '&';
}
return url;
}
/*
Copyright (c) 2012 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 Class and functions to handle positioning of plot data points.
*/
/**
* Class that handles plot data positioning.
* @constructor
*
* @param {Array} plotData Data that will be plotted. It is an array of lines,
* where each line is an array of points, and each point is a length-2 array
* representing an (x, y) pair.
*/
function Coordinates(plotData) {
this.plotData = plotData;
height = window.innerHeight - 16;
width = window.innerWidth - 16;
this.widthMax = width;
this.heightMax = Math.min(400, height - 85);
this.processValues_('x');
this.processValues_('y');
}
/**
* Determines the min/max x or y values in the plot, accounting for some extra
* buffer space.
*
* @param {string} type The type of value to process, either 'x' or 'y'.
*/
Coordinates.prototype.processValues_ = function (type) {
var merged = [];
for (var i = 0; i < this.plotData.length; i++)
for (var j = 0; j < this.plotData[i].length; j++) {
if (type == 'x')
merged.push(parseFloat(this.plotData[i][j][0])); // Index 0 is x value.
else
merged.push(parseFloat(this.plotData[i][j][1])); // Index 1 is y value.
}
min = merged[0];
max = merged[0];
for (var i = 1; i < merged.length; ++i) {
if (isNaN(min) || merged[i] < min)
min = merged[i];
if (isNaN(max) || merged[i] > max)
max = merged[i];
}
var bufferSpace = 0.02 * (max - min);
if (type == 'x') {
this.xMinValue = min - bufferSpace;
this.xMaxValue = max + bufferSpace;
} else {
this.yMinValue = min - bufferSpace;
this.yMaxValue = max + bufferSpace;
}
};
/**
* Difference between horizontal max and min values.
*
* @return {number} The x value range.
*/
Coordinates.prototype.xValueRange = function() {
return this.xMaxValue - this.xMinValue;
};
/**
* Difference between vertical max and min values.
*
* @return {number} The y value range.
*/
Coordinates.prototype.yValueRange = function() {
return this.yMaxValue - this.yMinValue
};
/**
* Converts horizontal data value to pixel value on canvas.
*
* @param {number} value The x data value.
* @return {number} The corresponding x pixel value on the canvas.
*/
Coordinates.prototype.xPixel = function(value) {
return this.widthMax * ((value - this.xMinValue) / this.xValueRange());
};
/**
* Converts vertical data value to pixel value on canvas.
*
* @param {number} value The y data value.
* @return {number} The corresponding y pixel value on the canvas.
*/
Coordinates.prototype.yPixel = function(value) {
if (this.yValueRange() == 0) {
// Completely horizontal lines should be centered horizontally.
return this.heightMax / 2;
} else {
return this.heightMax -
(this.heightMax * (value - this.yMinValue) / this.yValueRange());
}
};
/**
* Converts x point on canvas to data value it represents.
*
* @param {number} position The x pixel value on the canvas.
* @return {number} The corresponding x data value.
*/
Coordinates.prototype.xValue = function(position) {
return this.xMinValue + (position / this.widthMax * this.xValueRange());
};
/**
* Converts y point on canvas to data value it represents.
*
* @param {number} position The y pixel value on the canvas.
* @return {number} The corresponding y data value.
*/
Coordinates.prototype.yValue = function(position) {
var ratio = this.heightMax / (this.heightMax - position);
return this.yMinValue + (this.yValueRange() / ratio);
};
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment