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 |