blob: 8570a1455c7cc321d3ac7db8cd849c6c4f33594e [file] [log] [blame]
<html>
<!--
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.
-->
<!--
This page plots data loaded from Chrome performance tests listed in
chrome_config.js for specified version numbers in URL parameter.
Example:
build-comparison.html?versions=17.1.963.11,17.1.963.12,17.1.963.13
-->
<head>
<style type="text/css">
{
margin: 0;
padding: 0;
list-style-type: none;
}
body {
font-family: Helvetica, Arial, sans-serif;
color: #333;
}
a {
color: #2D7BB2;
text-decoration: none;
font-weight: bold;
}
a:hover {
color: #333;
}
h2, h3, h4 {
clear: both;
margin: 0 0 0.6em 0;
}
h3 {
color: #666;
}
button {
padding: 2px 6px 3px;
}
label {
font-size: 11px;
color: #666;
}
</style>
<title>Chrome Perf Platform Comparison</title>
<script src="chrome_config.js"></script>
<script src="ui/js/common.js"></script>
<script src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
var params = ParseParams();
var versions = {};
var allRowData = [];
var isDataFetched = false;
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(init);
function init() {
if (params.versions) {
split_ver = params.versions.split(/[\s,]+/);
for (var i = 0; i < split_ver.length; i++)
versions[split_ver[i]] = 1;
FetchGraphList();
document.getElementById('versions').defaultValue = params.versions;
}
}
/**
* On plot clicked, parse text area for version numbers and plot.
*/
function setVersion() {
var ver = document.getElementById('versions').value;
clearDiv('output');
clearDiv('log');
if (ver) {
versions = {};
split_ver = ver.split(/[\s,\n]+/);
for (var i = 0; i < split_ver.length; i++)
versions[split_ver[i]] = 1;
if (isDataFetched)
plot();
else
FetchGraphList();
var stateObj = { foo: 'bar'};
history.pushState(stateObj, "", MakeURL({'versions': ver}));
}
}
/**
* Fetch all the graphs.dat file on all systems and test directories.
*/
function FetchGraphList() {
// Fetch graphs.dat from all machines and tests.
var graphFiles = [];
var graphPaths = [];
for (var system in ChromeConfig.systemTitles) {
for (var testName in ChromeConfig.testTitles) {
var path = '../' + system + '/' + testName;
graphFiles.push(path + '/' + 'graphs.dat');
var p = {
path: path,
testName: testName,
machine: ChromeConfig.systemTitles[system],
}
graphPaths.push(p);
}
}
new FetchList(graphFiles, onGraphListReceived, graphPaths);
}
/**
* Fetch all *-summary.dat.
*/
function onGraphListReceived(data, graphPaths) {
// Select graph from graph list.
var summaryFiles = [];
for (var i = 0; i < data.length; i++) {
var graphList = JsonToJs(data[i]);
if (graphList) {
for (var j = 0; j < graphList.length; j++) {
if (graphList[j].important) {
var gList = graphList[j];
summaryFiles.push(graphPaths[i].path + '/' + graphList[j].name +
'-summary.dat');
var row = {
machine: graphPaths[i].machine,
units: graphList[j].units,
testName: graphPaths[i].testName,
graphName: graphList[j].graphName,
}
allRowData.push(row);
break;
}
}
}
}
new FetchList(summaryFiles, onGraphDataReceived);
}
function onGraphDataReceived(data) {
// Parse the summary data file.
for (var i = 0; i < data.length; i++) {
if (data[i]) {
var rows = new Rows(data[i]);
allRowData[i].rows = rows;
}
}
isDataFetched = true;
plot();
}
/**
* Order data and add charts.
*/
function plot() {
// Order row data by test names and machine names.
var graphData = {};
var foundVersions = {};
for (var i = 0; i < allRowData.length; i++) {
var rowData = allRowData[i];
var rows = rowData.rows;
if (!rows)
continue;
for (var j = 0; j < rows.length; j++) {
var row = rows.get(j);
if (!row)
continue;
if (row.version in versions) {
foundVersions[row.version] = 1;
var traces = row['traces'];
if (!graphData[rowData.testName])
graphData[rowData.testName] = {};
if (!graphData[rowData.testName][rowData.machine]) {
var data = {
traceList: [traces],
versions: [row.version],
units: rowData.units,
}
graphData[rowData.testName][rowData.machine] = data;
} else {
var data = graphData[rowData.testName][rowData.machine];
data.traceList.push(traces);
data.versions.push(row.version);
}
}
}
}
// Prepare traces for plotting.
for (var testName in graphData) {
var dataByMachine = graphData[testName];
for (var machine in dataByMachine) {
var data = dataByMachine[machine];
var traceNames = {};
for (var i = 0; i < data.traceList.length; i++) {
for (var traceName in data.traceList[i]) {
traceNames[traceName] = 1;
}
}
var traceNameList = [];
for (var traceName in traceNames)
traceNameList.push(traceName);
var traces = [];
for (var i = 0; i < data.traceList.length; i++) {
trace = [data.versions[i]];
for (var traceName in traceNames) {
if (data.traceList[i][traceName])
trace.push(parseFloat(data.traceList[i][traceName][0]));
else
trace.push(0);
}
traces.push(trace);
}
data.traces = traces;
data.traceNames = traceNameList;
}
}
var versionExist = false;
for (version in versions) {
if (version) {
if (!(version in foundVersions))
reportError('No data for: ' + version);
else
versionExist = true;
}
}
if (!versionExist)
return;
var output = document.getElementById('output');
var htmlTable = new HTMLTable(output);
// Add machine titles.
var machineNames = [];
for (var system in ChromeConfig.systemTitles) {
htmlTable.addHeader(ChromeConfig.systemTitles[system]);
machineNames.push(ChromeConfig.systemTitles[system]);
}
// Plot graph for each test and machine.
for (var testName in graphData) {
var dataByMachine = graphData[testName];
htmlTable.addRow();
for (var i = 0; i < machineNames.length; i++) {
var data = dataByMachine[machineNames[i]];
if (data) {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string', 'Version');
for (var j = 0; j < data.traceNames.length; j++)
dataTable.addColumn('number', data.traceNames[j]);
dataTable.addRows(data.traces);
var options = {
width: 400, height: 240,
title: ChromeConfig.testTitles[testName],
vAxis: {title: data.units, titleTextStyle: {color: 'red'}},
colors:['#0000FF','#E69F00'],
};
var charDiv = document.createElement('div');
htmlTable.addElement(charDiv);
var chart = new google.visualization.ColumnChart(charDiv);
chart.draw(dataTable, options);
} else {
var charDiv = document.createElement('div');
htmlTable.addElement(charDiv);
}
}
}
}
/**
* Class for creating HTML table.
* @constructor
*/
function HTMLTable(div) {
this.div_ = div;
this.table_ = document.createElement('table');
this.div_.appendChild(this.table_);
this.tr_ = null;
this.headerTr_ = null;
}
HTMLTable.prototype.addHeader = function(title) {
if (!this.headerTr_) {
this.headerTr_ = document.createElement('tr');
this.table_.appendChild(this.headerTr_);
}
var th = document.createElement('th');
this.headerTr_.appendChild(th);
th.innerHTML = title;
}
HTMLTable.prototype.addRow = function() {
this.tr_ = document.createElement('tr');
this.table_.appendChild(this.tr_);
}
HTMLTable.prototype.addElement = function(div) {
var td = document.createElement('td');
this.tr_.appendChild(td);
td.appendChild(div);
}
function JsonToJs(data) {
return eval('(' + data + ')');
}
function cleanId(str) {
return str.replace(/\s/g, '_').toLowerCase();
}
function clearDiv(id) {
var div = document.getElementById(id);
while (div.hasChildNodes()) {
div.removeChild(div.lastChild);
}
}
function reportError(error) {
document.getElementById('log').innerHTML = '<p>' + error + '</p>';
}
/**
* Encapsulates a *-summary.dat file.
* @constructor
*/
function Rows(data) {
this.rows_ = (data) ? data.split('\n') : [];
this.length = this.rows_.length;
}
/**
* Returns the row at the given index.
*/
Rows.prototype.get = function(i) {
if (!this.rows_[i].length) return null;
var row = JsonToJs(this.rows_[i]);
row.revision = isNaN(row['rev']) ? row['rev'] : parseInt(row['rev']);
row.version = row['ver'];
return row;
};
</script>
</head>
<body>
<br />
<center>
<h2>Chrome Perf</h2>
</center>
<p><b>Build versions: </b><br/>
<label for="direction">Enter version numbers with comma delimiter.</label>
<br/>
<textarea cols="40" rows="5" id="versions"></textarea>
<p><button value="Plot" onClick="setVersion()">Plot</button></p>
<pre id="log"></pre>
<div id="output"></div>
</body>
</html>