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

Side by Side Diff: tools/callstats.html

Issue 1964453002: [tools] improving callstats.html istructions and making callstats.py executable (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: updating callstats.html Created 4 years, 7 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
« no previous file with comments | « no previous file | tools/callstats.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 <html> 1 <html>
2 <!-- 2 <!--
3 Copyright 2016 the V8 project authors. All rights reserved. Use of this source 3 Copyright 2016 the V8 project authors. All rights reserved. Use of this source
4 code is governed by a BSD-style license that can be found in the LICENSE file. 4 code is governed by a BSD-style license that can be found in the LICENSE file.
5 --> 5 -->
6 6
7 <head> 7 <head>
8 <meta charset="UTF-8"> 8 <meta charset="UTF-8">
9 <style> 9 <style>
10 body { 10 body {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } 145 }
146 146
147 .compareSelector { 147 .compareSelector {
148 padding-bottom: 20px; 148 padding-bottom: 20px;
149 } 149 }
150 150
151 .pageDetailTable tbody { 151 .pageDetailTable tbody {
152 cursor: pointer 152 cursor: pointer
153 } 153 }
154 154
155 .pageDetailTable tfoot td {
156 border-top: 1px grey solid;
157 }
158
155 #popover { 159 #popover {
156 position: absolute; 160 position: absolute;
157 transform: translateY(-50%) translateX(40px); 161 transform: translateY(-50%) translateX(40px);
158 box-shadow: -2px 10px 44px -10px #000; 162 box-shadow: -2px 10px 44px -10px #000;
159 border-radius: 5px; 163 border-radius: 5px;
160 z-index: 1; 164 z-index: 1;
161 background-color: #FFF; 165 background-color: #FFF;
162 display: none; 166 display: none;
163 white-space: nowrap; 167 white-space: nowrap;
164 } 168 }
(...skipping 26 matching lines...) Expand all
191 text-align: center; 195 text-align: center;
192 } 196 }
193 197
194 #popover table .compare { 198 #popover table .compare {
195 display: none 199 display: none
196 } 200 }
197 201
198 #popover table.compare .compare { 202 #popover table.compare .compare {
199 display: table-cell; 203 display: table-cell;
200 } 204 }
205
206 #popover .compare .time,
207 #popover .compare .version {
208 padding-left: 10px;
209 }
201 </style> 210 </style>
202 <script> 211 <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"> </script>
212 <script type="text/javascript">
203 "use strict" 213 "use strict"
214 google.charts.load('current', {packages: ['corechart']});
204 215
205 // Did anybody say monkeypatching? 216 // Did anybody say monkeypatching?
206 if (!NodeList.prototype.forEach) { 217 if (!NodeList.prototype.forEach) {
207 NodeList.prototype.forEach = function(func) { 218 NodeList.prototype.forEach = function(func) {
208 for (var i = 0; i < this.length; i++) { 219 for (var i = 0; i < this.length; i++) {
209 func(this[i]); 220 func(this[i]);
210 } 221 }
211 } 222 }
212 } 223 }
213 224
214 var versions; 225 var versions;
215 var selectedPage; 226 var selectedPage;
216 var baselineVersion; 227 var baselineVersion;
217 var selectedEntry; 228 var selectedEntry;
218 229
219 function initialize() { 230 function initialize() {
220 var original = $("column"); 231 var original = $("column");
221 for (var i = 0; i < versions.length || i < 2; i++) { 232 var view = document.createElement('div');
233 view.id = 'view';
234 var i = 0;
235 versions.forEach((version) => {
236 if (!version.enabled) return;
222 // add column 237 // add column
223 var column = original.cloneNode(true); 238 var column = original.cloneNode(true);
224 column.id = "column_" + i; 239 column.id = "column_" + i;
225 // Fill in all versions 240 // Fill in all versions
226 var select = column.querySelector(".version"); 241 var select = column.querySelector(".version");
227 select.id = "selectVersion_" + i; 242 select.id = "selectVersion_" + i;
228 // add all select options 243 // add all select options
229 versions.forEach((version) => { 244 versions.forEach((version) => {
245 if (!version.enabled) return;
230 var option = document.createElement("option"); 246 var option = document.createElement("option");
231 option.textContent = version.name; 247 option.textContent = version.name;
232 option.version = version; 248 option.version = version;
233 select.appendChild(option); 249 select.appendChild(option);
234 }); 250 });
235 // Fill in all page versions 251 // Fill in all page versions
236 select = column.querySelector(".pageVersion"); 252 select = column.querySelector(".pageVersion");
237 select.id = "select_" + i; 253 select.id = "select_" + i;
238 // add all select options 254 // add all pages
239 versions.forEach((version) => { 255 versions.forEach((version) => {
256 if (!version.enabled) return;
240 var optgroup = document.createElement("optgroup"); 257 var optgroup = document.createElement("optgroup");
241 optgroup.label = version.name; 258 optgroup.label = version.name;
242 optgroup.version = version; 259 optgroup.version = version;
243 version.pages.forEach((page) => { 260 version.pages.forEach((page) => {
244 var option = document.createElement("option"); 261 var option = document.createElement("option");
245 option.textContent = page.name; 262 option.textContent = page.name;
246 option.page = page; 263 option.page = page;
247 optgroup.appendChild(option); 264 optgroup.appendChild(option);
248 }); 265 });
249 select.appendChild(optgroup); 266 select.appendChild(optgroup);
250 }); 267 });
251 $("view").appendChild(column); 268 view.appendChild(column);
252 } 269 i++;
270 });
271 var oldView = $('view');
272 oldView.parentNode.replaceChild(view, oldView);
273
253 var select = $('baseline'); 274 var select = $('baseline');
254 removeAllChildren(select); 275 removeAllChildren(select);
255 select.appendChild(document.createElement('option')); 276 select.appendChild(document.createElement('option'));
256 versions.forEach((version) => { 277 versions.forEach((version) => {
257 var option = document.createElement("option"); 278 var option = document.createElement("option");
258 option.textContent = version.name; 279 option.textContent = version.name;
259 option.version = version; 280 option.version = version;
260 select.appendChild(option); 281 select.appendChild(option);
261 }); 282 });
283
284 var versionSelectorList = $('results').querySelector('.versionSelector ul' );
285 removeAllChildren(versionSelectorList);
286 versions.forEach((version) => {
287 var li = document.createElement('li');
288 var checkbox = document.createElement('input');
289 checkbox.type = 'checkbox';
290 checkbox.checked = version.enabled;
291 checkbox.version = version;
292 checkbox.addEventListener('click', handleToggleVersionEnable);
293 li.appendChild(checkbox);
294 li.appendChild(document.createTextNode(version.name));
295 versionSelectorList.appendChild(li);
296 });
262 $('results').querySelectorAll('#results > .hidden').forEach((node) => { 297 $('results').querySelectorAll('#results > .hidden').forEach((node) => {
263 toggleCssClass(node, 'hidden', false); 298 toggleCssClass(node, 'hidden', false);
264 }); 299 });
265 } 300 }
266 301
267 function showPage(firstPage) { 302 function showPage(firstPage) {
303 var changeSelectedEntry = selectedEntry !== undefined
304 && selectedEntry.page === selectedPage;
268 selectedPage = firstPage; 305 selectedPage = firstPage;
269 selectedPage.sort(); 306 selectedPage.sort();
270 showPageInColumn(firstPage, 0); 307 showPageInColumn(firstPage, 0);
271 // Show the other versions of this page in the following columns. 308 // Show the other versions of this page in the following columns.
272 var pageVersions = versions.pageVersions(firstPage.name); 309 var pageVersions = versions.pageVersions(firstPage.name);
273 var index = 1; 310 var index = 1;
274 pageVersions.forEach((page) => { 311 pageVersions.forEach((page) => {
275 if (page !== firstPage) { 312 if (page !== firstPage) {
276 showPageInColumn(page, index); 313 showPageInColumn(page, index);
277 index++; 314 index++;
278 } 315 }
279 }); 316 });
280 showImpactList(selectedPage); 317 if (changeSelectedEntry) {
318 showEntryDetail(selectedPage.getEntry(selectedEntry));
319 } else {
320 showImpactList(selectedPage);
321 }
281 } 322 }
282 323
283 function showPageInColumn(page, columnIndex) { 324 function showPageInColumn(page, columnIndex) {
284 page.sort(); 325 page.sort();
285 var showDiff = (baselineVersion === undefined && columnIndex !== 0) || 326 var showDiff = (baselineVersion === undefined && columnIndex !== 0) ||
286 (baselineVersion !== undefined && page.version !== baselineVersion); 327 (baselineVersion !== undefined && page.version !== baselineVersion);
287 var diffStatus = (td, a, b) => {}; 328 var diffStatus = (td, a, b) => {};
288 if (showDiff) { 329 if (showDiff) {
289 if (baselineVersion !== undefined) { 330 if (baselineVersion !== undefined) {
290 diffStatus = (td, a, b) => { 331 diffStatus = (td, a, b) => {
(...skipping 20 matching lines...) Expand all
311 var column = $('column_' + columnIndex); 352 var column = $('column_' + columnIndex);
312 var select = $('select_' + columnIndex); 353 var select = $('select_' + columnIndex);
313 // Find the matching option 354 // Find the matching option
314 selectOption(select, (i, option) => { 355 selectOption(select, (i, option) => {
315 return option.page == page 356 return option.page == page
316 }); 357 });
317 var table = column.querySelector("table"); 358 var table = column.querySelector("table");
318 var oldTbody = table.querySelector('tbody'); 359 var oldTbody = table.querySelector('tbody');
319 var tbody = document.createElement('tbody'); 360 var tbody = document.createElement('tbody');
320 var referencePage = selectedPage; 361 var referencePage = selectedPage;
321 page.forEachSorted(selectedPage, 362 page.forEachSorted(selectedPage, (parentEntry, entry, referenceEntry) => {
322 (parentEntry, entry, referenceEntry) => { 363 // Filter out entries that do not exist in the first column for the defa ult
323 // Filter out entries that do not exist in the first column for the 364 // view.
324 // default view.
325 if (baselineVersion === undefined && referenceEntry && 365 if (baselineVersion === undefined && referenceEntry &&
326 referenceEntry.time == 0) { 366 referenceEntry.time == 0) {
327 return; 367 return;
328 } 368 }
329 var tr = document.createElement('tr'); 369 var tr = document.createElement('tr');
330 tbody.appendChild(tr); 370 tbody.appendChild(tr);
331 tr.entry = entry; 371 tr.entry = entry;
332 tr.parentEntry = parentEntry; 372 tr.parentEntry = parentEntry;
333 if (!parentEntry) { 373 tr.className = parentEntry === undefined ? 'parent' : 'child';
334 tr.className = 'parent'
335 } else {
336 tr.className = 'child'
337 }
338 // Don't show entries that do not exist on the current page or if we 374 // Don't show entries that do not exist on the current page or if we
339 // compare against the current page 375 // compare against the current page
340 if (entry !== undefined && page.version !== baselineVersion) { 376 if (entry !== undefined && page.version !== baselineVersion) {
341 // If we show a diff, use the baselineVersion as the referenceEntry 377 // If we show a diff, use the baselineVersion as the referenceEntry
342 if (baselineVersion !== undefined) { 378 if (baselineVersion !== undefined) {
343 var baselineEntry = baselineVersion.getEntry(entry); 379 var baselineEntry = baselineVersion.getEntry(entry);
344 if (baselineEntry !== undefined) referenceEntry = baselineEntry 380 if (baselineEntry !== undefined) referenceEntry = baselineEntry
345 } 381 }
346 if (!parentEntry) { 382 if (!parentEntry) {
347 var node = td(tr, '<div class="toggle">►</div>', 'position'); 383 var node = td(tr, '<div class="toggle">►</div>', 'position');
348 node.firstChild.addEventListener('click', handleToggleGroup); 384 node.firstChild.addEventListener('click', handleToggleGroup);
349 } else { 385 } else {
350 td(tr, entry.position == 0 ? '' : entry.position, 'position'); 386 td(tr, entry.position == 0 ? '' : entry.position, 'position');
351 } 387 }
352 td(tr, entry.name, 'name ' + entry.cssClass()); 388 td(tr, entry.name, 'name ' + entry.cssClass());
353 diffStatus( 389 diffStatus(
354 td(tr, ms(entry.time), 'value time'), 390 td(tr, ms(entry.time), 'value time'),
355 entry.time, referenceEntry.time); 391 entry.time, referenceEntry.time);
356 diffStatus( 392 diffStatus(
357 td(tr, percent(entry.timePercent), 'value time'), 393 td(tr, percent(entry.timePercent), 'value time'),
358 entry.time, referenceEntry.time); 394 entry.time, referenceEntry.time);
359 diffStatus( 395 diffStatus(
360 td(tr, count(entry.count), 'value count'), 396 td(tr, count(entry.count), 'value count'),
361 entry.count, referenceEntry.count); 397 entry.count, referenceEntry.count);
362 } else if (baselineVersion !== undefined && referenceEntry 398 } else if (baselineVersion !== undefined && referenceEntry
363 && page.version !== baselineVersion) { 399 && page.version !== baselineVersion) {
364 // Show comparison of entry that does not exist on the current page. 400 // Show comparison of entry that does not exist on the current page.
365 tr.entry = referenceEntry; 401 tr.entry = referenceEntry;
366 td(tr, '-', 'position'); 402 td(tr, '-', 'position');
367 td(tr, referenceEntry.name, 'name'); 403 td(tr, referenceEntry.name, 'name');
368 diffStatus( 404 diffStatus(
369 td(tr, ms(referenceEntry.time), 'value time'), 405 td(tr, ms(referenceEntry.time), 'value time'),
370 referenceEntry.time, 0); 406 referenceEntry.time, 0);
371 diffStatus( 407 diffStatus(
372 td(tr, percent(referenceEntry.timePercent), 'value time'), 408 td(tr, percent(referenceEntry.timePercent), 'value time'),
373 referenceEntry.timePercent, 0); 409 referenceEntry.timePercent, 0);
374 diffStatus( 410 diffStatus(
375 td(tr, count(referenceEntry.count), 'value count'), 411 td(tr, count(referenceEntry.count), 'value count'),
376 referenceEntry.count, 0); 412 referenceEntry.count, 0);
377 } else { 413 } else {
378 // Display empty entry / baseline entry 414 // Display empty entry / baseline entry
379 if (entry !== undefined) { 415 var showBaselineEntry = entry !== undefined;
416 if (showBaselineEntry) {
380 if (!parentEntry) { 417 if (!parentEntry) {
381 var node = td(tr, '<div class="toggle">►</div>', 'position'); 418 var node = td(tr, '<div class="toggle">►</div>', 'position');
382 node.firstChild.addEventListener('click', handleToggleGroup); 419 node.firstChild.addEventListener('click', handleToggleGroup);
383 } else { 420 } else {
384 td(tr, entry.position == 0 ? '' : entry.position, 'position'); 421 td(tr, entry.position == 0 ? '' : entry.position, 'position');
385 } 422 }
386 td(tr, entry.name, 'name'); 423 td(tr, entry.name, 'name');
424 td(tr, ms(entry.time, false), 'value time');
425 td(tr, percent(entry.timePercent, false), 'value time');
426 td(tr, count(entry.count, false), 'value count');
387 } else { 427 } else {
388 td(tr, '-', 'position'); 428 td(tr, '-', 'position');
389 td(tr, '-', 'name'); 429 td(tr, '-', 'name');
430 td(tr, '-', 'value time');
431 td(tr, '-', 'value time');
432 td(tr, '-', 'value count');
390 } 433 }
391 td(tr, '-', 'value time');
392 td(tr, '-', 'value time');
393 td(tr, '-', 'value count');
394 } 434 }
395 }); 435 });
396 table.replaceChild(tbody, oldTbody); 436 table.replaceChild(tbody, oldTbody);
397 var versionSelect = column.querySelector('select.version'); 437 var versionSelect = column.querySelector('select.version');
398 selectOption(versionSelect, (index, option) => { 438 selectOption(versionSelect, (index, option) => {
399 return option.version == page.version 439 return option.version == page.version
400 }); 440 });
401 } 441 }
402 442
403 function selectEntry(entry, updateSelectedPage) { 443 function selectEntry(entry, updateSelectedPage) {
(...skipping 16 matching lines...) Expand all
420 if (firstEntry.parent) showGroup(firstEntry.parent); 460 if (firstEntry.parent) showGroup(firstEntry.parent);
421 } 461 }
422 // Deselect all 462 // Deselect all
423 $('view').querySelectorAll('.list tbody tr').forEach((tr) => { 463 $('view').querySelectorAll('.list tbody tr').forEach((tr) => {
424 toggleCssClass(tr, 'selected', false); 464 toggleCssClass(tr, 'selected', false);
425 }); 465 });
426 // Select the entry row 466 // Select the entry row
427 $('view').querySelectorAll("tbody").forEach((body) => { 467 $('view').querySelectorAll("tbody").forEach((body) => {
428 var row = body.childNodes[rowIndex]; 468 var row = body.childNodes[rowIndex];
429 if (!row) return; 469 if (!row) return;
430 toggleCssClass(row, 'selected', 470 toggleCssClass(row, 'selected', row.entry && row.entry.name ==
431 row.entry && row.entry.name == firstEntry.name); 471 firstEntry.name);
432 }); 472 });
433 if (updateSelectedPage) { 473 if (updateSelectedPage) {
434 entry = selectedEntry.page.version.getEntry(entry); 474 entry = selectedEntry.page.version.getEntry(entry);
435 } 475 }
436 selectedEntry = entry; 476 selectedEntry = entry;
437 showEntryDetail(entry); 477 showEntryDetail(entry);
438 } 478 }
439 479
440 function showEntryDetail(entry) { 480 function showEntryDetail(entry) {
441 var table, tbody, entries; 481 var table, tbody, entries;
442 table = $('detailView').querySelector('.versionDetailTable'); 482 table = $('detailView').querySelector('.versionDetailTable');
443 tbody = document.createElement('tbody'); 483 tbody = document.createElement('tbody');
444 if (entry !== undefined) { 484 if (entry !== undefined) {
445 $('detailView').querySelector('.versionDetail h3 span').innerHTML 485 $('detailView').querySelector('.versionDetail h3 span').innerHTML =
446 = entry.name; 486 entry.name;
447 entries = versions.pageVersions(entry.page.name).map( 487 entries = versions.pageVersions(entry.page.name).map(
448 (page) => { 488 (page) => {
449 return page.get(entry.name) 489 return page.get(entry.name)
450 }); 490 });
451 entries.sort((a, b) => { 491 entries.sort((a, b) => {
452 return a.time - b.time 492 return a.time - b.time
453 }); 493 });
454 entries.forEach((pageEntry) => { 494 entries.forEach((pageEntry) => {
455 if (pageEntry === undefined) return; 495 if (pageEntry === undefined) return;
456 var tr = document.createElement('tr'); 496 var tr = document.createElement('tr');
457 if (pageEntry == entry) tr.className += 'selected'; 497 if (pageEntry == entry) tr.className += 'selected';
458 tr.entry = pageEntry; 498 tr.entry = pageEntry;
459 td(tr, pageEntry.page.version.name, 'version'); 499 td(tr, pageEntry.page.version.name, 'version');
460 td(tr, pageEntry.position, 'value position'); 500 td(tr, pageEntry.position, 'value position');
461 td(tr, ms(pageEntry.time), 'value time'); 501 td(tr, ms(pageEntry.time), 'value time');
462 td(tr, percent(pageEntry.timePercent), 'value time'); 502 td(tr, percent(pageEntry.timePercent), 'value time');
463 td(tr, count(pageEntry.count), 'value count'); 503 td(tr, count(pageEntry.count), 'value count');
464 tbody.appendChild(tr); 504 tbody.appendChild(tr);
465 }); 505 });
466 } 506 }
467 table.replaceChild(tbody, table.querySelector('tbody')); 507 table.replaceChild(tbody, table.querySelector('tbody'));
468 508
469 table = $('detailView').querySelector('.pageDetailTable'); 509 table = $('detailView').querySelector('.pageDetailTable');
470 tbody = document.createElement('tbody'); 510 tbody = document.createElement('tbody');
471 if (entry !== undefined) { 511 if (entry !== undefined) {
472 var version = entry.page.version; 512 var version = entry.page.version;
473 $('detailView').querySelector('.pageDetail h3 span').innerHTML 513 $('detailView').querySelector('.pageDetail h3 span').innerHTML =
474 = version.name; 514 version.name;
475 entries = version.pages.map( 515 entries = version.pages.map(
476 (page) => { 516 (page) => {
477 return page.get(entry.name) 517 return page.get(entry.name)
478 }); 518 });
479 entries.sort((a, b) => { 519 entries.sort((a, b) => {
480 return b.timePercent - a.timePercent 520 var cmp = b.timePercent - a.timePercent;
521 if (cmp.toFixed(1) == 0) return b.time - a.time;
522 return cmp
481 }); 523 });
482 entries.forEach((pageEntry) => { 524 entries.forEach((pageEntry) => {
483 if (pageEntry === undefined) return; 525 if (pageEntry === undefined) return;
484 var tr = document.createElement('tr'); 526 var tr = document.createElement('tr');
485 if (pageEntry === entry) tr.className += 'selected'; 527 if (pageEntry === entry) tr.className += 'selected';
486 tr.entry = pageEntry; 528 tr.entry = pageEntry;
487 td(tr, pageEntry.page.name, 'name'); 529 td(tr, pageEntry.page.name, 'name');
488 td(tr, pageEntry.position, 'value position'); 530 td(tr, pageEntry.position, 'value position');
489 td(tr, ms(pageEntry.time), 'value time'); 531 td(tr, ms(pageEntry.time), 'value time');
490 td(tr, percent(pageEntry.timePercent), 'value time'); 532 td(tr, percent(pageEntry.timePercent), 'value time');
491 td(tr, count(pageEntry.count), 'value count'); 533 td(tr, count(pageEntry.count), 'value count');
492 tbody.appendChild(tr); 534 tbody.appendChild(tr);
493 }); 535 });
494 // show the total for all pages 536 // show the total for all pages
495 var tds = table.querySelectorAll('tfoot td'); 537 var tds = table.querySelectorAll('tfoot td');
496 tds[2].innerHTML = ms(entry.getTimeImpact()); 538 tds[2].innerHTML = ms(entry.getTimeImpact());
497 // Only show the percentage total if we are in diff mode: 539 // Only show the percentage total if we are in diff mode:
498 if (baselineVersion !== undefined) { 540 tds[3].innerHTML = percent(entry.getTimePercentImpact());
499 tds[3].innerHTML = percent(entry.getTimePercentImpact());
500 } else {
501 tds[3].innerHTML = ''
502 }
503 tds[4].innerHTML = count(entry.getCountImpact()); 541 tds[4].innerHTML = count(entry.getCountImpact());
504 } 542 }
505 table.replaceChild(tbody, table.querySelector('tbody')); 543 table.replaceChild(tbody, table.querySelector('tbody'));
506 showImpactList(entry.page); 544 showImpactList(entry.page);
545 showPageGraphs(entry.page);
507 } 546 }
508 547
509 function showImpactList(page) { 548 function showImpactList(page) {
510 var impactView = $('detailView').querySelector('.impactView'); 549 var impactView = $('detailView').querySelector('.impactView');
511 impactView.querySelector('h3 span').innerHTML = page.version.name; 550 impactView.querySelector('h3 span').innerHTML = page.version.name;
512 551
513 var table = impactView.querySelector('table'); 552 var table = impactView.querySelector('table');
514 var tbody = document.createElement('tbody'); 553 var tbody = document.createElement('tbody');
515 var version = page.version; 554 var version = page.version;
516 var entries = version.allEntries(); 555 var entries = version.allEntries();
517 if (selectedEntry !== undefined && selectedEntry.isGroup) { 556 if (selectedEntry !== undefined && selectedEntry.isGroup) {
518 impactView.querySelector('h3 span').innerHTML 557 impactView.querySelector('h3 span').innerHTML += " " + selectedEntry.nam e;
519 += " " + selectedEntry.name;
520 entries = entries.filter((entry) => { 558 entries = entries.filter((entry) => {
521 return entry.name == selectedEntry.name || 559 return entry.name == selectedEntry.name ||
522 (entry.parent && entry.parent.name == selectedEntry.name) 560 (entry.parent && entry.parent.name == selectedEntry.name)
523 }); 561 });
524 } 562 }
563 var isCompareView = baselineVersion !== undefined;
564 entries = entries.filter((entry) => {
565 if (isCompareView) {
566 var impact = entry.getTimeImpact();
567 return impact < -1 || 1 < impact
568 }
569 return entry.getTimePercentImpact() > 0.1;
570 });
525 entries.sort((a, b) => { 571 entries.sort((a, b) => {
526 return b.getTimePercentImpact() - a.getTimePercentImpact(); 572 var cmp = b.getTimePercentImpact() - a.getTimePercentImpact();
573 if (isCompareView || cmp.toFixed(1) == 0) {
574 return b.getTimeImpact() - a.getTimeImpact();
575 }
576 return cmp
527 }); 577 });
528 entries.forEach((entry) => { 578 entries.forEach((entry) => {
529 var tr = document.createElement('tr'); 579 var tr = document.createElement('tr');
530 tr.entry = entry; 580 tr.entry = entry;
531 td(tr, entry.name, 'name'); 581 td(tr, entry.name, 'name');
532 td(tr, ms(entry.getTimeImpact()), 'value time'); 582 td(tr, ms(entry.getTimeImpact()), 'value time');
533 td(tr, percent(entry.getTimePercentImpact()), 'value time'); 583 var percentImpact = entry.getTimePercentImpact();
534 var topPages = entry.getPagesByPercentImpact().slice(0, 2) 584 td(tr, percentImpact > 1000 ? '-' : percent(percentImpact), 'value time' );
585 var topPages = entry.getPagesByPercentImpact().slice(0, 3)
535 .map((each) => { 586 .map((each) => {
536 return each.name + ' (' 587 return each.name + ' (' + percent(each.getEntry(entry).timePercent) +
537 + percent(each.getEntry(entry).timePercent) + ')' 588 ')'
538 }); 589 });
539 td(tr, topPages.join(', '), 'name'); 590 td(tr, topPages.join(', '), 'name');
540 tbody.appendChild(tr); 591 tbody.appendChild(tr);
541 }); 592 });
542 table.replaceChild(tbody, table.querySelector('tbody')); 593 table.replaceChild(tbody, table.querySelector('tbody'));
543 } 594 }
595
596 var selectedGroup;
597 function showPageGraphs(page) {
598 var groups = page.groups.filter(each => each.name != page.total.name);
599 if (selectedGroup == undefined) {
600 selectedGroup = groups[0];
601 } else {
602 groups = groups.filter(each => each.name != selectedGroup.name);
603 groups.unshift(selectedGroup);
604 }
605 var dataTable = new google.visualization.DataTable();
606 dataTable.addColumn('string', 'Name');
607 groups.forEach(group => {
608 var column = dataTable.addColumn('number', group.name);
609 dataTable.setColumnProperty(column, 'group', group);
610 });
611 // Calculate the average row
612 var row = ['Average'];
613 groups.forEach((group) => {
614 row.push(group.getTimeImpact());
615 });
616 dataTable.addRow(row);
617 // Sort the pages by the selected group.
618 var pages = page.version.pages.slice();
619 pages.sort((a, b) => {
620 return b.getEntry(selectedGroup).timePercent - a.getEntry(selectedGroup) .timePercent;
621 });
622 // Calculate the entries for the pages
623 pages.forEach((page) => {
624 row = [page.name];
625 groups.forEach((group) => {
626 row.push(page.getEntry(group).time);
627 });
628 dataTable.addRow(row);
629 });
630
631 var height = 1000/27*page.version.pages.length;
632 var options = {
633 title: 'Page Comparison for Version ' + page.version.name,
634 isStacked: 'percent',
635 height: height ,
636 hAxis: {
637 title: '% Time',
638 minValue: 0,
639 },
640 vAxis: {
641 }
642 };
643 var chart = new google.visualization.BarChart($('pageGraphs'));
644 chart.draw(dataTable, options);
645 google.visualization.events.addListener(chart, 'select', selectHandler);
646 function selectHandler() {
647 var column = chart.getSelection()[0].column;
648 if (column === undefined) return;
649 selectedGroup = dataTable.getColumnProperty(column, 'group');
650 showPageGraphs(selectedEntry.page);
651 }
652 }
544 653
545 function showGroup(entry) { 654 function showGroup(entry) {
546 toggleGroup(entry, true); 655 toggleGroup(entry, true);
547 } 656 }
548 657
549 function toggleGroup(group, show) { 658 function toggleGroup(group, show) {
550 $('view').querySelectorAll(".child").forEach((tr) => { 659 $('view').querySelectorAll(".child").forEach((tr) => {
551 var entry = tr.parentEntry; 660 var entry = tr.parentEntry;
552 if (!entry) return; 661 if (!entry) return;
553 if (entry.name !== group.name) return; 662 if (entry.name !== group.name) return;
554 toggleCssClass(tr, 'visible', show); 663 toggleCssClass(tr, 'visible', show);
555 }); 664 });
556 } 665 }
557 666
558 function showPopover(entry) { 667 function showPopover(entry) {
559 var popover = $('popover'); 668 var popover = $('popover');
560 popover.querySelector('td.name').innerHTML = entry.name; 669 popover.querySelector('td.name').innerHTML = entry.name;
561 popover.querySelector('td.page').innerHTML = entry.page.name; 670 popover.querySelector('td.page').innerHTML = entry.page.name;
562 setPopoverDetail(popover, entry, ''); 671 setPopoverDetail(popover, entry, '');
563 popover.querySelector('table').className = ""; 672 popover.querySelector('table').className = "";
564 if (baselineVersion !== undefined) { 673 if (baselineVersion !== undefined) {
565 entry = baselineVersion.getEntry(entry); 674 entry = baselineVersion.getEntry(entry);
566 if (entry === undefined) return;
567 setPopoverDetail(popover, entry, '.compare'); 675 setPopoverDetail(popover, entry, '.compare');
568 popover.querySelector('table').className = "compare"; 676 popover.querySelector('table').className = "compare";
569 } 677 }
570 } 678 }
571 679
572 function setPopoverDetail(popover, entry, prefix) { 680 function setPopoverDetail(popover, entry, prefix) {
573 popover.querySelector(prefix + '.version').innerHTML 681 var node = (name) => popover.querySelector(prefix + name);
574 = entry.page.version.name; 682 if (entry == undefined) {
575 popover.querySelector(prefix + '.time').innerHTML 683 node('.version').innerHTML = baselineVersion.name;
576 = ms(entry._time, false); 684 node('.time').innerHTML = '-';
577 popover.querySelector(prefix + '.timeVariance').innerHTML 685 node('.timeVariance').innerHTML = '-';
578 = percent(entry.timeVariancePercent, false); 686 node('.percent').innerHTML = '-';
579 popover.querySelector(prefix + '.percent').innerHTML 687 node('.percentVariance').innerHTML = '-';
580 = percent(entry.timePercent, false); 688 node('.count').innerHTML = '-';
581 popover.querySelector(prefix + '.percentVariance').innerHTML 689 node('.countVariance').innerHTML = '-';
582 = percent(entry.timePercentVariancePercent, false); 690 node('.timeImpact').innerHTML = '-';
583 popover.querySelector(prefix + '.count').innerHTML 691 node('.timePercentImpact').innerHTML = '-';
584 = count(entry._count, false); 692 } else {
585 popover.querySelector(prefix + '.countVariance').innerHTML 693 node('.version').innerHTML = entry.page.version.name;
586 = percent(entry.timeVariancePercent, false); 694 node('.time').innerHTML = ms(entry._time, false);
587 popover.querySelector(prefix + '.timeImpact').innerHTML 695 node('.timeVariance').innerHTML
588 = ms(entry.getTimeImpact(false), false); 696 = percent(entry.timeVariancePercent, false);
589 popover.querySelector(prefix + '.timePercentImpact').innerHTML 697 node('.percent').innerHTML = percent(entry.timePercent, false);
590 = percent(entry.getTimeImpactVariancePercent(false), false); 698 node('.percentVariance').innerHTML
699 = percent(entry.timePercentVariancePercent, false);
700 node('.count').innerHTML = count(entry._count, false);
701 node('.countVariance').innerHTML
702 = percent(entry.timeVariancePercent, false);
703 node('.timeImpact').innerHTML
704 = ms(entry.getTimeImpact(false), false);
705 node('.timePercentImpact').innerHTML
706 = percent(entry.getTimeImpactVariancePercent(false), false);
707 }
591 } 708 }
592 709
593 // ======================================================================== 710 // ========================================================================= ==
594 // Helpers 711 // Helpers
595 function $(id) { 712 function $(id) {
596 return document.getElementById(id) 713 return document.getElementById(id)
597 } 714 }
598 715
599 function removeAllChildren(node) { 716 function removeAllChildren(node) {
600 while (node.firstChild) { 717 while (node.firstChild) {
601 node.removeChild(node.firstChild); 718 node.removeChild(node.firstChild);
602 } 719 }
603 } 720 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 if (index == -1) { 758 if (index == -1) {
642 if (toggleState === false) return; 759 if (toggleState === false) return;
643 node.className += ' ' + cssClass; 760 node.className += ' ' + cssClass;
644 return; 761 return;
645 } 762 }
646 if (toggleState === true) return; 763 if (toggleState === true) return;
647 classes.splice(index, 1); 764 classes.splice(index, 1);
648 node.className = classes.join(' '); 765 node.className = classes.join(' ');
649 } 766 }
650 767
651 function diffSign(value, showDiff) { 768 function diffSign(value, digits, unit, showDiff) {
652 if (value <= 0 || showDiff === false) return ''; 769 if (showDiff === false || baselineVersion == undefined) {
653 if (baselineVersion == undefined) return ''; 770 return value.toFixed(digits) + unit;
654 return '+'; 771 }
772 return (value >= 0 ? '+' : '') + value.toFixed(digits) + unit + 'Δ';
655 } 773 }
656 774
657 function ms(time, showDiff) { 775 function ms(value, showDiff) {
658 return diffSign(time, showDiff) + time.toFixed(1) + 'ms'; 776 return diffSign(value, 1, 'ms', showDiff);
659 } 777 }
660 778
661 function count(time, showDiff) { 779 function count(value, showDiff) {
662 return diffSign(time, showDiff) + time.toFixed(0) + '#'; 780 return diffSign(value, 0, '#', showDiff);
663 } 781 }
664 782
665 function percent(time, showDiff) { 783 function percent(value, showDiff) {
666 return diffSign(time, showDiff) + time.toFixed(1) + '%'; 784 return diffSign(value, 1, '%', showDiff);
667 } 785 }
668 // ======================================================================== 786
787 // =========================================================================
669 // EventHandlers 788 // EventHandlers
789 function handleBodyLoad() {
790 $('uploadInput').focus();
791 }
792
670 function handleLoadFile() { 793 function handleLoadFile() {
671 var files = document.getElementById("uploadInput").files; 794 var files = document.getElementById("uploadInput").files;
672 var file = files[0]; 795 var file = files[0];
673 var reader = new FileReader(); 796 var reader = new FileReader();
674 797
675 reader.onload = function(evt) { 798 reader.onload = function(evt) {
676 versions = Versions.fromJSON(JSON.parse(this.result)); 799 versions = Versions.fromJSON(JSON.parse(this.result));
677 initialize() 800 initialize()
678 showPage(versions.versions[0].pages[0]); 801 showPage(versions.versions[0].pages[0]);
679 } 802 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 popover.style.top = event.pageY + 'px'; 863 popover.style.top = event.pageY + 'px';
741 popover.style.display = event.shiftKey ? 'block' : 'none'; 864 popover.style.display = event.shiftKey ? 'block' : 'none';
742 var target = event.target; 865 var target = event.target;
743 while (target.entry === undefined) { 866 while (target.entry === undefined) {
744 target = target.parentNode; 867 target = target.parentNode;
745 if (!target) return; 868 if (!target) return;
746 } 869 }
747 showPopover(target.entry); 870 showPopover(target.entry);
748 } 871 }
749 872
750 // ======================================================================== 873 function handleToggleVersionEnable(event) {
874 var version = this.version;
875 if (version === undefined) return;
876 version.enabled = this.checked;
877 initialize();
878 var page = selectedPage;
879 if (page === undefined || !page.version.enabled) {
880 page = versions.getEnabledPage(page.name);
881 }
882 showPage(page);
883 }
884
885 // ========================================================================= ==
751 886
752 class Versions { 887 class Versions {
753 constructor() { 888 constructor() {
754 this.versions = []; 889 this.versions = [];
755 } 890 }
756 add(version) { 891 add(version) {
757 this.versions.push(version) 892 this.versions.push(version)
758 } 893 }
759 pageVersions(name) { 894 pageVersions(name) {
760 var result = []; 895 var result = [];
761 this.versions.forEach((version) => { 896 this.versions.forEach((version) => {
897 if (!version.enabled) return;
762 var page = version.get(name); 898 var page = version.get(name);
763 if (page !== undefined) result.push(page); 899 if (page !== undefined) result.push(page);
764 }); 900 });
765 return result; 901 return result;
766 } 902 }
767 get length() { 903 get length() {
768 return this.versions.length 904 return this.versions.length
769 } 905 }
770 get(index) { 906 get(index) {
771 return this.versions[index] 907 return this.versions[index]
772 }; 908 };
773 forEach(f) { 909 forEach(f) {
774 this.versions.forEach(f); 910 this.versions.forEach(f);
775 } 911 }
776 sort() { 912 sort() {
777 this.versions.sort((a, b) => { 913 this.versions.sort((a, b) => {
778 if (a.name > b.name) return 1; 914 if (a.name > b.name) return 1;
779 if (a.name < b.name) return -1; 915 if (a.name < b.name) return -1;
780 return 0 916 return 0
781 }) 917 })
782 } 918 }
919 getEnabledPage(name) {
920 for (var i = 0; i < this.versions.length; i++) {
921 var version = this.versions[i];
922 if (!version.enabled) continue;
923 var page = version.get(name);
924 if (page !== undefined) return page;
925 }
926 }
783 } 927 }
784 Versions.fromJSON = function(json) { 928 Versions.fromJSON = function(json) {
785 var versions = new Versions(); 929 var versions = new Versions();
786 for (var version in json) { 930 for (var version in json) {
787 versions.add(Version.fromJSON(version, json[version])); 931 versions.add(Version.fromJSON(version, json[version]));
788 } 932 }
789 versions.sort(); 933 versions.sort();
790 return versions; 934 return versions;
791 } 935 }
792 936
793 class Version { 937 class Version {
794 constructor(name) { 938 constructor(name) {
795 this.name = name; 939 this.name = name;
796 this.pages = [] 940 this.enabled = true;
941 this.pages = [];
797 } 942 }
798 add(page) { 943 add(page) {
799 this.pages.push(page); 944 this.pages.push(page);
800 } 945 }
801 indexOf(name) { 946 indexOf(name) {
802 for (var i = 0; i < this.pages.length; i++) { 947 for (var i = 0; i < this.pages.length; i++) {
803 if (this.pages[i].name == name) return i; 948 if (this.pages[i].name == name) return i;
804 } 949 }
805 return -1; 950 return -1;
806 } 951 }
(...skipping 30 matching lines...) Expand all
837 var entry = page.get(name); 982 var entry = page.get(name);
838 if (entry !== undefined) sum += entry[property]; 983 if (entry !== undefined) sum += entry[property];
839 }); 984 });
840 return sum; 985 return sum;
841 } 986 }
842 getTotalTime(name, showDiff) { 987 getTotalTime(name, showDiff) {
843 return this.getTotalValue(name, showDiff === false ? '_time' : 'time'); 988 return this.getTotalValue(name, showDiff === false ? '_time' : 'time');
844 } 989 }
845 getTotalTimePercent(name, showDiff) { 990 getTotalTimePercent(name, showDiff) {
846 if (baselineVersion === undefined) { 991 if (baselineVersion === undefined) {
847 return this.getTotalValue(name, 'timePercent'); 992 // Return the overall average percent of the given entry name.
993 return this.getTotalValue(name, 'time') /
994 this.getTotalTime('Group-Total') * 100;
848 } 995 }
849 var baselineValue = baselineVersion.getTotalTime(name); 996 // Otherwise return the difference to the sum of the baseline version.
850 return this.getTotalValue(name, 'time') / baselineValue * 100; 997 var baselineValue = baselineVersion.getTotalTime(name, false);
998 return this.getTotalValue(name, '_time') / baselineValue * 100;
851 } 999 }
852 getTotalTimeVariance(name, showDiff) { 1000 getTotalTimeVariance(name, showDiff) {
853 // Calculate the overall error for a given entry name 1001 // Calculate the overall error for a given entry name
854 var sum = 0; 1002 var sum = 0;
855 this.pages.forEach((page) => { 1003 this.pages.forEach((page) => {
856 var entry = page.get(name); 1004 var entry = page.get(name);
857 if (entry === undefined) return; 1005 if (entry === undefined) return;
858 sum += entry.timeVariance * entry.timeVariance; 1006 sum += entry.timeVariance * entry.timeVariance;
859 }); 1007 });
860 return Math.sqrt(sum); 1008 return Math.sqrt(sum);
861 } 1009 }
862 getTotalTimeVariancePercent(name, showDiff) { 1010 getTotalTimeVariancePercent(name, showDiff) {
863 return this.getTotalTimeVariance(name, showDiff) / 1011 return this.getTotalTimeVariance(name, showDiff) /
864 this.getTotalTime(name, showDiff) * 100; 1012 this.getTotalTime(name, showDiff) * 100;
865 } 1013 }
866 getTotalCount(name, showDiff) { 1014 getTotalCount(name, showDiff) {
867 var property = showDiff === false ? '_count' : 'count'; 1015 return this.getTotalValue(name, showDiff === false ? '_count' : 'count') ;
868 return this.getTotalValue(name, property);
869 } 1016 }
870 getPagesByPercentImpact(name) { 1017 getPagesByPercentImpact(name) {
871 var sortedPages = 1018 var sortedPages =
872 this.pages.filter((each) => { 1019 this.pages.filter((each) => {
873 return each.get(name) !== undefined 1020 return each.get(name) !== undefined
874 }); 1021 });
875 sortedPages.sort((a, b) => { 1022 sortedPages.sort((a, b) => {
876 return b.get(name).timePercent - a.get(name).timePercent; 1023 return b.get(name).timePercent - a.get(name).timePercent;
877 }); 1024 });
878 return sortedPages; 1025 return sortedPages;
879 } 1026 }
1027 sort() {
1028 this.pages.sort((a, b) => {
1029 if (a.name > b.name) return 1;
1030 if (a.name < b.name) return -1;
1031 return 0
1032 })
1033 }
880 } 1034 }
881 Version.fromJSON = function(name, data) { 1035 Version.fromJSON = function(name, data) {
882 var version = new Version(name); 1036 var version = new Version(name);
883 for (var page in data) { 1037 for (var page in data) {
884 version.add(Page.fromJSON(version, page, data[page])); 1038 version.add(Page.fromJSON(version, page, data[page]));
885 } 1039 }
1040 version.sort();
886 return version; 1041 return version;
887 } 1042 }
888 1043
889 1044
890 class Page { 1045 class Page {
891 constructor(version, name) { 1046 constructor(version, name) {
892 this.name = name; 1047 this.name = name;
893 this.total = new GroupedEntry('Total', /.*Total.*/); 1048 this.total = new GroupedEntry('Total', /.*Total.*/);
894 this.unclassified = new UnclassifiedEntry(this) 1049 this.unclassified = new UnclassifiedEntry(this)
895 this.groups = [ 1050 this.groups = [
(...skipping 29 matching lines...) Expand all
925 return this.entryDict.get(name) 1080 return this.entryDict.get(name)
926 } 1081 }
927 getEntry(entry) { 1082 getEntry(entry) {
928 if (entry === undefined) return undefined; 1083 if (entry === undefined) return undefined;
929 return this.get(entry.name); 1084 return this.get(entry.name);
930 } 1085 }
931 get length() { 1086 get length() {
932 return this.versions.length 1087 return this.versions.length
933 } 1088 }
934 forEachSorted(referencePage, func) { 1089 forEachSorted(referencePage, func) {
935 // Iterate over all the entries in the order they appear on the 1090 // Iterate over all the entries in the order they appear on the referenc e page.
936 // reference page.
937 referencePage.forEach((parent, referenceEntry) => { 1091 referencePage.forEach((parent, referenceEntry) => {
938 var entry; 1092 var entry;
939 if (parent) parent = this.entryDict.get(parent.name); 1093 if (parent) parent = this.entryDict.get(parent.name);
940 if (referenceEntry) entry = this.entryDict.get(referenceEntry.name); 1094 if (referenceEntry) entry = this.entryDict.get(referenceEntry.name);
941 func(parent, entry, referenceEntry); 1095 func(parent, entry, referenceEntry);
942 }); 1096 });
943 } 1097 }
944 forEach(fun) { 1098 forEach(fun) {
945 this.forEachGroup((group) => { 1099 this.forEachGroup((group) => {
946 fun(undefined, group); 1100 fun(undefined, group);
947 group.forEach((entry) => { 1101 group.forEach((entry) => {
948 fun(group, entry) 1102 fun(group, entry)
949 }); 1103 });
950 }); 1104 });
951 } 1105 }
952 forEachGroup(fun) { 1106 forEachGroup(fun) {
953 this.groups.forEach(fun) 1107 this.groups.forEach(fun)
954 } 1108 }
955 sort() { 1109 sort() {
956 this.groups.sort((a, b) => { 1110 this.groups.sort((a, b) => {
957 return b.time - a.time; 1111 return b.time - a.time;
958 }); 1112 });
959 this.groups.forEach((group) => { 1113 this.groups.forEach((group) => {
960 group.sort() 1114 group.sort()
961 }); 1115 });
962 } 1116 }
963 } 1117 }
964 Page.fromJSON = function(version, name, data) { 1118 Page.fromJSON = function(version, name, data) {
1119 if (name.indexOf('www.') == 0) {
1120 name = name.substring(4);
1121 }
965 var page = new Page(version, name); 1122 var page = new Page(version, name);
966 for (var i = 0; i < data.length; i++) { 1123 for (var i = 0; i < data.length; i++) {
967 page.add(Entry.fromJSON(i, data[data.length - i - 1])); 1124 page.add(Entry.fromJSON(i, data[data.length - i - 1]));
968 } 1125 }
969 page.sort(); 1126 page.sort();
970 return page 1127 return page
971 } 1128 }
972 1129
973 1130
974 class Entry { 1131 class Entry {
(...skipping 25 matching lines...) Expand all
1000 return this.getCompareWithBaseline(this._time, '_time'); 1157 return this.getCompareWithBaseline(this._time, '_time');
1001 } 1158 }
1002 get count() { 1159 get count() {
1003 return this.getCompareWithBaseline(this._count, '_count'); 1160 return this.getCompareWithBaseline(this._count, '_count');
1004 } 1161 }
1005 get timePercent() { 1162 get timePercent() {
1006 var value = this._time / this.page.total._time * 100; 1163 var value = this._time / this.page.total._time * 100;
1007 if (baselineVersion == undefined) return value; 1164 if (baselineVersion == undefined) return value;
1008 var baselineEntry = baselineVersion.getEntry(this); 1165 var baselineEntry = baselineVersion.getEntry(this);
1009 if (!baselineEntry) return value; 1166 if (!baselineEntry) return value;
1010 return (this._time - baselineEntry._time) / 1167 if (baselineVersion === this.page.version) return value;
1011 this.page.total._time * 100; 1168 return (this._time - baselineEntry._time) / this.page.total._time *
1169 100;
1012 } 1170 }
1013 get timePercentVariancePercent() { 1171 get timePercentVariancePercent() {
1014 // Get the absolute values for the percentages 1172 // Get the absolute values for the percentages
1015 return this.timeVariance / this.page.total._time * 100; 1173 return this.timeVariance / this.page.total._time * 100;
1016 } 1174 }
1017 getTimeImpact(showDiff) { 1175 getTimeImpact(showDiff) {
1018 return this.page.version.getTotalTime(this.name, showDiff); 1176 return this.page.version.getTotalTime(this.name, showDiff);
1019 } 1177 }
1020 getTimeImpactVariancePercent(showDiff) { 1178 getTimeImpactVariancePercent(showDiff) {
1021 return this.page.version 1179 return this.page.version.getTotalTimeVariancePercent(this.name, showDiff );
1022 .getTotalTimeVariancePercent(this.name, showDiff);
1023 } 1180 }
1024 getTimePercentImpact(showDiff) { 1181 getTimePercentImpact(showDiff) {
1025 return this.page.version.getTotalTimePercent(this.name, showDiff); 1182 return this.page.version.getTotalTimePercent(this.name, showDiff);
1026 } 1183 }
1027 getCountImpact(showDiff) { 1184 getCountImpact(showDiff) {
1028 return this.page.version.getTotalCount(this.name, showDiff); 1185 return this.page.version.getTotalCount(this.name, showDiff);
1029 } 1186 }
1030 getPagesByPercentImpact() { 1187 getPagesByPercentImpact() {
1031 return this.page.version.getPagesByPercentImpact(this.name); 1188 return this.page.version.getPagesByPercentImpact(this.name);
1032 } 1189 }
(...skipping 25 matching lines...) Expand all
1058 // TODO: sum up variance 1215 // TODO: sum up variance
1059 this.entries.push(entry); 1216 this.entries.push(entry);
1060 entry.parent = this; 1217 entry.parent = this;
1061 return true; 1218 return true;
1062 } 1219 }
1063 forEach(fun) { 1220 forEach(fun) {
1064 if (baselineVersion === undefined) { 1221 if (baselineVersion === undefined) {
1065 this.entries.forEach(fun); 1222 this.entries.forEach(fun);
1066 return; 1223 return;
1067 } 1224 }
1068 // If we have a baslineVersion to compare against show also all entries 1225 // If we have a baslineVersion to compare against show also all entries from the
1069 // from the other group. 1226 // other group.
1070 var tmpEntries = baselineVersion.getEntry(this) 1227 var tmpEntries = baselineVersion.getEntry(this)
1071 .entries.filter((entry) => { 1228 .entries.filter((entry) => {
1072 return this.page.get(entry.name) == undefined 1229 return this.page.get(entry.name) == undefined
1073 }); 1230 });
1074 1231
1075 // The compared entries are sorted by absolute impact. 1232 // The compared entries are sorted by absolute impact.
1076 tmpEntries = tmpEntries.map((entry) => { 1233 tmpEntries = tmpEntries.map((entry) => {
1077 var tmpEntry = new Entry(0, entry.name, 0, 0, 0, 0, 0, 0); 1234 var tmpEntry = new Entry(0, entry.name, 0, 0, 0, 0, 0, 0);
1078 tmpEntry.page = this.page; 1235 tmpEntry.page = this.page;
1079 return tmpEntry; 1236 return tmpEntry;
(...skipping 28 matching lines...) Expand all
1108 if (this._time == 0) return 0; 1265 if (this._time == 0) return 0;
1109 return this.getVarianceForProperty('time') / this._time * 100 1266 return this.getVarianceForProperty('time') / this._time * 100
1110 } 1267 }
1111 get timeVariance() { 1268 get timeVariance() {
1112 return this.getVarianceForProperty('time') 1269 return this.getVarianceForProperty('time')
1113 } 1270 }
1114 } 1271 }
1115 1272
1116 class UnclassifiedEntry extends GroupedEntry { 1273 class UnclassifiedEntry extends GroupedEntry {
1117 constructor(page) { 1274 constructor(page) {
1118 super('Unclassified'); 1275 super('Runtime');
1119 this.page = page; 1276 this.page = page;
1120 this._time = undefined; 1277 this._time = undefined;
1121 this._count = undefined; 1278 this._count = undefined;
1122 } 1279 }
1123 add(entry) { 1280 add(entry) {
1124 this.entries.push(entry); 1281 this.entries.push(entry);
1125 entry.parent = this; 1282 entry.parent = this;
1126 return true; 1283 return true;
1127 } 1284 }
1128 forEachPageGroup(fun) { 1285 forEachPageGroup(fun) {
(...skipping 18 matching lines...) Expand all
1147 this.forEachPageGroup((group) => { 1304 this.forEachPageGroup((group) => {
1148 this._count -= group._count; 1305 this._count -= group._count;
1149 }); 1306 });
1150 } 1307 }
1151 return this.getCompareWithBaseline(this._count, '_count'); 1308 return this.getCompareWithBaseline(this._count, '_count');
1152 } 1309 }
1153 } 1310 }
1154 </script> 1311 </script>
1155 </head> 1312 </head>
1156 1313
1157 <body onmousemove="handleUpdatePopover(event)"> 1314 <body onmousemove="handleUpdatePopover(event)" onload="handleBodyLoad()">
1158 <h1>Runtime Stats Komparator</h1> 1315 <h1>Runtime Stats Komparator</h1>
1159 1316
1160 <div id="results"> 1317 <div id="results">
1161 <div class="inline"> 1318 <div class="inline">
1162 <h2>Data</h2> 1319 <h2>Data</h2>
1163 <form name="fileForm"> 1320 <form name="fileForm">
1164 <p> 1321 <p>
1165 <input id="uploadInput" type="file" name="files" onchange="handleLoadF ile();"> 1322 <input id="uploadInput" type="file" name="files" onchange="handleLoadF ile();" accept=".json">
1166 </p> 1323 </p>
1167 </form> 1324 </form>
1168 </div> 1325 </div>
1326
1169 <div class="inline hidden"> 1327 <div class="inline hidden">
1170 <h2>Result</h2> 1328 <h2>Result</h2>
1171 <div class="compareSelector"> 1329 <div class="compareSelector inline">
1172 Compare against:&nbsp;<select id="baseline" onchange="handleSelectBaseli ne(this, event)"></select><br/> 1330 Compare against:&nbsp;<select id="baseline" onchange="handleSelectBaseli ne(this, event)"></select><br/>
1173 <span style="color: #060">Green</span> the selected version above perfor ms 1331 <span style="color: #060">Green</span> the selected version above perfor ms
1174 better on this measurement. 1332 better on this measurement.
1175 </div> 1333 </div>
1334 <div class="versionSelector inline">
1335 Select Versions:
1336 <ul></ul>
1337 </div>
1176 </div> 1338 </div>
1177 <div id="view"> 1339 <div id="view">
1178 </div> 1340 </div>
1179 1341
1180 <div id="detailView" class="hidden"> 1342 <div id="detailView" class="hidden">
1181 <h2></h2> 1343 <h2></h2>
1182 <div class="versionDetail inline"> 1344 <div class="versionDetail inline">
1183 <h3><span></span></h3> 1345 <h3>Version Comparison for <span></span></h3>
1184 <table class="versionDetailTable" onclick="handleSelectDetailRow(this, e vent);"> 1346 <table class="versionDetailTable" onclick="handleSelectDetailRow(this, e vent);">
1185 <thead> 1347 <thead>
1186 <tr> 1348 <tr>
1187 <th class="version">Version&nbsp;</th> 1349 <th class="version">Version&nbsp;</th>
1188 <th class="position">Pos.&nbsp;</th> 1350 <th class="position">Pos.&nbsp;</th>
1189 <th class="value time">Time▴&nbsp;</th> 1351 <th class="value time">Time▴&nbsp;</th>
1190 <th class="value time">Percent&nbsp;</th> 1352 <th class="value time">Percent&nbsp;</th>
1191 <th class="value count">Count&nbsp;</th> 1353 <th class="value count">Count&nbsp;</th>
1192 </tr> 1354 </tr>
1193 </thead> 1355 </thead>
1194 <tbody></tbody> 1356 <tbody></tbody>
1195 </table> 1357 </table>
1196 </div> 1358 </div>
1197 <div class="pageDetail inline"> 1359 <div class="pageDetail inline">
1198 <h3><span></span></h3> 1360 <h3>Page Comparison for <span></span></h3>
1199 <table class="pageDetailTable" onclick="handleSelectDetailRow(this, even t);"> 1361 <table class="pageDetailTable" onclick="handleSelectDetailRow(this, even t);">
1200 <thead> 1362 <thead>
1201 <tr> 1363 <tr>
1202 <th class="page">Page&nbsp;</th> 1364 <th class="page">Page&nbsp;</th>
1203 <th class="position">Pos.&nbsp;</th> 1365 <th class="position">Pos.&nbsp;</th>
1204 <th class="value time">Time&nbsp;</th> 1366 <th class="value time">Time&nbsp;</th>
1205 <th class="value time">Percent▾&nbsp;</th> 1367 <th class="value time">Percent▾&nbsp;</th>
1206 <th class="value count">Count&nbsp;</th> 1368 <th class="value count">Count&nbsp;</th>
1207 </tr> 1369 </tr>
1208 </thead> 1370 </thead>
(...skipping 17 matching lines...) Expand all
1226 <th class="page">Name&nbsp;</th> 1388 <th class="page">Name&nbsp;</th>
1227 <th class="value time">Time&nbsp;</th> 1389 <th class="value time">Time&nbsp;</th>
1228 <th class="value time">Percent▾&nbsp;</th> 1390 <th class="value time">Percent▾&nbsp;</th>
1229 <th class="">Top Pages</th> 1391 <th class="">Top Pages</th>
1230 </tr> 1392 </tr>
1231 </thead> 1393 </thead>
1232 <tbody></tbody> 1394 <tbody></tbody>
1233 </table> 1395 </table>
1234 </div> 1396 </div>
1235 </div> 1397 </div>
1398 <div id="pageGraphs" class="hidden">
1399 </div>
1236 1400
1237 <div id="column" class="column"> 1401 <div id="column" class="column">
1238 <div class="header"> 1402 <div class="header">
1239 <select class="version" onchange="handleSelectVersion(this, event);"></s elect> 1403 <select class="version" onchange="handleSelectVersion(this, event);"></s elect>
1240 <select class="pageVersion" onchange="handleSelectPage(this, event);"></ select> 1404 <select class="pageVersion" onchange="handleSelectPage(this, event);"></ select>
1241 </div> 1405 </div>
1242 <table class="list" onclick="handleSelectRow(this, event);"> 1406 <table class="list" onclick="handleSelectRow(this, event);">
1243 <thead> 1407 <thead>
1244 <tr> 1408 <tr>
1245 <th class="position">Pos.&nbsp;</th> 1409 <th class="position">Pos.&nbsp;</th>
1246 <th class="name">Name&nbsp;</th> 1410 <th class="name">Name&nbsp;</th>
1247 <th class="value time">Time&nbsp;</th> 1411 <th class="value time">Time&nbsp;</th>
1248 <th class="value time">Percent&nbsp;</th> 1412 <th class="value time">Percent&nbsp;</th>
1249 <th class="value count">Count&nbsp;</th> 1413 <th class="value count">Count&nbsp;</th>
1250 </tr> 1414 </tr>
1251 </thead> 1415 </thead>
1252 <tbody></tbody> 1416 <tbody></tbody>
1253 </table> 1417 </table>
1254 </div> 1418 </div>
1255 </div> 1419 </div>
1256 1420
1257 <div class="inline"> 1421 <div class="inline">
1258 <h2>Usage</h2> 1422 <h2>Usage</h2>
1259 <ol> 1423 <ol>
1424 <li>Install scipy, e.g. <code>sudo aptitude install python-scipy</code>
1260 <li>Build chrome with the <a href="https://codereview.chromium.org/1923893 002">extended runtime callstats</a>.</li> 1425 <li>Build chrome with the <a href="https://codereview.chromium.org/1923893 002">extended runtime callstats</a>.</li>
1261 <li>Run callstats.py with a web-page-replay archive: 1426 <li>Run <code>callstats.py</code> with a web-page-replay archive:
1262 <pre>./callstats.py run \ 1427 <pre>$V8_DIR/tools/callstats.py run \
1263 --replay-bin=$CHROME_SRC/third_party/webpagereplay/replay.py \ 1428 --replay-bin=$CHROME_SRC/third_party/webpagereplay/replay.py \
1264 --replay-wpr=top25.wpr \ 1429 --replay-wpr=$INPUT_DIR/top25.wpr \
1265 --js-flags="" \ 1430 --js-flags="" \
1266 --with-chrome=$CHROME_SRC/out/Release/chrome \ 1431 --with-chrome=$CHROME_SRC/out/Release/chrome \
1267 --sites-file=top25.json</pre> 1432 --sites-file=$INPUT_DIR/top25.json</pre>
1268 </li> 1433 </li>
1269 <li>Move results file to a subdirectory: <code>mkdir $VERSION; mv *.txt $V ERSION</code></li> 1434 <li>Move results file to a subdirectory: <code>mkdir $VERSION_DIR; mv *.tx t $VERSION_DIR</code></li>
1270 <li>Repeat from step 1 with a different configuration (e.g. <code>--js-fla gs="--nolazy"</code>).</li> 1435 <li>Repeat from step 1 with a different configuration (e.g. <code>--js-fla gs="--nolazy"</code>).</li>
1271 <li>Create the final results file: <code>./callstats.py json $VERSION1 $VE RSION2 > result.json</code></li> 1436 <li>Create the final results file: <code>./callstats.py json $VERSION_DIR1 $VERSION_DIR2 > result.json</code></li>
1272 <li>Use <code>results.json</code> on this site.</code> 1437 <li>Use <code>results.json</code> on this site.</code>
1273 </ol> 1438 </ol>
1274 </div> 1439 </div>
1275 1440
1276 <div id="popover"> 1441 <div id="popover">
1277 <div class="popoverArrow"></div> 1442 <div class="popoverArrow"></div>
1278 <table> 1443 <table>
1279 <tr> 1444 <tr>
1280 <td class="name" colspan="6"></td> 1445 <td class="name" colspan="6"></td>
1281 </tr> 1446 </tr>
(...skipping 25 matching lines...) Expand all
1307 <td>Overall Impact:</td> 1472 <td>Overall Impact:</td>
1308 <td class="timeImpact"></td><td>±</td><td class="timePercentImpact"></td > 1473 <td class="timeImpact"></td><td>±</td><td class="timePercentImpact"></td >
1309 <td class="compare timeImpact"></td><td class="compare"> ± </td><td clas s="compare timePercentImpact"></td> 1474 <td class="compare timeImpact"></td><td class="compare"> ± </td><td clas s="compare timePercentImpact"></td>
1310 </tr> 1475 </tr>
1311 </table> 1476 </table>
1312 </div> 1477 </div>
1313 1478
1314 </body> 1479 </body>
1315 1480
1316 </html> 1481 </html>
OLDNEW
« no previous file with comments | « no previous file | tools/callstats.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698