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

Side by Side Diff: tools/callstats.html

Issue 2040823003: [tools] Update callstats.[py|html] (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 min-width: 200px; 50 min-width: 200px;
51 } 51 }
52 52
53 .column .header { 53 .column .header {
54 padding: 0 10px 0 10px 54 padding: 0 10px 0 10px
55 } 55 }
56 56
57 #column { 57 #column {
58 display: none; 58 display: none;
59 } 59 }
60 60
61 .list { 61 .list {
62 width: 100%; 62 width: 100%;
63 } 63 }
64 64
65 select { 65 select {
66 width: 100% 66 width: 100%
67 } 67 }
68 68
69 .list tbody { 69 .list tbody {
70 cursor: pointer; 70 cursor: pointer;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 } 103 }
104 104
105 .list tr.parent.selected { 105 .list tr.parent.selected {
106 background-color: #DDD; 106 background-color: #DDD;
107 } 107 }
108 108
109 tr.selected { 109 tr.selected {
110 background-color: #DDD; 110 background-color: #DDD;
111 } 111 }
112 112
113 .codeSearch {
114 display: block-inline;
115 float: right;
116 border-radius: 5px;
117 background-color: #EEE;
118 width: 1em;
119 text-align: center;
120 }
121
113 .list .position { 122 .list .position {
114 text-align: right; 123 text-align: right;
115 display: none; 124 display: none;
116 } 125 }
117 126
118 .list div.toggle { 127 .list div.toggle {
119 cursor: pointer; 128 cursor: pointer;
120 } 129 }
121 130
122 #column_0 .position { 131 #column_0 .position {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 } 209 }
201 210
202 #popover table.compare .compare { 211 #popover table.compare .compare {
203 display: table-cell; 212 display: table-cell;
204 } 213 }
205 214
206 #popover .compare .time, 215 #popover .compare .time,
207 #popover .compare .version { 216 #popover .compare .version {
208 padding-left: 10px; 217 padding-left: 10px;
209 } 218 }
219 .graph,
220 .graph .content {
221 width: 100%;
222 }
223
224 .diff .hideDiff {
225 display: none;
226 }
227 .noDiff .hideNoDiff {
228 display: none;
229 }
210 </style> 230 </style>
211 <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"> </script> 231 <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"> </script>
212 <script type="text/javascript"> 232 <script type="text/javascript">
213 "use strict" 233 "use strict"
214 google.charts.load('current', {packages: ['corechart']}); 234 google.charts.load('current', {packages: ['corechart']});
215 235
216 // Did anybody say monkeypatching? 236 // Did anybody say monkeypatching?
217 if (!NodeList.prototype.forEach) { 237 if (!NodeList.prototype.forEach) {
218 NodeList.prototype.forEach = function(func) { 238 NodeList.prototype.forEach = function(func) {
219 for (var i = 0; i < this.length; i++) { 239 for (var i = 0; i < this.length; i++) {
220 func(this[i]); 240 func(this[i]);
221 } 241 }
222 } 242 }
223 } 243 }
224 244
225 var versions; 245 var versions;
246 var pages;
226 var selectedPage; 247 var selectedPage;
227 var baselineVersion; 248 var baselineVersion;
228 var selectedEntry; 249 var selectedEntry;
229 250
230 function initialize() { 251 function initialize() {
231 var original = $("column"); 252 var original = $("column");
232 var view = document.createElement('div'); 253 var view = document.createElement('div');
233 view.id = 'view'; 254 view.id = 'view';
234 var i = 0; 255 var i = 0;
235 versions.forEach((version) => { 256 versions.forEach((version) => {
(...skipping 14 matching lines...) Expand all
250 }); 271 });
251 // Fill in all page versions 272 // Fill in all page versions
252 select = column.querySelector(".pageVersion"); 273 select = column.querySelector(".pageVersion");
253 select.id = "select_" + i; 274 select.id = "select_" + i;
254 // add all pages 275 // add all pages
255 versions.forEach((version) => { 276 versions.forEach((version) => {
256 if (!version.enabled) return; 277 if (!version.enabled) return;
257 var optgroup = document.createElement("optgroup"); 278 var optgroup = document.createElement("optgroup");
258 optgroup.label = version.name; 279 optgroup.label = version.name;
259 optgroup.version = version; 280 optgroup.version = version;
260 version.pages.forEach((page) => { 281 version.forEachPage((page) => {
261 var option = document.createElement("option"); 282 var option = document.createElement("option");
262 option.textContent = page.name; 283 option.textContent = page.name;
263 option.page = page; 284 option.page = page;
264 optgroup.appendChild(option); 285 optgroup.appendChild(option);
265 }); 286 });
266 select.appendChild(optgroup); 287 select.appendChild(optgroup);
267 }); 288 });
268 view.appendChild(column); 289 view.appendChild(column);
269 i++; 290 i++;
270 }); 291 });
271 var oldView = $('view'); 292 var oldView = $('view');
272 oldView.parentNode.replaceChild(view, oldView); 293 oldView.parentNode.replaceChild(view, oldView);
273 294
274 var select = $('baseline'); 295 var select = $('baseline');
275 removeAllChildren(select); 296 removeAllChildren(select);
276 select.appendChild(document.createElement('option')); 297 select.appendChild(document.createElement('option'));
277 versions.forEach((version) => { 298 versions.forEach((version) => {
278 var option = document.createElement("option"); 299 var option = document.createElement("option");
279 option.textContent = version.name; 300 option.textContent = version.name;
280 option.version = version; 301 option.version = version;
281 select.appendChild(option); 302 select.appendChild(option);
282 }); 303 });
304 initializeToggleList(versions.versions, $('versionSelector'));
305 initializeToggleList(pages.values(), $('pageSelector'));
306 initializeToggleContentVisibility();
307 }
283 308
284 var versionSelectorList = $('results').querySelector('.versionSelector ul' ); 309 function initializeToggleList(items, node) {
285 removeAllChildren(versionSelectorList); 310 var list = node.querySelector('ul');
286 versions.forEach((version) => { 311 removeAllChildren(list);
312 items = Array.from(items);
313 items.sort(NameComparator);
314 items.forEach((item) => {
287 var li = document.createElement('li'); 315 var li = document.createElement('li');
288 var checkbox = document.createElement('input'); 316 var checkbox = document.createElement('input');
289 checkbox.type = 'checkbox'; 317 checkbox.type = 'checkbox';
290 checkbox.checked = version.enabled; 318 checkbox.checked = item.enabled;
291 checkbox.version = version; 319 checkbox.item = item;
292 checkbox.addEventListener('click', handleToggleVersionEnable); 320 checkbox.addEventListener('click', handleToggleVersionEnable);
293 li.appendChild(checkbox); 321 li.appendChild(checkbox);
294 li.appendChild(document.createTextNode(version.name)); 322 li.appendChild(document.createTextNode(item.name));
295 versionSelectorList.appendChild(li); 323 list.appendChild(li);
296 }); 324 });
297 $('results').querySelectorAll('#results > .hidden').forEach((node) => { 325 $('results').querySelectorAll('#results > .hidden').forEach((node) => {
298 toggleCssClass(node, 'hidden', false); 326 toggleCssClass(node, 'hidden', false);
327 })
328 }
329
330 function initializeToggleContentVisibility() {
331 var nodes = document.querySelectorAll('.toggleContentVisibility');
332 nodes.forEach((node) => {
333 var content = node.querySelector('.content');
334 var header = node.querySelector('h1,h2,h3');
335 if (content === undefined || header === undefined) return;
336 if (header.querySelector('input') != undefined) return;
337 var checkbox = document.createElement('input');
338 checkbox.type = 'checkbox';
339 checkbox.checked = content.className.indexOf('hidden') == -1;
340 checkbox.contentNode = content;
341 checkbox.addEventListener('click', handleToggleContentVisibility);
342 header.insertBefore(checkbox, header.childNodes[0]);
299 }); 343 });
300 } 344 }
301 345
302 function showPage(firstPage) { 346 function showPage(firstPage) {
303 var changeSelectedEntry = selectedEntry !== undefined 347 var changeSelectedEntry = selectedEntry !== undefined
304 && selectedEntry.page === selectedPage; 348 && selectedEntry.page === selectedPage;
305 selectedPage = firstPage; 349 selectedPage = firstPage;
306 selectedPage.sort(); 350 selectedPage.sort();
307 showPageInColumn(firstPage, 0); 351 showPageInColumn(firstPage, 0);
308 // Show the other versions of this page in the following columns. 352 // Show the other versions of this page in the following columns.
309 var pageVersions = versions.pageVersions(firstPage.name); 353 var pageVersions = versions.getPageVersions(firstPage);
310 var index = 1; 354 var index = 1;
311 pageVersions.forEach((page) => { 355 pageVersions.forEach((page) => {
312 if (page !== firstPage) { 356 if (page !== firstPage) {
313 showPageInColumn(page, index); 357 showPageInColumn(page, index);
314 index++; 358 index++;
315 } 359 }
316 }); 360 });
317 if (changeSelectedEntry) { 361 if (changeSelectedEntry) {
318 showEntryDetail(selectedPage.getEntry(selectedEntry)); 362 showEntryDetail(selectedPage.getEntry(selectedEntry));
319 } else { 363 } else {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 if (baselineVersion !== undefined) { 422 if (baselineVersion !== undefined) {
379 var baselineEntry = baselineVersion.getEntry(entry); 423 var baselineEntry = baselineVersion.getEntry(entry);
380 if (baselineEntry !== undefined) referenceEntry = baselineEntry 424 if (baselineEntry !== undefined) referenceEntry = baselineEntry
381 } 425 }
382 if (!parentEntry) { 426 if (!parentEntry) {
383 var node = td(tr, '<div class="toggle">►</div>', 'position'); 427 var node = td(tr, '<div class="toggle">►</div>', 'position');
384 node.firstChild.addEventListener('click', handleToggleGroup); 428 node.firstChild.addEventListener('click', handleToggleGroup);
385 } else { 429 } else {
386 td(tr, entry.position == 0 ? '' : entry.position, 'position'); 430 td(tr, entry.position == 0 ? '' : entry.position, 'position');
387 } 431 }
388 td(tr, entry.name, 'name ' + entry.cssClass()); 432 addCodeSearchButton(entry,
433 td(tr, entry.name, 'name ' + entry.cssClass()));
434
389 diffStatus( 435 diffStatus(
390 td(tr, ms(entry.time), 'value time'), 436 td(tr, ms(entry.time), 'value time'),
391 entry.time, referenceEntry.time); 437 entry.time, referenceEntry.time);
392 diffStatus( 438 diffStatus(
393 td(tr, percent(entry.timePercent), 'value time'), 439 td(tr, percent(entry.timePercent), 'value time'),
394 entry.time, referenceEntry.time); 440 entry.time, referenceEntry.time);
395 diffStatus( 441 diffStatus(
396 td(tr, count(entry.count), 'value count'), 442 td(tr, count(entry.count), 'value count'),
397 entry.count, referenceEntry.count); 443 entry.count, referenceEntry.count);
398 } else if (baselineVersion !== undefined && referenceEntry 444 } else if (baselineVersion !== undefined && referenceEntry
399 && page.version !== baselineVersion) { 445 && page.version !== baselineVersion) {
400 // Show comparison of entry that does not exist on the current page. 446 // Show comparison of entry that does not exist on the current page.
401 tr.entry = referenceEntry; 447 tr.entry = new Entry(0, referenceEntry.name);
448 tr.entry.page = page;
402 td(tr, '-', 'position'); 449 td(tr, '-', 'position');
403 td(tr, referenceEntry.name, 'name'); 450 td(tr, referenceEntry.name, 'name');
404 diffStatus( 451 diffStatus(
405 td(tr, ms(referenceEntry.time), 'value time'), 452 td(tr, ms(-referenceEntry.time), 'value time'),
406 referenceEntry.time, 0); 453 -referenceEntry.time, 0);
407 diffStatus( 454 diffStatus(
408 td(tr, percent(referenceEntry.timePercent), 'value time'), 455 td(tr, percent(-referenceEntry.timePercent), 'value time'),
409 referenceEntry.timePercent, 0); 456 -referenceEntry.timePercent, 0);
410 diffStatus( 457 diffStatus(
411 td(tr, count(referenceEntry.count), 'value count'), 458 td(tr, count(-referenceEntry.count), 'value count'),
412 referenceEntry.count, 0); 459 -referenceEntry.count, 0);
413 } else { 460 } else {
414 // Display empty entry / baseline entry 461 // Display empty entry / baseline entry
415 var showBaselineEntry = entry !== undefined; 462 var showBaselineEntry = entry !== undefined;
416 if (showBaselineEntry) { 463 if (showBaselineEntry) {
417 if (!parentEntry) { 464 if (!parentEntry) {
418 var node = td(tr, '<div class="toggle">►</div>', 'position'); 465 var node = td(tr, '<div class="toggle">►</div>', 'position');
419 node.firstChild.addEventListener('click', handleToggleGroup); 466 node.firstChild.addEventListener('click', handleToggleGroup);
420 } else { 467 } else {
421 td(tr, entry.position == 0 ? '' : entry.position, 'position'); 468 td(tr, entry.position == 0 ? '' : entry.position, 'position');
422 } 469 }
(...skipping 14 matching lines...) Expand all
437 var versionSelect = column.querySelector('select.version'); 484 var versionSelect = column.querySelector('select.version');
438 selectOption(versionSelect, (index, option) => { 485 selectOption(versionSelect, (index, option) => {
439 return option.version == page.version 486 return option.version == page.version
440 }); 487 });
441 } 488 }
442 489
443 function selectEntry(entry, updateSelectedPage) { 490 function selectEntry(entry, updateSelectedPage) {
444 if (updateSelectedPage) { 491 if (updateSelectedPage) {
445 entry = selectedPage.version.getEntry(entry); 492 entry = selectedPage.version.getEntry(entry);
446 } 493 }
447 var rowIndex; 494 var rowIndex = 0;
448 var needsPageSwitch = updateSelectedPage && entry.page != selectedPage; 495 var needsPageSwitch = updateSelectedPage && entry.page != selectedPage;
449 // If clicked in the detail row change the first column to that page. 496 // If clicked in the detail row change the first column to that page.
450 if (needsPageSwitch) showPage(entry.page); 497 if (needsPageSwitch) showPage(entry.page);
451 var childNodes = $('column_0').querySelector('.list tbody').childNodes; 498 var childNodes = $('column_0').querySelector('.list tbody').childNodes;
452 for (var i = 0; i < childNodes.length; i++) { 499 for (var i = 0; i < childNodes.length; i++) {
453 if (childNodes[i].entry.name == entry.name) { 500 if (childNodes[i].entry.name == entry.name) {
454 rowIndex = i; 501 rowIndex = i;
455 break; 502 break;
456 } 503 }
457 } 504 }
(...skipping 13 matching lines...) Expand all
471 firstEntry.name); 518 firstEntry.name);
472 }); 519 });
473 if (updateSelectedPage) { 520 if (updateSelectedPage) {
474 entry = selectedEntry.page.version.getEntry(entry); 521 entry = selectedEntry.page.version.getEntry(entry);
475 } 522 }
476 selectedEntry = entry; 523 selectedEntry = entry;
477 showEntryDetail(entry); 524 showEntryDetail(entry);
478 } 525 }
479 526
480 function showEntryDetail(entry) { 527 function showEntryDetail(entry) {
528 showVersionDetails(entry);
529 showPageDetails(entry);
530 showImpactList(entry.page);
531 showGraphs(entry.page);
532 }
533
534 function showVersionDetails(entry) {
481 var table, tbody, entries; 535 var table, tbody, entries;
482 table = $('detailView').querySelector('.versionDetailTable'); 536 table = $('detailView').querySelector('.versionDetailTable');
483 tbody = document.createElement('tbody'); 537 tbody = document.createElement('tbody');
484 if (entry !== undefined) { 538 if (entry !== undefined) {
485 $('detailView').querySelector('.versionDetail h3 span').innerHTML = 539 $('detailView').querySelector('.versionDetail h3 span').innerHTML =
486 entry.name; 540 entry.name + ' in ' + entry.page.name;
487 entries = versions.pageVersions(entry.page.name).map( 541 entries = versions.getPageVersions(entry.page).map(
488 (page) => { 542 (page) => {
489 return page.get(entry.name) 543 return page.get(entry.name)
490 }); 544 });
491 entries.sort((a, b) => { 545 entries.sort((a, b) => {
492 return a.time - b.time 546 return a.time - b.time
493 }); 547 });
494 entries.forEach((pageEntry) => { 548 entries.forEach((pageEntry) => {
495 if (pageEntry === undefined) return; 549 if (pageEntry === undefined) return;
496 var tr = document.createElement('tr'); 550 var tr = document.createElement('tr');
497 if (pageEntry == entry) tr.className += 'selected'; 551 if (pageEntry == entry) tr.className += 'selected';
498 tr.entry = pageEntry; 552 tr.entry = pageEntry;
553 var isBaselineEntry = pageEntry.page.version == baselineVersion;
499 td(tr, pageEntry.page.version.name, 'version'); 554 td(tr, pageEntry.page.version.name, 'version');
500 td(tr, pageEntry.position, 'value position'); 555 td(tr, ms(pageEntry.time, !isBaselineEntry), 'value time');
501 td(tr, ms(pageEntry.time), 'value time'); 556 td(tr, percent(pageEntry.timePercent, !isBaselineEntry), 'value time') ;
502 td(tr, percent(pageEntry.timePercent), 'value time'); 557 td(tr, count(pageEntry.count, !isBaselineEntry), 'value count');
503 td(tr, count(pageEntry.count), 'value count');
504 tbody.appendChild(tr); 558 tbody.appendChild(tr);
505 }); 559 });
506 } 560 }
507 table.replaceChild(tbody, table.querySelector('tbody')); 561 table.replaceChild(tbody, table.querySelector('tbody'));
562 }
508 563
564 function showPageDetails(entry) {
565 var table, tbody, entries;
509 table = $('detailView').querySelector('.pageDetailTable'); 566 table = $('detailView').querySelector('.pageDetailTable');
510 tbody = document.createElement('tbody'); 567 tbody = document.createElement('tbody');
511 if (entry !== undefined) { 568 if (entry === undefined) {
512 var version = entry.page.version; 569 table.replaceChild(tbody, table.querySelector('tbody'));
513 $('detailView').querySelector('.pageDetail h3 span').innerHTML = 570 return;
514 version.name; 571 }
515 entries = version.pages.map( 572 var version = entry.page.version;
516 (page) => { 573 var showDiff = version !== baselineVersion;
517 return page.get(entry.name) 574 $('detailView').querySelector('.pageDetail h3 span').innerHTML =
518 }); 575 version.name;
519 entries.sort((a, b) => { 576 entries = version.pages.map((page) => {
520 var cmp = b.timePercent - a.timePercent; 577 if (!page.enabled) return;
521 if (cmp.toFixed(1) == 0) return b.time - a.time; 578 return page.get(entry.name)
522 return cmp
523 }); 579 });
524 entries.forEach((pageEntry) => { 580 entries.sort((a, b) => {
525 if (pageEntry === undefined) return; 581 var cmp = b.timePercent - a.timePercent;
526 var tr = document.createElement('tr'); 582 if (cmp.toFixed(1) == 0) return b.time - a.time;
527 if (pageEntry === entry) tr.className += 'selected'; 583 return cmp
528 tr.entry = pageEntry; 584 });
529 td(tr, pageEntry.page.name, 'name'); 585 entries.forEach((pageEntry) => {
530 td(tr, pageEntry.position, 'value position'); 586 if (pageEntry === undefined) return;
531 td(tr, ms(pageEntry.time), 'value time'); 587 var tr = document.createElement('tr');
532 td(tr, percent(pageEntry.timePercent), 'value time'); 588 if (pageEntry === entry) tr.className += 'selected';
533 td(tr, count(pageEntry.count), 'value count'); 589 tr.entry = pageEntry;
534 tbody.appendChild(tr); 590 td(tr, pageEntry.page.name, 'name');
535 }); 591 td(tr, ms(pageEntry.time, showDiff), 'value time');
536 // show the total for all pages 592 td(tr, percent(pageEntry.timePercent, showDiff), 'value time');
537 var tds = table.querySelectorAll('tfoot td'); 593 td(tr, percent(pageEntry.timePercentPerEntry, showDiff),
538 tds[2].innerHTML = ms(entry.getTimeImpact()); 594 'value time hideNoDiff');
539 // Only show the percentage total if we are in diff mode: 595 td(tr, count(pageEntry.count, showDiff), 'value count');
540 tds[3].innerHTML = percent(entry.getTimePercentImpact()); 596 tbody.appendChild(tr);
541 tds[4].innerHTML = count(entry.getCountImpact()); 597 });
542 } 598 // show the total for all pages
599 var tds = table.querySelectorAll('tfoot td');
600 tds[1].innerHTML = ms(entry.getTimeImpact(), showDiff);
601 // Only show the percentage total if we are in diff mode:
602 tds[2].innerHTML = percent(entry.getTimePercentImpact(), showDiff);
603 tds[3].innerHTML = '';
604 tds[4].innerHTML = count(entry.getCountImpact(), showDiff);
543 table.replaceChild(tbody, table.querySelector('tbody')); 605 table.replaceChild(tbody, table.querySelector('tbody'));
544 showImpactList(entry.page);
545 showPageGraphs(entry.page);
546 } 606 }
547 607
548 function showImpactList(page) { 608 function showImpactList(page) {
549 var impactView = $('detailView').querySelector('.impactView'); 609 var impactView = $('detailView').querySelector('.impactView');
550 impactView.querySelector('h3 span').innerHTML = page.version.name; 610 impactView.querySelector('h3 span').innerHTML = page.version.name;
551 611
552 var table = impactView.querySelector('table'); 612 var table = impactView.querySelector('table');
553 var tbody = document.createElement('tbody'); 613 var tbody = document.createElement('tbody');
554 var version = page.version; 614 var version = page.version;
555 var entries = version.allEntries(); 615 var entries = version.allEntries();
(...skipping 30 matching lines...) Expand all
586 .map((each) => { 646 .map((each) => {
587 return each.name + ' (' + percent(each.getEntry(entry).timePercent) + 647 return each.name + ' (' + percent(each.getEntry(entry).timePercent) +
588 ')' 648 ')'
589 }); 649 });
590 td(tr, topPages.join(', '), 'name'); 650 td(tr, topPages.join(', '), 'name');
591 tbody.appendChild(tr); 651 tbody.appendChild(tr);
592 }); 652 });
593 table.replaceChild(tbody, table.querySelector('tbody')); 653 table.replaceChild(tbody, table.querySelector('tbody'));
594 } 654 }
595 655
596 var selectedGroup; 656 function showGraphs(page) {
597 function showPageGraphs(page) { 657 var groups = page.groups.slice();
598 var groups = page.groups.filter(each => each.name != page.total.name); 658 // Sort groups by the biggest impact
659 groups.sort((a, b) => {
660 return b.getTimeImpact() - a.getTimeImpact();
661 });
599 if (selectedGroup == undefined) { 662 if (selectedGroup == undefined) {
600 selectedGroup = groups[0]; 663 selectedGroup = groups[0];
601 } else { 664 } else {
602 groups = groups.filter(each => each.name != selectedGroup.name); 665 groups = groups.filter(each => each.name != selectedGroup.name);
603 groups.unshift(selectedGroup); 666 groups.unshift(selectedGroup);
604 } 667 }
668 showPageGraph(groups, page);
669 showVersionGraph(groups, page);
670 showPageVersionGraph(groups, page);
671 }
672
673 function getGraphDataTable(groups) {
605 var dataTable = new google.visualization.DataTable(); 674 var dataTable = new google.visualization.DataTable();
606 dataTable.addColumn('string', 'Name'); 675 dataTable.addColumn('string', 'Name');
607 groups.forEach(group => { 676 groups.forEach(group => {
608 var column = dataTable.addColumn('number', group.name); 677 var column = dataTable.addColumn('number', group.name.substring(6));
609 dataTable.setColumnProperty(column, 'group', group); 678 dataTable.setColumnProperty(column, 'group', group);
610 }); 679 });
680 return dataTable;
681 }
682
683 var selectedGroup;
684 function showPageGraph(groups, page) {
685 var isDiffView = baselineVersion !== undefined;
686 var dataTable = getGraphDataTable(groups);
611 // Calculate the average row 687 // Calculate the average row
612 var row = ['Average']; 688 var row = ['Average'];
613 groups.forEach((group) => { 689 groups.forEach((group) => {
614 row.push(group.getTimeImpact()); 690 if (isDiffView) {
691 row.push(group.isTotal ? 0 : group.getAverageTimeImpact());
692 } else {
693 row.push(group.isTotal ? 0 : group.getTimeImpact());
694 }
615 }); 695 });
616 dataTable.addRow(row); 696 dataTable.addRow(row);
617 // Sort the pages by the selected group. 697 // Sort the pages by the selected group.
618 var pages = page.version.pages.slice(); 698 var pages = page.version.pages.filter(page => page.enabled);
619 pages.sort((a, b) => { 699 function sumDiff(page) {
620 return b.getEntry(selectedGroup).timePercent - a.getEntry(selectedGroup) .timePercent; 700 var sum = 0;
621 }); 701 groups.forEach(group => {
702 var value = group.getTimePercentImpact() -
703 page.getEntry(group).timePercent;
704 sum += value * value;
705 });
706 return sum;
707 }
708 if (isDiffView) {
709 pages.sort((a, b) => {
710 return b.getEntry(selectedGroup).time-
711 a.getEntry(selectedGroup).time;
712 });
713 } else {
714 pages.sort((a, b) => {
715 return b.getEntry(selectedGroup).timePercent -
716 a.getEntry(selectedGroup).timePercent;
717 });
718 }
719 // Sort by sum of squared distance to the average.
720 // pages.sort((a, b) => {
721 // return a.distanceFromTotalPercent() - b.distanceFromTotalPercent();
722 // });
622 // Calculate the entries for the pages 723 // Calculate the entries for the pages
623 pages.forEach((page) => { 724 pages.forEach((page) => {
624 row = [page.name]; 725 row = [page.name];
625 groups.forEach((group) => { 726 groups.forEach((group) => {
626 row.push(page.getEntry(group).time); 727 row.push(group.isTotal ? 0 : page.getEntry(group).time);
627 }); 728 });
628 dataTable.addRow(row); 729 var rowIndex = dataTable.addRow(row);
730 dataTable.setRowProperty(rowIndex, 'page', page);
629 }); 731 });
732 renderGraph('Pages for ' + page.version.name, groups, dataTable,
733 'pageGraph', isDiffView ? true : 'percent');
734 }
630 735
631 var height = 1000/27*page.version.pages.length; 736 function showVersionGraph(groups, page) {
737 var dataTable = getGraphDataTable(groups);
738 var row;
739 var vs = versions.versions.filter(version => version.enabled);
740 vs.sort((a, b) => {
741 return b.getEntry(selectedGroup).getTimeImpact() -
742 a.getEntry(selectedGroup).getTimeImpact();
743 });
744 // Calculate the entries for the versions
745 vs.forEach((version) => {
746 row = [version.name];
747 groups.forEach((group) => {
748 row.push(group.isTotal ? 0 : version.getEntry(group).getTimeImpact());
749 });
750 var rowIndex = dataTable.addRow(row);
751 dataTable.setRowProperty(rowIndex, 'page', page);
752 });
753 renderGraph('Versions Total Time over all Pages', groups, dataTable,
754 'versionGraph', true);
755 }
756
757 function showPageVersionGraph(groups, page) {
758 var dataTable = getGraphDataTable(groups);
759 var row;
760 var vs = versions.getPageVersions(page);
761 vs.sort((a, b) => {
762 return b.getEntry(selectedGroup).time - a.getEntry(selectedGroup).time;
763 });
764 // Calculate the entries for the versions
765 vs.forEach((page) => {
766 row = [page.version.name];
767 groups.forEach((group) => {
768 row.push(group.isTotal ? 0 : page.getEntry(group).time);
769 });
770 var rowIndex = dataTable.addRow(row);
771 dataTable.setRowProperty(rowIndex, 'page', page);
772 });
773 renderGraph('Versions for ' + page.name, groups, dataTable,
774 'pageVersionGraph', true);
775 }
776
777 function renderGraph(title, groups, dataTable, id, isStacked) {
778 var isDiffView = baselineVersion !== undefined;
779 var formatter = new google.visualization.NumberFormat({
780 suffix: (isDiffView ? 'msΔ' : 'ms'),
781 negativeColor: 'red',
782 groupingSymbol: "'"
783 });
784 for (var i = 1; i < dataTable.getNumberOfColumns(); i++) {
785 formatter.format(dataTable, i);
786 }
787 var height = 85 + 28 * dataTable.getNumberOfRows();
632 var options = { 788 var options = {
633 title: 'Page Comparison for Version ' + page.version.name, 789 isStacked: isStacked,
634 isStacked: 'percent', 790 height: height,
635 height: height ,
636 hAxis: { 791 hAxis: {
637 title: '% Time',
638 minValue: 0, 792 minValue: 0,
639 }, 793 },
794 animation:{
795 duration: 500,
796 easing: 'out',
797 },
640 vAxis: { 798 vAxis: {
641 } 799 },
800 explorer: {
801 actions: ['dragToZoom', 'rightClickToReset'],
802 maxZoomIn: 0.01
803 },
804 legend: {position:'top', textStyle:{fontSize: '16px'}},
805 chartArea: {left:200, top:50, width:'98%', height:'80%'},
806 colors: groups.map(each => each.color)
642 }; 807 };
643 var chart = new google.visualization.BarChart($('pageGraphs')); 808 var parentNode = $(id);
809 parentNode.querySelector('h2>span, h3>span').innerHTML = title;
810 var graphNode = parentNode.querySelector('.content');
811
812 var chart = graphNode.chart;
813 if (chart === undefined) {
814 chart = graphNode.chart = new google.visualization.BarChart(graphNode);
815 } else {
816 google.visualization.events.removeAllListeners(chart);
817 }
818 google.visualization.events.addListener(chart, 'select', selectHandler);
819 function getChartEntry(selection) {
820 if (!selection) return undefined;
821 var column = selection.column;
822 if (column == undefined) return undefined;
823 var selectedGroup = dataTable.getColumnProperty(column, 'group');
824 var row = selection.row;
825 if (row == null) return selectedGroup;
826 var page = dataTable.getRowProperty(row, 'page');
827 if (!page) return selectedGroup;
828 return page.getEntry(selectedGroup);
829 }
830 function selectHandler() {
831 selectedGroup = getChartEntry(chart.getSelection()[0])
832 if (!selectedGroup) return;
833 selectEntry(selectedGroup, true);
834 }
835
836 // Make our global tooltips work
837 google.visualization.events.addListener(chart, 'onmouseover', mouseOverHan dler);
838 function mouseOverHandler(selection) {
839 graphNode.entry = getChartEntry(selection);
840 }
644 chart.draw(dataTable, options); 841 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 } 842 }
653 843
654 function showGroup(entry) { 844 function showGroup(entry) {
655 toggleGroup(entry, true); 845 toggleGroup(entry, true);
656 } 846 }
657 847
658 function toggleGroup(group, show) { 848 function toggleGroup(group, show) {
659 $('view').querySelectorAll(".child").forEach((tr) => { 849 $('view').querySelectorAll(".child").forEach((tr) => {
660 var entry = tr.parentEntry; 850 var entry = tr.parentEntry;
661 if (!entry) return; 851 if (!entry) return;
(...skipping 15 matching lines...) Expand all
677 } 867 }
678 } 868 }
679 869
680 function setPopoverDetail(popover, entry, prefix) { 870 function setPopoverDetail(popover, entry, prefix) {
681 var node = (name) => popover.querySelector(prefix + name); 871 var node = (name) => popover.querySelector(prefix + name);
682 if (entry == undefined) { 872 if (entry == undefined) {
683 node('.version').innerHTML = baselineVersion.name; 873 node('.version').innerHTML = baselineVersion.name;
684 node('.time').innerHTML = '-'; 874 node('.time').innerHTML = '-';
685 node('.timeVariance').innerHTML = '-'; 875 node('.timeVariance').innerHTML = '-';
686 node('.percent').innerHTML = '-'; 876 node('.percent').innerHTML = '-';
877 node('.percentPerEntry').innerHTML = '-';
687 node('.percentVariance').innerHTML = '-'; 878 node('.percentVariance').innerHTML = '-';
688 node('.count').innerHTML = '-'; 879 node('.count').innerHTML = '-';
689 node('.countVariance').innerHTML = '-'; 880 node('.countVariance').innerHTML = '-';
690 node('.timeImpact').innerHTML = '-'; 881 node('.timeImpact').innerHTML = '-';
691 node('.timePercentImpact').innerHTML = '-'; 882 node('.timePercentImpact').innerHTML = '-';
692 } else { 883 } else {
693 node('.version').innerHTML = entry.page.version.name; 884 node('.version').innerHTML = entry.page.version.name;
694 node('.time').innerHTML = ms(entry._time, false); 885 node('.time').innerHTML = ms(entry._time, false);
695 node('.timeVariance').innerHTML 886 node('.timeVariance').innerHTML
696 = percent(entry.timeVariancePercent, false); 887 = percent(entry.timeVariancePercent, false);
697 node('.percent').innerHTML = percent(entry.timePercent, false); 888 node('.percent').innerHTML = percent(entry.timePercent, false);
889 node('.percentPerEntry').innerHTML
890 = percent(entry.timePercentPerEntry, false);
698 node('.percentVariance').innerHTML 891 node('.percentVariance').innerHTML
699 = percent(entry.timePercentVariancePercent, false); 892 = percent(entry.timePercentVariancePercent, false);
700 node('.count').innerHTML = count(entry._count, false); 893 node('.count').innerHTML = count(entry._count, false);
701 node('.countVariance').innerHTML 894 node('.countVariance').innerHTML
702 = percent(entry.timeVariancePercent, false); 895 = percent(entry.timeVariancePercent, false);
703 node('.timeImpact').innerHTML 896 node('.timeImpact').innerHTML
704 = ms(entry.getTimeImpact(false), false); 897 = ms(entry.getTimeImpact(false), false);
705 node('.timePercentImpact').innerHTML 898 node('.timePercentImpact').innerHTML
706 = percent(entry.getTimeImpactVariancePercent(false), false); 899 = percent(entry.getTimeImpactVariancePercent(false), false);
707 } 900 }
708 } 901 }
709 902 </script>
710 // ========================================================================= == 903 <script type="text/javascript">
904 "use strict"
905 // =========================================================================
711 // Helpers 906 // Helpers
712 function $(id) { 907 function $(id) {
713 return document.getElementById(id) 908 return document.getElementById(id)
714 } 909 }
715 910
716 function removeAllChildren(node) { 911 function removeAllChildren(node) {
717 while (node.firstChild) { 912 while (node.firstChild) {
718 node.removeChild(node.firstChild); 913 node.removeChild(node.firstChild);
719 } 914 }
720 } 915 }
721 916
722 function selectOption(select, match) { 917 function selectOption(select, match) {
723 var options = select.options; 918 var options = select.options;
724 for (var i = 0; i < options.length; i++) { 919 for (var i = 0; i < options.length; i++) {
725 if (match(i, options[i])) { 920 if (match(i, options[i])) {
726 select.selectedIndex = i; 921 select.selectedIndex = i;
727 return; 922 return;
728 } 923 }
729 } 924 }
730 } 925 }
731 926
927 function addCodeSearchButton(entry, node) {
928 if (entry.isGroup) return;
929 var button = document.createElement("div");
930 button.innerHTML = '?'
931 button.className = "codeSearch"
932 button.addEventListener('click', handleCodeSearch);
933 node.appendChild(button);
934 return node;
935 }
936
732 function td(tr, content, className) { 937 function td(tr, content, className) {
733 var td = document.createElement("td"); 938 var td = document.createElement("td");
734 td.innerHTML = content; 939 td.innerHTML = content;
735 td.className = className 940 td.className = className
736 tr.appendChild(td); 941 tr.appendChild(td);
737 return td 942 return td
738 } 943 }
739 944
740 function nodeIndex(node) { 945 function nodeIndex(node) {
741 var children = node.parentNode.childNodes, 946 var children = node.parentNode.childNodes,
(...skipping 16 matching lines...) Expand all
758 if (index == -1) { 963 if (index == -1) {
759 if (toggleState === false) return; 964 if (toggleState === false) return;
760 node.className += ' ' + cssClass; 965 node.className += ' ' + cssClass;
761 return; 966 return;
762 } 967 }
763 if (toggleState === true) return; 968 if (toggleState === true) return;
764 classes.splice(index, 1); 969 classes.splice(index, 1);
765 node.className = classes.join(' '); 970 node.className = classes.join(' ');
766 } 971 }
767 972
973 function NameComparator(a, b) {
974 if (a.name > b.name) return 1;
975 if (a.name < b.name) return -1;
976 return 0
977 }
978
768 function diffSign(value, digits, unit, showDiff) { 979 function diffSign(value, digits, unit, showDiff) {
769 if (showDiff === false || baselineVersion == undefined) { 980 if (showDiff === false || baselineVersion == undefined) {
981 if (value === undefined) return '';
770 return value.toFixed(digits) + unit; 982 return value.toFixed(digits) + unit;
771 } 983 }
772 return (value >= 0 ? '+' : '') + value.toFixed(digits) + unit + 'Δ'; 984 return (value >= 0 ? '+' : '') + value.toFixed(digits) + unit + 'Δ';
773 } 985 }
774 986
775 function ms(value, showDiff) { 987 function ms(value, showDiff) {
776 return diffSign(value, 1, 'ms', showDiff); 988 return diffSign(value, 1, 'ms', showDiff);
777 } 989 }
778 990
779 function count(value, showDiff) { 991 function count(value, showDiff) {
780 return diffSign(value, 0, '#', showDiff); 992 return diffSign(value, 0, '#', showDiff);
781 } 993 }
782 994
783 function percent(value, showDiff) { 995 function percent(value, showDiff) {
784 return diffSign(value, 1, '%', showDiff); 996 return diffSign(value, 1, '%', showDiff);
785 } 997 }
786 998
999 </script>
1000 <script type="text/javascript">
1001 "use strict"
787 // ========================================================================= 1002 // =========================================================================
788 // EventHandlers 1003 // EventHandlers
789 function handleBodyLoad() { 1004 function handleBodyLoad() {
790 $('uploadInput').focus(); 1005 $('uploadInput').focus();
791 } 1006 }
792 1007
793 function handleLoadFile() { 1008 function handleLoadFile() {
794 var files = document.getElementById("uploadInput").files; 1009 var files = document.getElementById("uploadInput").files;
795 var file = files[0]; 1010 var file = files[0];
796 var reader = new FileReader(); 1011 var reader = new FileReader();
797 1012
798 reader.onload = function(evt) { 1013 reader.onload = function(evt) {
1014 pages = new Pages();
799 versions = Versions.fromJSON(JSON.parse(this.result)); 1015 versions = Versions.fromJSON(JSON.parse(this.result));
800 initialize() 1016 initialize()
801 showPage(versions.versions[0].pages[0]); 1017 showPage(versions.versions[0].pages[0]);
802 } 1018 }
803 reader.readAsText(file); 1019 reader.readAsText(file);
804 } 1020 }
805 1021
806 function handleToggleGroup(event) { 1022 function handleToggleGroup(event) {
807 var group = event.target.parentNode.parentNode.entry; 1023 var group = event.target.parentNode.parentNode.entry;
808 toggleGroup(selectedPage.get(group.name)); 1024 toggleGroup(selectedPage.get(group.name));
(...skipping 11 matching lines...) Expand all
820 1036
821 function handleSelectVersion(select, event) { 1037 function handleSelectVersion(select, event) {
822 var option = select.options[select.selectedIndex]; 1038 var option = select.options[select.selectedIndex];
823 var version = option.version; 1039 var version = option.version;
824 if (select.id == "selectVersion_0") { 1040 if (select.id == "selectVersion_0") {
825 var page = version.get(selectedPage.name); 1041 var page = version.get(selectedPage.name);
826 showPage(page); 1042 showPage(page);
827 } else { 1043 } else {
828 var columnIndex = select.id.split('_')[1]; 1044 var columnIndex = select.id.split('_')[1];
829 var pageSelect = $('select_' + columnIndex); 1045 var pageSelect = $('select_' + columnIndex);
830 var page = pageSelect.options[select.selectedIndex].page; 1046 var page = pageSelect.options[pageSelect.selectedIndex].page;
831 page = version.get(page.name); 1047 page = version.get(page.name);
832 showPageInColumn(page, columnIndex); 1048 showPageInColumn(page, columnIndex);
833 } 1049 }
834 } 1050 }
835 1051
836 function handleSelectDetailRow(table, event) { 1052 function handleSelectDetailRow(table, event) {
837 if (event.target.tagName != 'TD') return; 1053 if (event.target.tagName != 'TD') return;
838 var tr = event.target.parentNode; 1054 var tr = event.target.parentNode;
839 if (tr.tagName != 'TR') return; 1055 if (tr.tagName != 'TR') return;
840 if (tr.entry === undefined) return; 1056 if (tr.entry === undefined) return;
841 selectEntry(tr.entry, true); 1057 selectEntry(tr.entry, true);
842 } 1058 }
843 1059
844 function handleSelectRow(table, event, fromDetail) { 1060 function handleSelectRow(table, event, fromDetail) {
845 if (event.target.tagName != 'TD') return; 1061 if (event.target.tagName != 'TD') return;
846 var tr = event.target.parentNode; 1062 var tr = event.target.parentNode;
847 if (tr.tagName != 'TR') return; 1063 if (tr.tagName != 'TR') return;
848 if (tr.entry === undefined) return; 1064 if (tr.entry === undefined) return;
849 selectEntry(tr.entry, false); 1065 selectEntry(tr.entry, false);
850 } 1066 }
851 1067
852 function handleSelectBaseline(select, event) { 1068 function handleSelectBaseline(select, event) {
853 var option = select.options[select.selectedIndex]; 1069 var option = select.options[select.selectedIndex];
854 baselineVersion = option.version 1070 baselineVersion = option.version;
1071 var showingDiff = baselineVersion !== undefined;
1072 var body = $('body');
1073 toggleCssClass(body, 'diff', showingDiff);
1074 toggleCssClass(body, 'noDiff', !showingDiff);
855 showPage(selectedPage); 1075 showPage(selectedPage);
856 if (selectedEntry === undefined) return; 1076 if (selectedEntry === undefined) return;
857 selectEntry(selectedEntry, true); 1077 selectEntry(selectedEntry, true);
858 } 1078 }
859 1079
1080 function findEntry(event) {
1081 var target = event.target;
1082 while (target.entry === undefined) {
1083 target = target.parentNode;
1084 if (!target) return undefined;
1085 }
1086 return target.entry;
1087 }
1088
860 function handleUpdatePopover(event) { 1089 function handleUpdatePopover(event) {
861 var popover = $('popover'); 1090 var popover = $('popover');
862 popover.style.left = event.pageX + 'px'; 1091 popover.style.left = event.pageX + 'px';
863 popover.style.top = event.pageY + 'px'; 1092 popover.style.top = event.pageY + 'px';
1093 popover.style.display = 'none';
864 popover.style.display = event.shiftKey ? 'block' : 'none'; 1094 popover.style.display = event.shiftKey ? 'block' : 'none';
865 var target = event.target; 1095 var entry = findEntry(event);
866 while (target.entry === undefined) { 1096 if (entry === undefined) return;
867 target = target.parentNode; 1097 showPopover(entry);
868 if (!target) return;
869 }
870 showPopover(target.entry);
871 } 1098 }
872 1099
873 function handleToggleVersionEnable(event) { 1100 function handleToggleVersionEnable(event) {
874 var version = this.version; 1101 var item = this.item ;
875 if (version === undefined) return; 1102 if (item === undefined) return;
876 version.enabled = this.checked; 1103 item .enabled = this.checked;
877 initialize(); 1104 initialize();
878 var page = selectedPage; 1105 var page = selectedPage;
879 if (page === undefined || !page.version.enabled) { 1106 if (page === undefined || !page.version.enabled) {
880 page = versions.getEnabledPage(page.name); 1107 page = versions.getEnabledPage(page.name);
881 } 1108 }
882 showPage(page); 1109 showPage(page);
883 } 1110 }
884 1111
885 // ========================================================================= == 1112 function handleToggleContentVisibility(event) {
1113 var content = event.target.contentNode;
1114 toggleCssClass(content, 'hidden');
1115 }
886 1116
1117 function handleCodeSearch(event) {
1118 var entry = findEntry(event);
1119 if (entry === undefined) return;
1120 var url = "https://cs.chromium.org/search/?sq=package:chromium&type=cs&q=" ;
1121 name = entry.name;
1122 if (name.startsWith("API_")) {
1123 name = name.substring(4);
1124 }
1125 url += encodeURIComponent(name) + "+file:src/v8/src";
1126 window.open(url,'_blank');
1127 }
1128 </script>
1129 <script type="text/javascript">
1130 "use strict"
1131 // =========================================================================
887 class Versions { 1132 class Versions {
888 constructor() { 1133 constructor() {
889 this.versions = []; 1134 this.versions = [];
890 } 1135 }
891 add(version) { 1136 add(version) {
892 this.versions.push(version) 1137 this.versions.push(version)
893 } 1138 }
894 pageVersions(name) { 1139 getPageVersions(page) {
895 var result = []; 1140 var result = [];
896 this.versions.forEach((version) => { 1141 this.versions.forEach((version) => {
897 if (!version.enabled) return; 1142 if (!version.enabled) return;
898 var page = version.get(name); 1143 var versionPage = version.get(page.name);
899 if (page !== undefined) result.push(page); 1144 if (versionPage !== undefined) result.push(versionPage);
900 }); 1145 });
901 return result; 1146 return result;
902 } 1147 }
903 get length() { 1148 get length() {
904 return this.versions.length 1149 return this.versions.length
905 } 1150 }
906 get(index) { 1151 get(index) {
907 return this.versions[index] 1152 return this.versions[index]
908 }; 1153 };
909 forEach(f) { 1154 forEach(f) {
910 this.versions.forEach(f); 1155 this.versions.forEach(f);
911 } 1156 }
912 sort() { 1157 sort() {
913 this.versions.sort((a, b) => { 1158 this.versions.sort(NameComparator);
914 if (a.name > b.name) return 1;
915 if (a.name < b.name) return -1;
916 return 0
917 })
918 } 1159 }
919 getEnabledPage(name) { 1160 getEnabledPage(name) {
920 for (var i = 0; i < this.versions.length; i++) { 1161 for (var i = 0; i < this.versions.length; i++) {
921 var version = this.versions[i]; 1162 var version = this.versions[i];
922 if (!version.enabled) continue; 1163 if (!version.enabled) continue;
923 var page = version.get(name); 1164 var page = version.get(name);
924 if (page !== undefined) return page; 1165 if (page !== undefined) return page;
925 } 1166 }
926 } 1167 }
927 } 1168 }
928 Versions.fromJSON = function(json) { 1169 Versions.fromJSON = function(json) {
929 var versions = new Versions(); 1170 var versions = new Versions();
930 for (var version in json) { 1171 for (var version in json) {
931 versions.add(Version.fromJSON(version, json[version])); 1172 versions.add(Version.fromJSON(version, json[version]));
932 } 1173 }
933 versions.sort(); 1174 versions.sort();
934 return versions; 1175 return versions;
935 } 1176 }
(...skipping 21 matching lines...) Expand all
957 get length() { 1198 get length() {
958 return this.versions.length 1199 return this.versions.length
959 } 1200 }
960 getEntry(entry) { 1201 getEntry(entry) {
961 if (entry === undefined) return undefined; 1202 if (entry === undefined) return undefined;
962 var page = this.get(entry.page.name); 1203 var page = this.get(entry.page.name);
963 if (page === undefined) return undefined; 1204 if (page === undefined) return undefined;
964 return page.get(entry.name); 1205 return page.get(entry.name);
965 } 1206 }
966 forEachEntry(fun) { 1207 forEachEntry(fun) {
967 this.pages.forEach((page) => { 1208 this.forEachPage((page) => {
968 page.forEach(fun); 1209 page.forEach(fun);
969 }); 1210 });
970 } 1211 }
1212 forEachPage(fun) {
1213 this.pages.forEach((page) => {
1214 if (!page.enabled) return;
1215 fun(page);
1216 })
1217 }
971 allEntries() { 1218 allEntries() {
972 var map = new Map(); 1219 var map = new Map();
973 this.forEachEntry((group, entry) => { 1220 this.forEachEntry((group, entry) => {
974 if (!map.has(entry.name)) map.set(entry.name, entry); 1221 if (!map.has(entry.name)) map.set(entry.name, entry);
975 }); 1222 });
976 return Array.from(map.values()); 1223 return Array.from(map.values());
977 } 1224 }
978 getTotalValue(name, property) { 1225 getTotalValue(name, property) {
979 if (name === undefined) name = this.pages[0].total.name; 1226 if (name === undefined) name = this.pages[0].total.name;
980 var sum = 0; 1227 var sum = 0;
981 this.pages.forEach((page) => { 1228 this.forEachPage((page) => {
982 var entry = page.get(name); 1229 var entry = page.get(name);
983 if (entry !== undefined) sum += entry[property]; 1230 if (entry !== undefined) sum += entry[property];
984 }); 1231 });
985 return sum; 1232 return sum;
986 } 1233 }
987 getTotalTime(name, showDiff) { 1234 getTotalTime(name, showDiff) {
988 return this.getTotalValue(name, showDiff === false ? '_time' : 'time'); 1235 return this.getTotalValue(name, showDiff === false ? '_time' : 'time');
989 } 1236 }
990 getTotalTimePercent(name, showDiff) { 1237 getTotalTimePercent(name, showDiff) {
991 if (baselineVersion === undefined) { 1238 if (baselineVersion === undefined || showDiff === false) {
992 // Return the overall average percent of the given entry name. 1239 // Return the overall average percent of the given entry name.
993 return this.getTotalValue(name, 'time') / 1240 return this.getTotalValue(name, 'time') /
994 this.getTotalTime('Group-Total') * 100; 1241 this.getTotalTime('Group-Total') * 100;
995 } 1242 }
996 // Otherwise return the difference to the sum of the baseline version. 1243 // Otherwise return the difference to the sum of the baseline version.
997 var baselineValue = baselineVersion.getTotalTime(name, false); 1244 var baselineValue = baselineVersion.getTotalTime(name, false);
998 return this.getTotalValue(name, '_time') / baselineValue * 100; 1245 var total = this.getTotalValue(name, '_time');
1246 return (total / baselineValue - 1) * 100;
999 } 1247 }
1000 getTotalTimeVariance(name, showDiff) { 1248 getTotalTimeVariance(name, showDiff) {
1001 // Calculate the overall error for a given entry name 1249 // Calculate the overall error for a given entry name
1002 var sum = 0; 1250 var sum = 0;
1003 this.pages.forEach((page) => { 1251 this.forEachPage((page) => {
1004 var entry = page.get(name); 1252 var entry = page.get(name);
1005 if (entry === undefined) return; 1253 if (entry === undefined) return;
1006 sum += entry.timeVariance * entry.timeVariance; 1254 sum += entry.timeVariance * entry.timeVariance;
1007 }); 1255 });
1008 return Math.sqrt(sum); 1256 return Math.sqrt(sum);
1009 } 1257 }
1010 getTotalTimeVariancePercent(name, showDiff) { 1258 getTotalTimeVariancePercent(name, showDiff) {
1011 return this.getTotalTimeVariance(name, showDiff) / 1259 return this.getTotalTimeVariance(name, showDiff) /
1012 this.getTotalTime(name, showDiff) * 100; 1260 this.getTotalTime(name, showDiff) * 100;
1013 } 1261 }
1014 getTotalCount(name, showDiff) { 1262 getTotalCount(name, showDiff) {
1015 return this.getTotalValue(name, showDiff === false ? '_count' : 'count') ; 1263 return this.getTotalValue(name, showDiff === false ? '_count' : 'count') ;
1016 } 1264 }
1265 getAverageTimeImpact(name, showDiff) {
1266 return this.getTotalTime(name, showDiff) / this.pages.length;
1267 }
1017 getPagesByPercentImpact(name) { 1268 getPagesByPercentImpact(name) {
1018 var sortedPages = 1269 var sortedPages =
1019 this.pages.filter((each) => { 1270 this.pages.filter((each) => {
1020 return each.get(name) !== undefined 1271 return each.get(name) !== undefined
1021 }); 1272 });
1022 sortedPages.sort((a, b) => { 1273 sortedPages.sort((a, b) => {
1023 return b.get(name).timePercent - a.get(name).timePercent; 1274 return b.get(name).timePercent - a.get(name).timePercent;
1024 }); 1275 });
1025 return sortedPages; 1276 return sortedPages;
1026 } 1277 }
1027 sort() { 1278 sort() {
1028 this.pages.sort((a, b) => { 1279 this.pages.sort(NameComparator)
1029 if (a.name > b.name) return 1;
1030 if (a.name < b.name) return -1;
1031 return 0
1032 })
1033 } 1280 }
1034 } 1281 }
1035 Version.fromJSON = function(name, data) { 1282 Version.fromJSON = function(name, data) {
1036 var version = new Version(name); 1283 var version = new Version(name);
1037 for (var page in data) { 1284 for (var pageName in data) {
1038 version.add(Page.fromJSON(version, page, data[page])); 1285 version.add(PageVersion.fromJSON(version, pageName, data[pageName]));
1039 } 1286 }
1040 version.sort(); 1287 version.sort();
1041 return version; 1288 return version;
1042 } 1289 }
1043 1290
1291 class Pages extends Map {
1292 get(name) {
1293 if (name.indexOf('www.') == 0) {
1294 name = name.substring(4);
1295 }
1296 if (!this.has(name)) {
1297 this.set(name, new Page(name));
1298 }
1299 return super.get(name);
1300 }
1301 }
1044 1302
1045 class Page { 1303 class Page {
1046 constructor(version, name) { 1304 constructor(name) {
1047 this.name = name; 1305 this.name = name;
1048 this.total = new GroupedEntry('Total', /.*Total.*/); 1306 this.enabled = true;
1049 this.unclassified = new UnclassifiedEntry(this) 1307 this.versions = [];
1308 }
1309 add(page) {
1310 this.versions.push(page);
1311 }
1312 }
1313
1314 class PageVersion {
1315 constructor(version, page) {
1316 this.page = page;
1317 this.page.add(this);
1318 this.total = new GroupedEntry('Total', /.*Total.*/, '#BBB');
1319 this.total.isTotal = true;
1320 this.unclassified = new UnclassifiedEntry(this, "#000")
1050 this.groups = [ 1321 this.groups = [
1051 this.total, 1322 this.total,
1052 new GroupedEntry('IC', /.*IC.*/), 1323 new GroupedEntry('IC', /.*IC.*/, "#3366CC"),
1053 new GroupedEntry('Optimize', 1324 new GroupedEntry('Optimize',
1054 /StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/), 1325 /StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/, "#DC3912"),
1055 new GroupedEntry('Compile', /.*Compile.*|Parse.*/), 1326 new GroupedEntry('Compile', /.*Compile.*/, "#FFAA00"),
1056 new GroupedEntry('Callback', /.*Callback$/), 1327 new GroupedEntry('Parse', /.*Parse.*/, "#FF6600"),
1057 new GroupedEntry('API', /.*API.*/), 1328 new GroupedEntry('Callback', /.*Callback$/, "#109618"),
1058 new GroupedEntry('GC', /GC|AllocateInTargetSpace/), 1329 new GroupedEntry('API', /.*API.*/, "#990099"),
1059 new GroupedEntry('JavaScript', /JS_Execution/), 1330 new GroupedEntry('GC', /GC|AllocateInTargetSpace/, "#0099C6"),
1331 new GroupedEntry('JavaScript', /JS_Execution/, "#DD4477"),
1332 new GroupedEntry('Runtime', /.*/, "#88BB00"),
1060 this.unclassified 1333 this.unclassified
1061 ]; 1334 ];
1062 this.entryDict = new Map(); 1335 this.entryDict = new Map();
1063 this.groups.forEach((entry) => { 1336 this.groups.forEach((entry) => {
1064 entry.page = this; 1337 entry.page = this;
1065 this.entryDict.set(entry.name, entry); 1338 this.entryDict.set(entry.name, entry);
1066 }); 1339 });
1067 this.version = version; 1340 this.version = version;
1068 } 1341 }
1069 add(entry) { 1342 add(entry) {
1070 entry.page = this; 1343 entry.page = this;
1071 this.entryDict.set(entry.name, entry); 1344 this.entryDict.set(entry.name, entry);
1072 var added = false; 1345 var added = false;
1073 this.groups.forEach((group) => { 1346 this.groups.forEach((group) => {
1074 if (!added) added = group.add(entry); 1347 if (!added) added = group.add(entry);
1075 }); 1348 });
1076 if (added) return; 1349 if (added) return;
1077 this.unclassified.push(entry); 1350 this.unclassified.push(entry);
1078 } 1351 }
1079 get(name) { 1352 get(name) {
1080 return this.entryDict.get(name) 1353 return this.entryDict.get(name)
1081 } 1354 }
1082 getEntry(entry) { 1355 getEntry(entry) {
1083 if (entry === undefined) return undefined; 1356 if (entry === undefined) return undefined;
1084 return this.get(entry.name); 1357 return this.get(entry.name);
1085 } 1358 }
1086 get length() { 1359 get length() {
1087 return this.versions.length 1360 return this.versions.length
1088 } 1361 }
1362 get name() { return this.page.name }
1363 get enabled() { return this.page.enabled }
1089 forEachSorted(referencePage, func) { 1364 forEachSorted(referencePage, func) {
1090 // Iterate over all the entries in the order they appear on the referenc e page. 1365 // Iterate over all the entries in the order they appear on the
1366 // reference page.
1091 referencePage.forEach((parent, referenceEntry) => { 1367 referencePage.forEach((parent, referenceEntry) => {
1092 var entry; 1368 var entry;
1093 if (parent) parent = this.entryDict.get(parent.name); 1369 if (parent) parent = this.entryDict.get(parent.name);
1094 if (referenceEntry) entry = this.entryDict.get(referenceEntry.name); 1370 if (referenceEntry) entry = this.entryDict.get(referenceEntry.name);
1095 func(parent, entry, referenceEntry); 1371 func(parent, entry, referenceEntry);
1096 }); 1372 });
1097 } 1373 }
1098 forEach(fun) { 1374 forEach(fun) {
1099 this.forEachGroup((group) => { 1375 this.forEachGroup((group) => {
1100 fun(undefined, group); 1376 fun(undefined, group);
1101 group.forEach((entry) => { 1377 group.forEach((entry) => {
1102 fun(group, entry) 1378 fun(group, entry)
1103 }); 1379 });
1104 }); 1380 });
1105 } 1381 }
1106 forEachGroup(fun) { 1382 forEachGroup(fun) {
1107 this.groups.forEach(fun) 1383 this.groups.forEach(fun)
1108 } 1384 }
1109 sort() { 1385 sort() {
1110 this.groups.sort((a, b) => { 1386 this.groups.sort((a, b) => {
1111 return b.time - a.time; 1387 return b.time - a.time;
1112 }); 1388 });
1113 this.groups.forEach((group) => { 1389 this.groups.forEach((group) => {
1114 group.sort() 1390 group.sort()
1115 }); 1391 });
1116 } 1392 }
1393 distanceFromTotalPercent() {
1394 var sum = 0;
1395 this.groups.forEach(group => {
1396 if (group == this.total) return;
1397 var value = group.getTimePercentImpact() -
1398 this.getEntry(group).timePercent;
1399 sum += value * value;
1400 });
1401 return sum;
1402 }
1117 } 1403 }
1118 Page.fromJSON = function(version, name, data) { 1404 PageVersion.fromJSON = function(version, name, data) {
1119 if (name.indexOf('www.') == 0) { 1405 var page = new PageVersion(version, pages.get(name));
1120 name = name.substring(4);
1121 }
1122 var page = new Page(version, name);
1123 for (var i = 0; i < data.length; i++) { 1406 for (var i = 0; i < data.length; i++) {
1124 page.add(Entry.fromJSON(i, data[data.length - i - 1])); 1407 page.add(Entry.fromJSON(i, data[data.length - i - 1]));
1125 } 1408 }
1126 page.sort(); 1409 page.sort();
1127 return page 1410 return page
1128 } 1411 }
1129 1412
1130 1413
1131 class Entry { 1414 class Entry {
1132 constructor(position, name, time, timeVariance, timeVariancePercent, 1415 constructor(position, name, time, timeVariance, timeVariancePercent,
1133 count, 1416 count,
1134 countVariance, countVariancePercent) { 1417 countVariance, countVariancePercent) {
1135 this.position = position; 1418 this.position = position;
1136 this.name = name; 1419 this.name = name;
1137 this._time = time; 1420 this._time = time;
1138 this._timeVariance = timeVariance; 1421 this._timeVariance = timeVariance;
1139 this._timeVariancePercent = timeVariancePercent; 1422 this._timeVariancePercent = timeVariancePercent;
1140 this._count = count; 1423 this._count = count;
1141 this.countVariance = countVariance; 1424 this.countVariance = countVariance;
1142 this.countVariancePercent = countVariancePercent; 1425 this.countVariancePercent = countVariancePercent;
1143 this.page = undefined; 1426 this.page = undefined;
1144 this.parent = undefined; 1427 this.parent = undefined;
1428 this.isTotal = false;
1145 } 1429 }
1146 getCompareWithBaseline(value, property) { 1430 getCompareWithBaseline(value, property) {
1147 if (baselineVersion == undefined) return value; 1431 if (baselineVersion == undefined) return value;
1148 var baselineEntry = baselineVersion.getEntry(this); 1432 var baselineEntry = baselineVersion.getEntry(this);
1149 if (!baselineEntry) return value; 1433 if (!baselineEntry) return value;
1150 if (baselineVersion === this.page.version) return value; 1434 if (baselineVersion === this.page.version) return value;
1151 return value - baselineEntry[property]; 1435 return value - baselineEntry[property];
1152 } 1436 }
1153 cssClass() { 1437 cssClass() {
1154 return '' 1438 return ''
1155 } 1439 }
1156 get time() { 1440 get time() {
1157 return this.getCompareWithBaseline(this._time, '_time'); 1441 return this.getCompareWithBaseline(this._time, '_time');
1158 } 1442 }
1159 get count() { 1443 get count() {
1160 return this.getCompareWithBaseline(this._count, '_count'); 1444 return this.getCompareWithBaseline(this._count, '_count');
1161 } 1445 }
1162 get timePercent() { 1446 get timePercent() {
1163 var value = this._time / this.page.total._time * 100; 1447 var value = this._time / this.page.total._time * 100;
1164 if (baselineVersion == undefined) return value; 1448 if (baselineVersion == undefined) return value;
1165 var baselineEntry = baselineVersion.getEntry(this); 1449 var baselineEntry = baselineVersion.getEntry(this);
1166 if (!baselineEntry) return value; 1450 if (!baselineEntry) return value;
1167 if (baselineVersion === this.page.version) return value; 1451 if (baselineVersion === this.page.version) return value;
1168 return (this._time - baselineEntry._time) / this.page.total._time * 1452 return (this._time - baselineEntry._time) / this.page.total._time *
1169 100; 1453 100;
1170 } 1454 }
1455 get timePercentPerEntry() {
1456 var value = this._time / this.page.total._time * 100;
1457 if (baselineVersion == undefined) return value;
1458 var baselineEntry = baselineVersion.getEntry(this);
1459 if (!baselineEntry) return value;
1460 if (baselineVersion === this.page.version) return value;
1461 return (this._time / baselineEntry._time - 1) * 100;
1462 }
1171 get timePercentVariancePercent() { 1463 get timePercentVariancePercent() {
1172 // Get the absolute values for the percentages 1464 // Get the absolute values for the percentages
1173 return this.timeVariance / this.page.total._time * 100; 1465 return this.timeVariance / this.page.total._time * 100;
1174 } 1466 }
1175 getTimeImpact(showDiff) { 1467 getTimeImpact(showDiff) {
1176 return this.page.version.getTotalTime(this.name, showDiff); 1468 return this.page.version.getTotalTime(this.name, showDiff);
1177 } 1469 }
1178 getTimeImpactVariancePercent(showDiff) { 1470 getTimeImpactVariancePercent(showDiff) {
1179 return this.page.version.getTotalTimeVariancePercent(this.name, showDiff ); 1471 return this.page.version.getTotalTimeVariancePercent(this.name, showDiff );
1180 } 1472 }
1181 getTimePercentImpact(showDiff) { 1473 getTimePercentImpact(showDiff) {
1182 return this.page.version.getTotalTimePercent(this.name, showDiff); 1474 return this.page.version.getTotalTimePercent(this.name, showDiff);
1183 } 1475 }
1184 getCountImpact(showDiff) { 1476 getCountImpact(showDiff) {
1185 return this.page.version.getTotalCount(this.name, showDiff); 1477 return this.page.version.getTotalCount(this.name, showDiff);
1186 } 1478 }
1479 getAverageTimeImpact(showDiff) {
1480 return this.page.version.getAverageTimeImpact(this.name, showDiff);
1481 }
1187 getPagesByPercentImpact() { 1482 getPagesByPercentImpact() {
1188 return this.page.version.getPagesByPercentImpact(this.name); 1483 return this.page.version.getPagesByPercentImpact(this.name);
1189 } 1484 }
1190 get isGroup() { 1485 get isGroup() {
1191 return false 1486 return false
1192 } 1487 }
1193 get timeVariance() { 1488 get timeVariance() {
1194 return this._timeVariance 1489 return this._timeVariance
1195 } 1490 }
1196 get timeVariancePercent() { 1491 get timeVariancePercent() {
1197 return this._timeVariancePercent 1492 return this._timeVariancePercent
1198 } 1493 }
1199 } 1494 }
1200 Entry.fromJSON = function(position, data) { 1495 Entry.fromJSON = function(position, data) {
1201 return new Entry(position, ...data); 1496 return new Entry(position, ...data);
1202 } 1497 }
1203 1498
1204 1499
1205 class GroupedEntry extends Entry { 1500 class GroupedEntry extends Entry {
1206 constructor(name, regexp) { 1501 constructor(name, regexp, color) {
1207 super(0, 'Group-' + name, 0, 0, 0, 0, 0, 0); 1502 super(0, 'Group-' + name, 0, 0, 0, 0, 0, 0);
1208 this.regexp = regexp; 1503 this.regexp = regexp;
1504 this.color = color;
1209 this.entries = []; 1505 this.entries = [];
1210 } 1506 }
1211 add(entry) { 1507 add(entry) {
1212 if (!entry.name.match(this.regexp)) return false; 1508 if (!entry.name.match(this.regexp)) return false;
1213 this._time += entry.time; 1509 this._time += entry.time;
1214 this._count += entry.count; 1510 this._count += entry.count;
1215 // TODO: sum up variance 1511 // TODO: sum up variance
1216 this.entries.push(entry); 1512 this.entries.push(entry);
1217 entry.parent = this; 1513 entry.parent = this;
1218 return true; 1514 return true;
1219 } 1515 }
1220 forEach(fun) { 1516 forEach(fun) {
1221 if (baselineVersion === undefined) { 1517 if (baselineVersion === undefined) {
1222 this.entries.forEach(fun); 1518 this.entries.forEach(fun);
1223 return; 1519 return;
1224 } 1520 }
1225 // If we have a baslineVersion to compare against show also all entries from the 1521 // If we have a baslineVersion to compare against show also all entries
1226 // other group. 1522 // from the other group.
1227 var tmpEntries = baselineVersion.getEntry(this) 1523 var tmpEntries = baselineVersion.getEntry(this)
1228 .entries.filter((entry) => { 1524 .entries.filter((entry) => {
1229 return this.page.get(entry.name) == undefined 1525 return this.page.get(entry.name) == undefined
1230 }); 1526 });
1231 1527
1232 // The compared entries are sorted by absolute impact. 1528 // The compared entries are sorted by absolute impact.
1233 tmpEntries = tmpEntries.map((entry) => { 1529 tmpEntries = tmpEntries.map((entry) => {
1234 var tmpEntry = new Entry(0, entry.name, 0, 0, 0, 0, 0, 0); 1530 var tmpEntry = new Entry(0, entry.name, 0, 0, 0, 0, 0, 0);
1235 tmpEntry.page = this.page; 1531 tmpEntry.page = this.page;
1236 return tmpEntry; 1532 return tmpEntry;
(...skipping 27 matching lines...) Expand all
1264 get timeVariancePercent() { 1560 get timeVariancePercent() {
1265 if (this._time == 0) return 0; 1561 if (this._time == 0) return 0;
1266 return this.getVarianceForProperty('time') / this._time * 100 1562 return this.getVarianceForProperty('time') / this._time * 100
1267 } 1563 }
1268 get timeVariance() { 1564 get timeVariance() {
1269 return this.getVarianceForProperty('time') 1565 return this.getVarianceForProperty('time')
1270 } 1566 }
1271 } 1567 }
1272 1568
1273 class UnclassifiedEntry extends GroupedEntry { 1569 class UnclassifiedEntry extends GroupedEntry {
1274 constructor(page) { 1570 constructor(page, color) {
1275 super('Runtime'); 1571 super('Unclassified', undefined, color);
1276 this.page = page; 1572 this.page = page;
1277 this._time = undefined; 1573 this._time = undefined;
1278 this._count = undefined; 1574 this._count = undefined;
1279 } 1575 }
1280 add(entry) { 1576 add(entry) {
1281 this.entries.push(entry); 1577 this.entries.push(entry);
1282 entry.parent = this; 1578 entry.parent = this;
1283 return true; 1579 return true;
1284 } 1580 }
1285 forEachPageGroup(fun) { 1581 forEachPageGroup(fun) {
(...skipping 18 matching lines...) Expand all
1304 this.forEachPageGroup((group) => { 1600 this.forEachPageGroup((group) => {
1305 this._count -= group._count; 1601 this._count -= group._count;
1306 }); 1602 });
1307 } 1603 }
1308 return this.getCompareWithBaseline(this._count, '_count'); 1604 return this.getCompareWithBaseline(this._count, '_count');
1309 } 1605 }
1310 } 1606 }
1311 </script> 1607 </script>
1312 </head> 1608 </head>
1313 1609
1314 <body onmousemove="handleUpdatePopover(event)" onload="handleBodyLoad()"> 1610 <body id="body" onmousemove="handleUpdatePopover(event)" onload="handleBodyLoad( )" class="noDiff">
1315 <h1>Runtime Stats Komparator</h1> 1611 <h1>Runtime Stats Komparator</h1>
1316 1612
1317 <div id="results"> 1613 <div id="results">
1318 <div class="inline"> 1614 <div class="inline">
1319 <h2>Data</h2> 1615 <h2>Data</h2>
1320 <form name="fileForm"> 1616 <form name="fileForm">
1321 <p> 1617 <p>
1322 <input id="uploadInput" type="file" name="files" onchange="handleLoadF ile();" accept=".json"> 1618 <input id="uploadInput" type="file" name="files" onchange="handleLoadF ile();" accept=".json">
1323 </p> 1619 </p>
1324 </form> 1620 </form>
1325 </div> 1621 </div>
1326 1622
1327 <div class="inline hidden"> 1623 <div class="inline hidden">
1328 <h2>Result</h2> 1624 <h2>Result</h2>
1329 <div class="compareSelector inline"> 1625 <div class="compareSelector inline">
1330 Compare against:&nbsp;<select id="baseline" onchange="handleSelectBaseli ne(this, event)"></select><br/> 1626 Compare against:&nbsp;<select id="baseline" onchange="handleSelectBaseli ne(this, event)"></select><br/>
1331 <span style="color: #060">Green</span> the selected version above perfor ms 1627 <span style="color: #060">Green</span> the selected version above perfor ms
1332 better on this measurement. 1628 better on this measurement.
1333 </div> 1629 </div>
1334 <div class="versionSelector inline"> 1630 </div>
1335 Select Versions: 1631
1632 <div id="versionSelector" class="inline toggleContentVisibility">
1633 <h2>Version Selector</h2>
1634 <div class="content hidden">
1336 <ul></ul> 1635 <ul></ul>
1337 </div> 1636 </div>
1338 </div> 1637 </div>
1638
1639 <div id="pageSelector" class="inline toggleContentVisibility">
1640 <h2>Page Selector</h2>
1641 <div class="content hidden">
1642 <ul></ul>
1643 </div>
1644 </div>
1645
1339 <div id="view"> 1646 <div id="view">
1340 </div> 1647 </div>
1341 1648
1342 <div id="detailView" class="hidden"> 1649 <div id="detailView" class="hidden">
1343 <h2></h2> 1650 <div class="versionDetail inline toggleContentVisibility">
1344 <div class="versionDetail inline"> 1651 <h3><span></span></h3>
1345 <h3>Version Comparison for <span></span></h3> 1652 <div class="content">
1346 <table class="versionDetailTable" onclick="handleSelectDetailRow(this, e vent);"> 1653 <table class="versionDetailTable" onclick="handleSelectDetailRow(this, event);">
1347 <thead> 1654 <thead>
1348 <tr> 1655 <tr>
1349 <th class="version">Version&nbsp;</th> 1656 <th class="version">Version&nbsp;</th>
1350 <th class="position">Pos.&nbsp;</th> 1657 <th class="position">Pos.&nbsp;</th>
1351 <th class="value time">Time▴&nbsp;</th> 1658 <th class="value time">Time▴&nbsp;</th>
1352 <th class="value time">Percent&nbsp;</th> 1659 <th class="value time">Percent&nbsp;</th>
1353 <th class="value count">Count&nbsp;</th> 1660 <th class="value count">Count&nbsp;</th>
1354 </tr> 1661 </tr>
1355 </thead> 1662 </thead>
1356 <tbody></tbody> 1663 <tbody></tbody>
1357 </table> 1664 </table>
1665 </div>
1358 </div> 1666 </div>
1359 <div class="pageDetail inline"> 1667 <div class="pageDetail inline toggleContentVisibility">
1360 <h3>Page Comparison for <span></span></h3> 1668 <h3>Page Comparison for <span></span></h3>
1361 <table class="pageDetailTable" onclick="handleSelectDetailRow(this, even t);"> 1669 <div class="content">
1362 <thead> 1670 <table class="pageDetailTable" onclick="handleSelectDetailRow(this, ev ent);">
1363 <tr> 1671 <thead>
1364 <th class="page">Page&nbsp;</th> 1672 <tr>
1365 <th class="position">Pos.&nbsp;</th> 1673 <th class="page">Page&nbsp;</th>
1366 <th class="value time">Time&nbsp;</th> 1674 <th class="value time">Time&nbsp;</th>
1367 <th class="value time">Percent▾&nbsp;</th> 1675 <th class="value time">Percent▾&nbsp;</th>
1368 <th class="value count">Count&nbsp;</th> 1676 <th class="value time hideNoDiff">%/Entry&nbsp;</th>
1369 </tr> 1677 <th class="value count">Count&nbsp;</th>
1370 </thead> 1678 </tr>
1371 <tfoot> 1679 </thead>
1372 <tr> 1680 <tfoot>
1373 <td class="page">Total:</td> 1681 <tr>
1374 <td class="position"></td> 1682 <td class="page">Total:</td>
1375 <td class="value time"></td> 1683 <td class="value time"></td>
1376 <td class="value time"></td> 1684 <td class="value time"></td>
1377 <td class="value count"></td> 1685 <td class="value time hideNoDiff"></td>
1378 </tr> 1686 <td class="value count"></td>
1379 </tfoot> 1687 </tr>
1380 <tbody></tbody> 1688 </tfoot>
1381 </table> 1689 <tbody></tbody>
1690 </table>
1691 </div>
1382 </div> 1692 </div>
1383 <div class="impactView inline"> 1693 <div class="impactView inline toggleContentVisibility">
1384 <h3>Impact list for <span></span></h3> 1694 <h3>Impact list for <span></span></h3>
1385 <table class="pageDetailTable" onclick="handleSelectDetailRow(this, even t);"> 1695 <div class="content">
1386 <thead> 1696 <table class="pageDetailTable" onclick="handleSelectDetailRow(this, ev ent);">
1387 <tr> 1697 <thead>
1388 <th class="page">Name&nbsp;</th> 1698 <tr>
1389 <th class="value time">Time&nbsp;</th> 1699 <th class="page">Name&nbsp;</th>
1390 <th class="value time">Percent▾&nbsp;</th> 1700 <th class="value time">Time&nbsp;</th>
1391 <th class="">Top Pages</th> 1701 <th class="value time">Percent▾&nbsp;</th>
1392 </tr> 1702 <th class="">Top Pages</th>
1393 </thead> 1703 </tr>
1394 <tbody></tbody> 1704 </thead>
1395 </table> 1705 <tbody></tbody>
1706 </table>
1707 </div>
1396 </div> 1708 </div>
1397 </div> 1709 </div>
1398 <div id="pageGraphs" class="hidden"> 1710 <div id="pageVersionGraph" class="graph hidden toggleContentVisibility">
1711 <h3><span></span></h3>
1712 <div class="content"></div>
1713 </div>
1714 <div id="pageGraph" class="graph hidden toggleContentVisibility">
1715 <h3><span></span></h3>
1716 <div class="content"></div>
1717 </div>
1718 <div id="versionGraph" class="graph hidden toggleContentVisibility">
1719 <h3><span></span></h3>
1720 <div class="content"></div>
1399 </div> 1721 </div>
1400 1722
1401 <div id="column" class="column"> 1723 <div id="column" class="column">
1402 <div class="header"> 1724 <div class="header">
1403 <select class="version" onchange="handleSelectVersion(this, event);"></s elect> 1725 <select class="version" onchange="handleSelectVersion(this, event);"></s elect>
1404 <select class="pageVersion" onchange="handleSelectPage(this, event);"></ select> 1726 <select class="pageVersion" onchange="handleSelectPage(this, event);"></ select>
1405 </div> 1727 </div>
1406 <table class="list" onclick="handleSelectRow(this, event);"> 1728 <table class="list" onclick="handleSelectRow(this, event);">
1407 <thead> 1729 <thead>
1408 <tr> 1730 <tr>
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 <td>Time:</td> 1779 <td>Time:</td>
1458 <td class="time"></td><td>±</td><td class="timeVariance"></td> 1780 <td class="time"></td><td>±</td><td class="timeVariance"></td>
1459 <td class="compare time"></td><td class="compare"> ± </td><td class="com pare timeVariance"></td> 1781 <td class="compare time"></td><td class="compare"> ± </td><td class="com pare timeVariance"></td>
1460 </tr> 1782 </tr>
1461 <tr> 1783 <tr>
1462 <td>Percent:</td> 1784 <td>Percent:</td>
1463 <td class="percent"></td><td>±</td><td class="percentVariance"></td> 1785 <td class="percent"></td><td>±</td><td class="percentVariance"></td>
1464 <td class="compare percent"></td><td class="compare"> ± </td><td class=" compare percentVariance"></td> 1786 <td class="compare percent"></td><td class="compare"> ± </td><td class=" compare percentVariance"></td>
1465 </tr> 1787 </tr>
1466 <tr> 1788 <tr>
1789 <td>Percent per Entry:</td>
1790 <td class="percentPerEntry"></td><td colspan=2></td>
1791 <td class="compare percentPerEntry"></td><td colspan=2></td>
1792 </tr>
1793 <tr>
1467 <td>Count:</td> 1794 <td>Count:</td>
1468 <td class="count"></td><td>±</td><td class="countVariance"></td> 1795 <td class="count"></td><td>±</td><td class="countVariance"></td>
1469 <td class="compare count"></td><td class="compare"> ± </td><td class="co mpare countVariance"></td> 1796 <td class="compare count"></td><td class="compare"> ± </td><td class="co mpare countVariance"></td>
1470 </tr> 1797 </tr>
1471 <tr> 1798 <tr>
1472 <td>Overall Impact:</td> 1799 <td>Overall Impact:</td>
1473 <td class="timeImpact"></td><td>±</td><td class="timePercentImpact"></td > 1800 <td class="timeImpact"></td><td>±</td><td class="timePercentImpact"></td >
1474 <td class="compare timeImpact"></td><td class="compare"> ± </td><td clas s="compare timePercentImpact"></td> 1801 <td class="compare timeImpact"></td><td class="compare"> ± </td><td clas s="compare timePercentImpact"></td>
1475 </tr> 1802 </tr>
1476 </table> 1803 </table>
1477 </div> 1804 </div>
1478
1479 </body> 1805 </body>
1480
1481 </html> 1806 </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