| OLD | NEW |
| (Empty) |
| 1 <html> | |
| 2 | |
| 3 <!-- | |
| 4 Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 5 Use of this source code is governed by a BSD-style license that can be | |
| 6 found in the LICENSE file. | |
| 7 --> | |
| 8 | |
| 9 <!-- | |
| 10 | |
| 11 This page plots data loaded from Chrome performance tests listed in | |
| 12 chrome_config.js for specified version numbers in URL parameter. | |
| 13 | |
| 14 Example: | |
| 15 build-comparison.html?versions=17.1.963.11,17.1.963.12,17.1.963.13 | |
| 16 --> | |
| 17 <head> | |
| 18 <style type="text/css"> | |
| 19 { | |
| 20 margin: 0; | |
| 21 padding: 0; | |
| 22 list-style-type: none; | |
| 23 } | |
| 24 body { | |
| 25 font-family: Helvetica, Arial, sans-serif; | |
| 26 color: #333; | |
| 27 } | |
| 28 a { | |
| 29 color: #2D7BB2; | |
| 30 text-decoration: none; | |
| 31 font-weight: bold; | |
| 32 } | |
| 33 a:hover { | |
| 34 color: #333; | |
| 35 } | |
| 36 h2, h3, h4 { | |
| 37 clear: both; | |
| 38 margin: 0 0 0.6em 0; | |
| 39 } | |
| 40 h3 { | |
| 41 color: #666; | |
| 42 } | |
| 43 button { | |
| 44 padding: 2px 6px 3px; | |
| 45 } | |
| 46 label { | |
| 47 font-size: 11px; | |
| 48 color: #666; | |
| 49 } | |
| 50 </style> | |
| 51 | |
| 52 <title>Chrome Perf Platform Comparison</title> | |
| 53 <script src="chrome_config.js"></script> | |
| 54 <script src="ui/js/common.js"></script> | |
| 55 <script src="https://www.google.com/jsapi"></script> | |
| 56 | |
| 57 <script type="text/javascript"> | |
| 58 var params = ParseParams(); | |
| 59 var versions = {}; | |
| 60 var allRowData = []; | |
| 61 var isDataFetched = false; | |
| 62 | |
| 63 google.load("visualization", "1", {packages:["corechart"]}); | |
| 64 google.setOnLoadCallback(init); | |
| 65 | |
| 66 function init() { | |
| 67 if (params.versions) { | |
| 68 split_ver = params.versions.split(/[\s,]+/); | |
| 69 for (var i = 0; i < split_ver.length; i++) | |
| 70 versions[split_ver[i]] = 1; | |
| 71 FetchGraphList(); | |
| 72 | |
| 73 document.getElementById('versions').defaultValue = params.versions; | |
| 74 } | |
| 75 } | |
| 76 | |
| 77 /** | |
| 78 * On plot clicked, parse text area for version numbers and plot. | |
| 79 */ | |
| 80 function setVersion() { | |
| 81 var ver = document.getElementById('versions').value; | |
| 82 clearDiv('output'); | |
| 83 clearDiv('log'); | |
| 84 if (ver) { | |
| 85 versions = {}; | |
| 86 split_ver = ver.split(/[\s,\n]+/); | |
| 87 for (var i = 0; i < split_ver.length; i++) | |
| 88 versions[split_ver[i]] = 1; | |
| 89 if (isDataFetched) | |
| 90 plot(); | |
| 91 else | |
| 92 FetchGraphList(); | |
| 93 | |
| 94 var stateObj = { foo: 'bar'}; | |
| 95 history.pushState(stateObj, "", MakeURL({'versions': ver})); | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 /** | |
| 100 * Fetch all the graphs.dat file on all systems and test directories. | |
| 101 */ | |
| 102 function FetchGraphList() { | |
| 103 // Fetch graphs.dat from all machines and tests. | |
| 104 var graphFiles = []; | |
| 105 var graphPaths = []; | |
| 106 for (var system in ChromeConfig.systemTitles) { | |
| 107 for (var testName in ChromeConfig.testTitles) { | |
| 108 var path = '../' + system + '/' + testName; | |
| 109 graphFiles.push(path + '/' + 'graphs.dat'); | |
| 110 var p = { | |
| 111 path: path, | |
| 112 testName: testName, | |
| 113 machine: ChromeConfig.systemTitles[system], | |
| 114 } | |
| 115 graphPaths.push(p); | |
| 116 } | |
| 117 } | |
| 118 new FetchList(graphFiles, onGraphListReceived, graphPaths); | |
| 119 } | |
| 120 | |
| 121 /** | |
| 122 * Fetch all *-summary.dat. | |
| 123 */ | |
| 124 function onGraphListReceived(data, graphPaths) { | |
| 125 // Select graph from graph list. | |
| 126 var summaryFiles = []; | |
| 127 for (var i = 0; i < data.length; i++) { | |
| 128 var graphList = JsonToJs(data[i]); | |
| 129 if (graphList) { | |
| 130 for (var j = 0; j < graphList.length; j++) { | |
| 131 if (graphList[j].important) { | |
| 132 var gList = graphList[j]; | |
| 133 summaryFiles.push(graphPaths[i].path + '/' + graphList[j].name + | |
| 134 '-summary.dat'); | |
| 135 var row = { | |
| 136 machine: graphPaths[i].machine, | |
| 137 units: graphList[j].units, | |
| 138 testName: graphPaths[i].testName, | |
| 139 graphName: graphList[j].graphName, | |
| 140 } | |
| 141 allRowData.push(row); | |
| 142 break; | |
| 143 } | |
| 144 } | |
| 145 } | |
| 146 } | |
| 147 new FetchList(summaryFiles, onGraphDataReceived); | |
| 148 } | |
| 149 | |
| 150 function onGraphDataReceived(data) { | |
| 151 // Parse the summary data file. | |
| 152 for (var i = 0; i < data.length; i++) { | |
| 153 if (data[i]) { | |
| 154 var rows = new Rows(data[i]); | |
| 155 allRowData[i].rows = rows; | |
| 156 } | |
| 157 } | |
| 158 isDataFetched = true; | |
| 159 plot(); | |
| 160 } | |
| 161 | |
| 162 /** | |
| 163 * Order data and add charts. | |
| 164 */ | |
| 165 function plot() { | |
| 166 // Order row data by test names and machine names. | |
| 167 var graphData = {}; | |
| 168 var foundVersions = {}; | |
| 169 for (var i = 0; i < allRowData.length; i++) { | |
| 170 var rowData = allRowData[i]; | |
| 171 var rows = rowData.rows; | |
| 172 if (!rows) | |
| 173 continue; | |
| 174 for (var j = 0; j < rows.length; j++) { | |
| 175 var row = rows.get(j); | |
| 176 if (!row) | |
| 177 continue; | |
| 178 if (row.version in versions) { | |
| 179 foundVersions[row.version] = 1; | |
| 180 var traces = row['traces']; | |
| 181 if (!graphData[rowData.testName]) | |
| 182 graphData[rowData.testName] = {}; | |
| 183 if (!graphData[rowData.testName][rowData.machine]) { | |
| 184 var data = { | |
| 185 traceList: [traces], | |
| 186 versions: [row.version], | |
| 187 units: rowData.units, | |
| 188 } | |
| 189 graphData[rowData.testName][rowData.machine] = data; | |
| 190 } else { | |
| 191 var data = graphData[rowData.testName][rowData.machine]; | |
| 192 data.traceList.push(traces); | |
| 193 data.versions.push(row.version); | |
| 194 } | |
| 195 } | |
| 196 } | |
| 197 } | |
| 198 | |
| 199 // Prepare traces for plotting. | |
| 200 for (var testName in graphData) { | |
| 201 var dataByMachine = graphData[testName]; | |
| 202 for (var machine in dataByMachine) { | |
| 203 var data = dataByMachine[machine]; | |
| 204 var traceNames = {}; | |
| 205 for (var i = 0; i < data.traceList.length; i++) { | |
| 206 for (var traceName in data.traceList[i]) { | |
| 207 traceNames[traceName] = 1; | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 var traceNameList = []; | |
| 212 for (var traceName in traceNames) | |
| 213 traceNameList.push(traceName); | |
| 214 | |
| 215 var traces = []; | |
| 216 for (var i = 0; i < data.traceList.length; i++) { | |
| 217 trace = [data.versions[i]]; | |
| 218 for (var traceName in traceNames) { | |
| 219 if (data.traceList[i][traceName]) | |
| 220 trace.push(parseFloat(data.traceList[i][traceName][0])); | |
| 221 else | |
| 222 trace.push(0); | |
| 223 } | |
| 224 traces.push(trace); | |
| 225 } | |
| 226 data.traces = traces; | |
| 227 data.traceNames = traceNameList; | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 var versionExist = false; | |
| 232 for (version in versions) { | |
| 233 if (version) { | |
| 234 if (!(version in foundVersions)) | |
| 235 reportError('No data for: ' + version); | |
| 236 else | |
| 237 versionExist = true; | |
| 238 } | |
| 239 } | |
| 240 if (!versionExist) | |
| 241 return; | |
| 242 | |
| 243 var output = document.getElementById('output'); | |
| 244 var htmlTable = new HTMLTable(output); | |
| 245 | |
| 246 // Add machine titles. | |
| 247 var machineNames = []; | |
| 248 for (var system in ChromeConfig.systemTitles) { | |
| 249 htmlTable.addHeader(ChromeConfig.systemTitles[system]); | |
| 250 machineNames.push(ChromeConfig.systemTitles[system]); | |
| 251 } | |
| 252 | |
| 253 // Plot graph for each test and machine. | |
| 254 for (var testName in graphData) { | |
| 255 var dataByMachine = graphData[testName]; | |
| 256 htmlTable.addRow(); | |
| 257 | |
| 258 for (var i = 0; i < machineNames.length; i++) { | |
| 259 var data = dataByMachine[machineNames[i]]; | |
| 260 if (data) { | |
| 261 var dataTable = new google.visualization.DataTable(); | |
| 262 dataTable.addColumn('string', 'Version'); | |
| 263 | |
| 264 for (var j = 0; j < data.traceNames.length; j++) | |
| 265 dataTable.addColumn('number', data.traceNames[j]); | |
| 266 dataTable.addRows(data.traces); | |
| 267 | |
| 268 var options = { | |
| 269 width: 400, height: 240, | |
| 270 title: ChromeConfig.testTitles[testName], | |
| 271 vAxis: {title: data.units, titleTextStyle: {color: 'red'}}, | |
| 272 colors:['#0000FF','#E69F00'], | |
| 273 }; | |
| 274 | |
| 275 var charDiv = document.createElement('div'); | |
| 276 htmlTable.addElement(charDiv); | |
| 277 var chart = new google.visualization.ColumnChart(charDiv); | |
| 278 chart.draw(dataTable, options); | |
| 279 } else { | |
| 280 var charDiv = document.createElement('div'); | |
| 281 htmlTable.addElement(charDiv); | |
| 282 } | |
| 283 } | |
| 284 } | |
| 285 } | |
| 286 | |
| 287 /** | |
| 288 * Class for creating HTML table. | |
| 289 * @constructor | |
| 290 */ | |
| 291 function HTMLTable(div) { | |
| 292 this.div_ = div; | |
| 293 this.table_ = document.createElement('table'); | |
| 294 this.div_.appendChild(this.table_); | |
| 295 this.tr_ = null; | |
| 296 this.headerTr_ = null; | |
| 297 } | |
| 298 | |
| 299 HTMLTable.prototype.addHeader = function(title) { | |
| 300 if (!this.headerTr_) { | |
| 301 this.headerTr_ = document.createElement('tr'); | |
| 302 this.table_.appendChild(this.headerTr_); | |
| 303 } | |
| 304 var th = document.createElement('th'); | |
| 305 this.headerTr_.appendChild(th); | |
| 306 th.innerHTML = title; | |
| 307 } | |
| 308 | |
| 309 HTMLTable.prototype.addRow = function() { | |
| 310 this.tr_ = document.createElement('tr'); | |
| 311 this.table_.appendChild(this.tr_); | |
| 312 } | |
| 313 | |
| 314 HTMLTable.prototype.addElement = function(div) { | |
| 315 var td = document.createElement('td'); | |
| 316 this.tr_.appendChild(td); | |
| 317 td.appendChild(div); | |
| 318 } | |
| 319 | |
| 320 function JsonToJs(data) { | |
| 321 return eval('(' + data + ')'); | |
| 322 } | |
| 323 | |
| 324 function cleanId(str) { | |
| 325 return str.replace(/\s/g, '_').toLowerCase(); | |
| 326 } | |
| 327 | |
| 328 function clearDiv(id) { | |
| 329 var div = document.getElementById(id); | |
| 330 while (div.hasChildNodes()) { | |
| 331 div.removeChild(div.lastChild); | |
| 332 } | |
| 333 } | |
| 334 | |
| 335 function reportError(error) { | |
| 336 document.getElementById('log').innerHTML = '<p>' + error + '</p>'; | |
| 337 } | |
| 338 | |
| 339 /** | |
| 340 * Encapsulates a *-summary.dat file. | |
| 341 * @constructor | |
| 342 */ | |
| 343 function Rows(data) { | |
| 344 this.rows_ = (data) ? data.split('\n') : []; | |
| 345 this.length = this.rows_.length; | |
| 346 } | |
| 347 | |
| 348 /** | |
| 349 * Returns the row at the given index. | |
| 350 */ | |
| 351 Rows.prototype.get = function(i) { | |
| 352 if (!this.rows_[i].length) return null; | |
| 353 var row = JsonToJs(this.rows_[i]); | |
| 354 row.revision = isNaN(row['rev']) ? row['rev'] : parseInt(row['rev']); | |
| 355 row.version = row['ver']; | |
| 356 return row; | |
| 357 }; | |
| 358 </script> | |
| 359 </head> | |
| 360 <body> | |
| 361 <br /> | |
| 362 <center> | |
| 363 <h2>Chrome Perf</h2> | |
| 364 </center> | |
| 365 <p><b>Build versions: </b><br/> | |
| 366 <label for="direction">Enter version numbers with comma delimiter.</label> | |
| 367 <br/> | |
| 368 <textarea cols="40" rows="5" id="versions"></textarea> | |
| 369 <p><button value="Plot" onClick="setVersion()">Plot</button></p> | |
| 370 <pre id="log"></pre> | |
| 371 <div id="output"></div> | |
| 372 </body> | |
| 373 </html> | |
| OLD | NEW |