| <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> |