Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: perf/dashboard/ui/generic_plotter.html

Issue 1654813003: Remove old dead perf dashboard pages and js (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « perf/dashboard/ui/endure_plotter.html ('k') | perf/dashboard/ui/js/coordinates.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 For testing this file locally, start a localhost server at the root of the
11 perf directory (e.g. with "python -m SimpleHTTPServer") and pass in a
12 baseUrl as a query parameter, e.g.
13 http://localhost:8000/dashboard/ui/generic_plotter.html?history=150&rev=-1&gra ph=dom&baseUrl=http://localhost:8000/data/linux-release-webkit-latest/dromaeo_do mcore/.
14
15 You need a localhost server to get around Chromium's restrictions on loading
16 file urls in XMLHttpRequests.
17
18 A brief note on terminology as used here: a "graph" is a plotted screenful
19 of data, showing the results of one type of test: for example, the
20 page-load-time graph. A "trace" is a single line on a graph, showing one
21 one for the test: for example, the reference build trace on the
22 page-load-time graph.
23
24 This page plots arbitrary numerical data loaded from files in a specific
25 format. It uses two or more data files, all JSON-encoded:
26
27 graphs.dat: a list of objects, each with these properties: name (the name
28 of a graph) and units (the units for the data to be read by humans).
29 Schematically:
30 [{"name": <graph_name>, "units": <units>}, ...]
31
32 <graphname>-summary.dat: for each of the graphs listed in graphs.dat, the
33 corresponding summary file holds rows of data. Each row of data is an
34 object with several properties:
35 "rev": the revision number for this row of data
36 "traces": an object with several properties of its own. The name of
37 the property corresponds to a trace name, used only as an
38 internal identifier, and the property's value is an array of
39 its measurement and that measurement's standard deviation (or
40 other measurement error).
41 Schematically:
42 {"rev": <rev>,
43 "traces": {<trace_name1>: [<value1>, <stddev1>],
44 <trace_name2>: [<value2>, <stddev2>], ...}
45 }
46 -->
47 <head>
48 <style>
49 body {
50 font-family: sans-serif;
51 }
52 div#output {
53 cursor: pointer;
54 }
55 div#switcher * {
56 border: 1px solid black;
57 border-radius: 4px 4px 0 0;
58 padding-left: 0.5em;
59 padding-right: 0.5em;
60 }
61 div#switcher a {
62 background: #ddd;
63 cursor: pointer;
64 }
65 canvas.plot {
66 border: 1px solid black;
67 }
68 div.plot-coordinates {
69 font-family: monospace;
70 }
71 iframe {
72 display: none;
73 width: 100%;
74 height: 100%;
75 border: none;
76 }
77 .selector {
78 border: solid 1px black;
79 cursor: pointer;
80 padding-left: 0.3em;
81 background-color: white;
82 width: 80px;
83 display: inline-block;
84 }
85 .selector:hover {
86 background-color: rgb(200,200,250);
87 }
88 div#selectors {
89 display: none;
90 right: 6px;
91 position: absolute;
92 }
93 #explain {
94 font-size: 0.75em;
95 font-style: italic;
96 color: rgb(100,100,100);
97 }
98 #views {
99 border: 1px solid black;
100 width: 100%;
101 display: none;
102 }
103 #webkit-tab {
104 border-left: none;
105 display: none;
106 }
107 </style>
108
109 <script src="js/common.js"></script>
110 <script src="js/plotter.js"></script>
111 <script src="js/coordinates.js"></script>
112 <script src="config.js"></script>
113 <script>
114 document.title = Config.title + ' - ' + Config.buildslave;
115
116 var did_position_details = false;
117 var units = 'thing-a-ma-bobs';
118 var graph_list = [];
119 var first_trace = '';
120
121 var refresh_params = false;
122 var params = ParseParams();
123 if (!('history' in params)) {
124 params.history = 150;
125 refresh_params = true;
126 }
127 if (!('rev' in params)) {
128 params.rev = -1; // -1 specifies the latest revision.
129 refresh_params = true;
130 }
131 if (refresh_params)
132 window.location.href = MakeURL(params);
133
134 if (!Config.detailTabs)
135 Config.detailTabs = {'view-change': 'CL'};
136
137 /**
138 * Encapsulates a *-summary.dat file.
139 * @constructor
140 */
141 function Rows(data) {
142 this.rows = data.split('\n');
143 this.length = this.rows.length;
144 }
145
146 /**
147 * Returns the row at the given index.
148 */
149 Rows.prototype.get = function(i) {
150 if (!i in this.rows || this.rows[i] === undefined) return null;
151 if (!this.rows[i].length) return null;
152 var row = JSON.parse(this.rows[i]);
153 row.revision = isNaN(row['rev']) ? row['rev'] : parseInt(row['rev']);
154 row.webkitRevision = isNaN(row['webkit_rev']) ?
155 row['webkit_rev'] : parseInt(row['webkit_rev']);
156 return row;
157 };
158
159 function report_error(error) {
160 document.getElementById("output").innerHTML = "<p>" + error + "</p>";
161 }
162
163 function received_graph_list(data, error) {
164 if (error) {
165 report_error(error);
166 return;
167 }
168 graph_list = JSON.parse(data);
169
170 if (!('graph' in params) || params.graph == '') {
171 if (graph_list.length > 0)
172 params.graph = graph_list[0].name
173 }
174
175 // Add a selection tab for each graph, and find the units for the selected
176 // one while we're at it.
177 tabs = [];
178 for (var index = 0; index < graph_list.length; ++index) {
179 var graph = graph_list[index];
180 tabs.push(graph.name);
181 if (graph.name == params.graph)
182 units = graph.units;
183 }
184 initPlotSwitcher(tabs);
185
186 // Fetch the data for the selected graph.
187 fetch_summary();
188
189 }
190
191 function go_to(graph) {
192 params.graph = graph;
193 if (params.graph == '')
194 delete params.graph;
195 window.location.href = MakeURL(params);
196 }
197
198 function get_url() {
199 var new_url = encodeURI(window.location.href);
200 new_url = new_url.replace(/'/g, '%27');
201 new_url = new_url.replace(/\&lookout=1/, '');
202 if (new_url.indexOf('http://') == 0 || new_url.indexOf('https://') == 0)
203 return new_url;
204 return '';
205 }
206
207 function on_clicked_plot(prev_entry, current_entry) {
208 if ('lookout' in params) {
209 window.open(get_url());
210 return;
211 }
212
213 // Define sources for detail tabs
214 if ('view-change' in Config.detailTabs) {
215 // If the changeLinkPrefix has {PREV_CL}/{CL} markers, replace them.
216 // Otherwise, append to the URL.
217 var url = Config.changeLinkPrefix;
218 if (url.indexOf('{PREV_CL}') >= 0 || url.indexOf('{CL}') >= 0) {
219 url = url.replace('{PREV_CL}', prev_entry.chromium);
220 url = url.replace('{CL}', current_entry.chromium);
221 } else {
222 url += prev_entry.chromium + ':' + current_entry.chromium;
223 }
224 document.getElementById('view-change').setAttribute('src', url);
225 }
226 if ('view-pages' in Config.detailTabs) {
227 document.getElementById('view-pages').src = 'details.html?cl=' +
228 current_entry.chromium + '&graph=' + params.graph + '&trace=' +
229 first_trace;
230 }
231 if ('view-coverage' in Config.detailTabs) {
232 document.getElementById('view-coverage').src =
233 Config.coverageLinkPrefix + current_entry.chromium;
234 }
235 if (!isNaN(prev_entry.webkit) && !isNaN(current_entry.webkit) &&
236 prev_entry.webkit <= current_entry.webkit) {
237 Config.detailTabs['view-webkit-change'] = 'Webkit';
238 document.getElementById('webkit-tab').style.display = 'inline-block';
239 var url = 'http://trac.webkit.org/log/?verbose=on&rev=' +
240 current_entry.webkit + '&stop_rev=' + prev_entry.webkit;
241 document.getElementById('view-webkit-change').src = url;
242 } else {
243 var webkitView = document.getElementById('view-webkit-change');
244 if (webkitView.style.display == 'block')
245 show_first_view();
246 delete Config.detailTabs['view-webkit-change'];
247 document.getElementById('webkit-tab').style.display = 'none';
248 }
249
250 if (!did_position_details) {
251 show_first_view();
252 position_details();
253 did_position_details = true;
254 }
255 }
256
257 function show_first_view() {
258 for (var tab in Config.detailTabs) {
259 change_view(tab);
260 break;
261 }
262 }
263
264 function received_summary(data, error) {
265 if (error) {
266 report_error(error);
267 return;
268 }
269 // Parse the summary data file.
270 var rows = new Rows(data);
271 var max_rows = rows.length;
272 if (max_rows > params.history)
273 max_rows = params.history;
274
275 var allTraces = {};
276
277 // Find the start and end of the data slice we will focus on.
278 var start_row = 0;
279 if (params.rev > 0) {
280 var i = 0;
281 while (i < rows.length) {
282 var row = rows.get(i);
283
284 // If the current row's revision is higher than the desired revision,
285 // continue searching.
286 if (row.revision > params.rev) {
287 i++;
288 continue;
289 }
290
291 // We're either just under or at the desired revision.
292 start_row = i;
293
294 // If the desired revision does not exist, use the row before it.
295 if (row.revision < params.rev && start_row > 0)
296 start_row -= 1;
297
298 break;
299 }
300 }
301
302 // Some summary files contain data not listed in rev-descending order. For
303 // those cases, it is possible we will find a start row in the middle of the
304 // data whose neighboring data is not nearby. See xp-release-dual-core
305 // moz rev 265 => no graph.
306 var end_row = start_row + max_rows;
307
308 // Build and order a list of revision numbers.
309 var revisionNumbers = [];
310 var hasNumericRevisions = true;
311 // graphData[rev] = {trace1:[value, stddev], trace2:[value, stddev], ...}
312 var graphData = {};
313 for (var i = start_row; i < end_row; ++i) {
314 var row = rows.get(i);
315 if (!row)
316 continue;
317 var traces = row['traces'];
318 for (var j = 0; j < traces.length; ++j)
319 traces[j] = parseFloat(traces[j]);
320
321 if (!(row.revision in graphData)) {
322 graphData[row.revision] = {};
323 }
324 graphData[row.revision][row.webkitRevision] = traces;
325 if (isNaN(row.revision) || isNaN(row.webkitRevision)) {
326 hasNumericRevisions = false;
327 }
328 revisionNumbers.push(
329 { chromium: row.revision, webkit: row.webkitRevision });
330
331 // Collect unique trace names. If traces are explicitly specified in
332 // params, delete unspecified trace data.
333 for (var traceName in traces) {
334 if (typeof(params['trace']) != 'undefined' &&
335 params['trace'][traceName] != 1) {
336 delete(traces[traceName]);
337 }
338 allTraces[traceName] = 1;
339 }
340 }
341
342 // Build a list of all the trace names we've seen, in the order in which
343 // they appear in the data file. Although JS objects are not required by
344 // the spec to iterate their properties in order, in practice they do,
345 // because it causes compatibility problems otherwise.
346 var traceNames = [];
347 for (var traceName in allTraces)
348 traceNames.push(traceName);
349
350 first_trace = traceNames[0];
351
352 // If the revisions are numeric (svn), sort them numerically to ensure they
353 // are in ascending order. Otherwise, if the revisions aren't numeric (git),
354 // reverse them under the assumption the rows were prepended to the file.
355 if (hasNumericRevisions) {
356 revisionNumbers.sort(function(a, b) {
357 var revdiff = parseInt(a.chromium, 10) - parseInt(b.chromium, 10);
358 if (revdiff != 0) {
359 return revdiff;
360 }
361 return parseInt(a.webkit, 10) - parseInt(b.webkit, 10);
362 });
363 } else {
364 revisionNumbers.reverse();
365 }
366
367 // Build separate ordered lists of trace data.
368 var traceData = {};
369 for (var revIndex = 0; revIndex < revisionNumbers.length; ++revIndex) {
370 var rev = revisionNumbers[revIndex].chromium;
371 var webkitrev = revisionNumbers[revIndex].webkit;
372 var revisionData = graphData[rev][webkitrev];
373 for (var nameIndex = 0; nameIndex < traceNames.length; ++nameIndex) {
374 var traceName = traceNames[nameIndex];
375 if (!traceData[traceName])
376 traceData[traceName] = [];
377 if (!revisionData[traceName])
378 traceData[traceName].push([NaN, NaN]);
379 else
380 traceData[traceName].push([parseFloat(revisionData[traceName][0]),
381 parseFloat(revisionData[traceName][1])]);
382 }
383 }
384 var plotData = [];
385 for (var traceName in traceData)
386 plotData.push(traceData[traceName]);
387 var plotter = new Plotter(revisionNumbers, plotData, traceNames, units,
388 document.getElementById("output"));
389 plotter.onclick = on_clicked_plot;
390 plotter.plot();
391 }
392
393 function fetch_summary() {
394 if ('graph' in params)
395 file = escape(params.graph) + "-summary.dat"
396 else
397 file = "summary.dat"
398 var baseUrl = params.baseUrl || '';
399 Fetch(baseUrl + file, received_summary);
400 }
401
402 function fetch_graph_list() {
403 var baseUrl = params.baseUrl || '';
404 Fetch(baseUrl + "graphs.dat", received_graph_list);
405 }
406
407 function initPlotSwitcher(tabs) {
408 var switcher = document.getElementById("switcher");
409 for (var i = 0; i < tabs.length; i++) {
410 var is_selected = tabs[i] == params.graph;
411 var tab = document.createElement(is_selected ? "span" : "a");
412 tab.appendChild(document.createTextNode(tabs[i] + " "));
413 if (!is_selected)
414 tab.addEventListener("click", goToClosure(tabs[i]), false);
415 switcher.appendChild(tab);
416 }
417 }
418
419 function goToClosure(graph) {
420 return function(){go_to(graph)};
421 }
422
423 function position_details() {
424 var views = document.getElementById("views");
425 views.style.display = "block";
426 var selectors = document.getElementById("selectors");
427 selectors.style.display = "block";
428
429 var output = document.getElementById("output");
430 var views_width = output.offsetWidth - selectors.offsetWidth;
431
432 views.style.height = (window.innerHeight - output.offsetHeight -
433 output.offsetTop - 16) + "px";
434 selectors.style.top = (views.offsetTop - selectors.offsetHeight + 1) + "px";
435 }
436
437 function change_view(target) {
438 for (var tab in Config.detailTabs) {
439 document.getElementById(tab).style.display =
440 (tab == target ? "block" : "none");
441 }
442 }
443
444 function init() {
445 // We need to fill the graph list before parsing the params or fetching the
446 // data, so we have a default graph in case none was specified.
447 fetch_graph_list();
448 }
449
450 window.addEventListener("resize", position_details, false);
451 window.addEventListener("load", init, false);
452 </script>
453 </head>
454
455
456 <body>
457 <div id="header_lookout" align="center">
458 <font style='color: #0066FF; font-family: Arial, serif;
459 font-size: 20pt; font-weight: bold;'>
460 <script>
461 document.write("<a target=\"_blank\" href=\"");
462 document.write(get_url());
463 document.write("\">");
464 if ('header' in params && params.header != '') {
465 document.write(escape(params.header));
466 } else {
467 document.write(Config.title);
468 }
469 document.write("</a>");
470 </script>
471 </font>
472 </div>
473
474 <div id="header_text">
475 Builds generated by the <a href="http://build.chromium.org/">Chromium Buildbot</ a>
476 are run through <b>
477 <script>
478 document.write(Config.title);
479 </script>
480 </b>and the results of that test are charted here.
481 </div>
482
483 <div id="explain">
484 The vertical axis is measured values, and the horizontal
485 axis is the revision number for the build being tested.
486 </div>
487 <p></p>
488 <div id="switcher">
489
490 </div>
491 <div id="output"></div>
492 <div id="details">
493 <div id="views">
494 <script>
495 for (var tab in Config.detailTabs) {
496 document.write("<iframe id=\"" + tab + "\"></iframe>");
497 }
498 </script>
499 <iframe id='view-webkit-change'></iframe>
500 </div>
501 <div id="selectors">
502 <script>
503 var firstTab = true;
504 for (var tab in Config.detailTabs) {
505 document.write("<div ");
506 if (firstTab) {
507 firstTab = false;
508 } else {
509 document.write("style=\"border-left: none\" ");
510 }
511 document.write("class=\"selector\" onclick=\"change_view('"
512 + tab + "')\">" + Config.detailTabs[tab] + "</div>");
513 }
514 </script><div id="webkit-tab" class="selector"
515 onclick="change_view('view-webkit-change')">Webkit</div>
516 </div>
517 </div>
518 <pre id="log"></pre>
519 <script>
520 if ('lookout' in params) {
521 document.getElementById("switcher").style.display = "none";
522 document.getElementById("details").style.display = "none";
523 document.getElementById("header_text").style.display = "none";
524 document.getElementById("explain").style.display = "none";
525 if ('thumbnail' in params) {
526 document.getElementById("header_lookout").style.display = "none";
527 }
528 } else {
529 document.getElementById("header_lookout").style.display = "none";
530 }
531 </script>
532 </body>
533 </html>
OLDNEW
« no previous file with comments | « perf/dashboard/ui/endure_plotter.html ('k') | perf/dashboard/ui/js/coordinates.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698