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

Side by Side Diff: tools/callstats.html

Issue 2683863004: [RuntimeStats] Show all entries which are in at least one version. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | 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 {
11 font-family: arial; 11 font-family: arial;
12 } 12 }
13 13
rmcilroy 2017/02/08 15:03:36 Sorry my editor stripped trailing whitespace. I ca
Camillo Bruni 2017/02/08 15:13:06 absolutely fine :)
14 table { 14 table {
15 display: table; 15 display: table;
16 border-spacing: 0px; 16 border-spacing: 0px;
17 } 17 }
18 18
19 tr { 19 tr {
20 border-spacing: 0px; 20 border-spacing: 0px;
21 padding: 10px; 21 padding: 10px;
22 } 22 }
23 23
24 td, 24 td,
25 th { 25 th {
26 padding: 3px 10px 3px 5px; 26 padding: 3px 10px 3px 5px;
27 } 27 }
28 28
29 .inline { 29 .inline {
30 display: inline-block; 30 display: inline-block;
31 vertical-align: top; 31 vertical-align: top;
32 } 32 }
33 33
34 h2, 34 h2,
35 h3 { 35 h3 {
36 margin-bottom: 0px; 36 margin-bottom: 0px;
37 } 37 }
38 38
39 .hidden { 39 .hidden {
40 display: none; 40 display: none;
41 } 41 }
42 42
43 .view { 43 .view {
44 display: table; 44 display: table;
45 } 45 }
46 46
47 .column { 47 .column {
48 display: table-cell; 48 display: table-cell;
49 border-right: 1px black dotted; 49 border-right: 1px black dotted;
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;
71 } 71 }
72 72
73 .list tr:nth-child(even) { 73 .list tr:nth-child(even) {
74 background-color: #EFEFEF; 74 background-color: #EFEFEF;
75 } 75 }
76 76
77 .list tr:nth-child(even).selected { 77 .list tr:nth-child(even).selected {
78 background-color: #DDD; 78 background-color: #DDD;
79 } 79 }
80 80
81 .list tr.child { 81 .list tr.child {
82 display: none; 82 display: none;
83 } 83 }
84 84
85 .list tr.child.visible { 85 .list tr.child.visible {
86 display: table-row; 86 display: table-row;
87 } 87 }
88 88
89 .list .child .name { 89 .list .child .name {
90 padding-left: 20px; 90 padding-left: 20px;
91 } 91 }
92 92
93 .list .parent td { 93 .list .parent td {
94 border-top: 1px solid #AAA; 94 border-top: 1px solid #AAA;
95 } 95 }
96 96
97 .list .total { 97 .list .total {
98 font-weight: bold 98 font-weight: bold
99 } 99 }
100 100
101 .list tr.parent { 101 .list tr.parent {
102 background-color: #FFF; 102 background-color: #FFF;
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 { 113 .codeSearch {
114 display: block-inline; 114 display: block-inline;
115 float: right; 115 float: right;
116 border-radius: 5px; 116 border-radius: 5px;
117 background-color: #EEE; 117 background-color: #EEE;
118 width: 1em; 118 width: 1em;
119 text-align: center; 119 text-align: center;
120 } 120 }
121 121
122 .list .position { 122 .list .position {
123 text-align: right; 123 text-align: right;
124 display: none; 124 display: none;
125 } 125 }
126 126
127 .list div.toggle { 127 .list div.toggle {
128 cursor: pointer; 128 cursor: pointer;
129 } 129 }
130 130
131 #column_0 .position { 131 #column_0 .position {
132 display: table-cell; 132 display: table-cell;
133 } 133 }
134 134
135 #column_0 .name { 135 #column_0 .name {
136 display: table-cell; 136 display: table-cell;
137 } 137 }
138 138
139 .list .name { 139 .list .name {
140 display: none; 140 display: none;
141 white-space: nowrap; 141 white-space: nowrap;
142 } 142 }
143 143
144 .value { 144 .value {
145 text-align: right; 145 text-align: right;
146 } 146 }
147 147
148 .selectedVersion { 148 .selectedVersion {
149 font-weight: bold; 149 font-weight: bold;
150 } 150 }
151 151
152 #baseline { 152 #baseline {
153 width: auto; 153 width: auto;
154 } 154 }
155 155
156 .compareSelector { 156 .compareSelector {
157 padding-bottom: 20px; 157 padding-bottom: 20px;
158 } 158 }
159 159
160 .pageDetailTable tbody { 160 .pageDetailTable tbody {
161 cursor: pointer 161 cursor: pointer
162 } 162 }
163 163
164 .pageDetailTable tfoot td { 164 .pageDetailTable tfoot td {
165 border-top: 1px grey solid; 165 border-top: 1px grey solid;
166 } 166 }
167 167
168 #popover { 168 #popover {
169 position: absolute; 169 position: absolute;
170 transform: translateY(-50%) translateX(40px); 170 transform: translateY(-50%) translateX(40px);
171 box-shadow: -2px 10px 44px -10px #000; 171 box-shadow: -2px 10px 44px -10px #000;
172 border-radius: 5px; 172 border-radius: 5px;
173 z-index: 1; 173 z-index: 1;
174 background-color: #FFF; 174 background-color: #FFF;
175 display: none; 175 display: none;
176 white-space: nowrap; 176 white-space: nowrap;
177 } 177 }
178 178
179 #popover table { 179 #popover table {
180 position: relative; 180 position: relative;
181 z-index: 1; 181 z-index: 1;
182 text-align: right; 182 text-align: right;
183 margin: 10px; 183 margin: 10px;
184 } 184 }
185 #popover td { 185 #popover td {
186 padding: 3px 0px 3px 5px; 186 padding: 3px 0px 3px 5px;
187 white-space: nowrap; 187 white-space: nowrap;
188 } 188 }
189 189
190 .popoverArrow { 190 .popoverArrow {
191 background-color: #FFF; 191 background-color: #FFF;
192 position: absolute; 192 position: absolute;
193 width: 30px; 193 width: 30px;
194 height: 30px; 194 height: 30px;
195 transform: translateY(-50%)rotate(45deg); 195 transform: translateY(-50%)rotate(45deg);
196 top: 50%; 196 top: 50%;
197 left: -10px; 197 left: -10px;
198 z-index: 0; 198 z-index: 0;
199 } 199 }
200 200
201 #popover .name { 201 #popover .name {
202 padding: 5px; 202 padding: 5px;
203 font-weight: bold; 203 font-weight: bold;
204 text-align: center; 204 text-align: center;
205 } 205 }
206 206
207 #popover table .compare { 207 #popover table .compare {
208 display: none 208 display: none
209 } 209 }
210 210
211 #popover table.compare .compare { 211 #popover table.compare .compare {
212 display: table-cell; 212 display: table-cell;
213 } 213 }
214 214
215 #popover .compare .time, 215 #popover .compare .time,
216 #popover .compare .version { 216 #popover .compare .version {
217 padding-left: 10px; 217 padding-left: 10px;
218 } 218 }
219 .graph, 219 .graph,
220 .graph .content { 220 .graph .content {
(...skipping 19 matching lines...) Expand all
240 func(this[i]); 240 func(this[i]);
241 } 241 }
242 } 242 }
243 } 243 }
244 244
245 var versions; 245 var versions;
246 var pages; 246 var pages;
247 var selectedPage; 247 var selectedPage;
248 var baselineVersion; 248 var baselineVersion;
249 var selectedEntry; 249 var selectedEntry;
250 250
251 // Marker to programatically replace the defaultData. 251 // Marker to programatically replace the defaultData.
252 var defaultData = /*default-data-start*/undefined/*default-data-end*/; 252 var defaultData = /*default-data-start*/undefined/*default-data-end*/;
253 253
254 function initialize() { 254 function initialize() {
255 // Initialize the stats table and toggle lists. 255 // Initialize the stats table and toggle lists.
256 var original = $("column"); 256 var original = $("column");
257 var view = document.createElement('div'); 257 var view = document.createElement('div');
258 view.id = 'view'; 258 view.id = 'view';
259 var i = 0; 259 var i = 0;
260 versions.forEach((version) => { 260 versions.forEach((version) => {
(...skipping 27 matching lines...) Expand all
288 option.page = page; 288 option.page = page;
289 optgroup.appendChild(option); 289 optgroup.appendChild(option);
290 }); 290 });
291 select.appendChild(optgroup); 291 select.appendChild(optgroup);
292 }); 292 });
293 view.appendChild(column); 293 view.appendChild(column);
294 i++; 294 i++;
295 }); 295 });
296 var oldView = $('view'); 296 var oldView = $('view');
297 oldView.parentNode.replaceChild(view, oldView); 297 oldView.parentNode.replaceChild(view, oldView);
298 298
299 var select = $('baseline'); 299 var select = $('baseline');
300 removeAllChildren(select); 300 removeAllChildren(select);
301 select.appendChild(document.createElement('option')); 301 select.appendChild(document.createElement('option'));
302 versions.forEach((version) => { 302 versions.forEach((version) => {
303 var option = document.createElement("option"); 303 var option = document.createElement("option");
304 option.textContent = version.name; 304 option.textContent = version.name;
305 option.version = version; 305 option.version = version;
306 select.appendChild(option); 306 select.appendChild(option);
307 }); 307 });
308 initializeToggleList(versions.versions, $('versionSelector')); 308 initializeToggleList(versions.versions, $('versionSelector'));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 if (JSON.stringify(window.history.state) === JSON.stringify(state)) return ; 380 if (JSON.stringify(window.history.state) === JSON.stringify(state)) return ;
381 var params = "?"; 381 var params = "?";
382 for (var pairs of Object.entries(state)) { 382 for (var pairs of Object.entries(state)) {
383 params += encodeURIComponent(pairs[0]) + "=" 383 params += encodeURIComponent(pairs[0]) + "="
384 + encodeURIComponent(pairs[1]) + "&"; 384 + encodeURIComponent(pairs[1]) + "&";
385 } 385 }
386 window.history.pushState(state, selection.toString(), params); 386 window.history.pushState(state, selection.toString(), params);
387 } 387 }
388 388
389 function showPage(firstPage) { 389 function showPage(firstPage) {
390 var changeSelectedEntry = selectedEntry !== undefined 390 var changeSelectedEntry = selectedEntry !== undefined
391 && selectedEntry.page === selectedPage; 391 && selectedEntry.page === selectedPage;
392 pushHistoryState(); 392 pushHistoryState();
393 selectedPage = firstPage; 393 selectedPage = firstPage;
394 selectedPage.sort(); 394 selectedPage.sort();
395 showPageInColumn(firstPage, 0); 395 showPageInColumn(firstPage, 0);
396 // Show the other versions of this page in the following columns. 396 // Show the other versions of this page in the following columns.
397 var pageVersions = versions.getPageVersions(firstPage); 397 var pageVersions = versions.getPageVersions(firstPage);
398 var index = 1; 398 var index = 1;
399 pageVersions.forEach((page) => { 399 pageVersions.forEach((page) => {
400 if (page !== firstPage) { 400 if (page !== firstPage) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 var select = $('select_' + columnIndex); 441 var select = $('select_' + columnIndex);
442 // Find the matching option 442 // Find the matching option
443 selectOption(select, (i, option) => { 443 selectOption(select, (i, option) => {
444 return option.page == page 444 return option.page == page
445 }); 445 });
446 var table = column.querySelector("table"); 446 var table = column.querySelector("table");
447 var oldTbody = table.querySelector('tbody'); 447 var oldTbody = table.querySelector('tbody');
448 var tbody = document.createElement('tbody'); 448 var tbody = document.createElement('tbody');
449 var referencePage = selectedPage; 449 var referencePage = selectedPage;
450 page.forEachSorted(selectedPage, (parentEntry, entry, referenceEntry) => { 450 page.forEachSorted(selectedPage, (parentEntry, entry, referenceEntry) => {
451 // Filter out entries that do not exist in the first column for the defa ult
452 // view.
453 if (baselineVersion === undefined && referenceEntry &&
454 referenceEntry.time == 0) {
455 return;
456 }
457 var tr = document.createElement('tr'); 451 var tr = document.createElement('tr');
458 tbody.appendChild(tr); 452 tbody.appendChild(tr);
459 tr.entry = entry; 453 tr.entry = entry;
460 tr.parentEntry = parentEntry; 454 tr.parentEntry = parentEntry;
461 tr.className = parentEntry === undefined ? 'parent' : 'child'; 455 tr.className = parentEntry === undefined ? 'parent' : 'child';
462 // Don't show entries that do not exist on the current page or if we 456 // Don't show entries that do not exist on the current page or if we
463 // compare against the current page 457 // compare against the current page
464 if (entry !== undefined && page.version !== baselineVersion) { 458 if (entry !== undefined && page.version !== baselineVersion) {
465 // If we show a diff, use the baselineVersion as the referenceEntry 459 // If we show a diff, use the baselineVersion as the referenceEntry
466 if (baselineVersion !== undefined) { 460 if (baselineVersion !== undefined) {
467 var baselineEntry = baselineVersion.getEntry(entry); 461 var baselineEntry = baselineVersion.getEntry(entry);
468 if (baselineEntry !== undefined) referenceEntry = baselineEntry 462 if (baselineEntry !== undefined) referenceEntry = baselineEntry
469 } 463 }
470 if (!parentEntry) { 464 if (!parentEntry) {
471 var node = td(tr, '<div class="toggle">►</div>', 'position'); 465 var node = td(tr, '<div class="toggle">►</div>', 'position');
472 node.firstChild.addEventListener('click', handleToggleGroup); 466 node.firstChild.addEventListener('click', handleToggleGroup);
473 } else { 467 } else {
474 td(tr, entry.position == 0 ? '' : entry.position, 'position'); 468 td(tr, entry.position == 0 ? '' : entry.position, 'position');
475 } 469 }
476 addCodeSearchButton(entry, 470 addCodeSearchButton(entry,
477 td(tr, entry.name, 'name ' + entry.cssClass())); 471 td(tr, entry.name, 'name ' + entry.cssClass()));
478 472
479 diffStatus( 473 diffStatus(
480 td(tr, ms(entry.time), 'value time'), 474 td(tr, ms(entry.time), 'value time'),
481 entry.time, referenceEntry.time); 475 entry.time, referenceEntry.time);
482 diffStatus( 476 diffStatus(
483 td(tr, percent(entry.timePercent), 'value time'), 477 td(tr, percent(entry.timePercent), 'value time'),
484 entry.time, referenceEntry.time); 478 entry.time, referenceEntry.time);
485 diffStatus( 479 diffStatus(
486 td(tr, count(entry.count), 'value count'), 480 td(tr, count(entry.count), 'value count'),
487 entry.count, referenceEntry.count); 481 entry.count, referenceEntry.count);
488 } else if (baselineVersion !== undefined && referenceEntry 482 } else if (baselineVersion !== undefined && referenceEntry
489 && page.version !== baselineVersion) { 483 && page.version !== baselineVersion) {
490 // Show comparison of entry that does not exist on the current page. 484 // Show comparison of entry that does not exist on the current page.
491 tr.entry = new Entry(0, referenceEntry.name); 485 tr.entry = new Entry(0, referenceEntry.name);
492 tr.entry.page = page; 486 tr.entry.page = page;
493 td(tr, '-', 'position'); 487 td(tr, '-', 'position');
494 td(tr, referenceEntry.name, 'name'); 488 td(tr, referenceEntry.name, 'name');
495 diffStatus( 489 diffStatus(
496 td(tr, ms(-referenceEntry.time), 'value time'), 490 td(tr, ms(-referenceEntry.time), 'value time'),
497 -referenceEntry.time, 0); 491 -referenceEntry.time, 0);
498 diffStatus( 492 diffStatus(
(...skipping 11 matching lines...) Expand all
510 node.firstChild.addEventListener('click', handleToggleGroup); 504 node.firstChild.addEventListener('click', handleToggleGroup);
511 } else { 505 } else {
512 td(tr, entry.position == 0 ? '' : entry.position, 'position'); 506 td(tr, entry.position == 0 ? '' : entry.position, 'position');
513 } 507 }
514 td(tr, entry.name, 'name'); 508 td(tr, entry.name, 'name');
515 td(tr, ms(entry.time, false), 'value time'); 509 td(tr, ms(entry.time, false), 'value time');
516 td(tr, percent(entry.timePercent, false), 'value time'); 510 td(tr, percent(entry.timePercent, false), 'value time');
517 td(tr, count(entry.count, false), 'value count'); 511 td(tr, count(entry.count, false), 'value count');
518 } else { 512 } else {
519 td(tr, '-', 'position'); 513 td(tr, '-', 'position');
520 td(tr, '-', 'name'); 514 td(tr, referenceEntry.name, 'name');
521 td(tr, '-', 'value time'); 515 td(tr, '-', 'value time');
522 td(tr, '-', 'value time'); 516 td(tr, '-', 'value time');
523 td(tr, '-', 'value count'); 517 td(tr, '-', 'value count');
524 } 518 }
525 } 519 }
526 }); 520 });
527 table.replaceChild(tbody, oldTbody); 521 table.replaceChild(tbody, oldTbody);
528 var versionSelect = column.querySelector('select.version'); 522 var versionSelect = column.querySelector('select.version');
529 selectOption(versionSelect, (index, option) => { 523 selectOption(versionSelect, (index, option) => {
530 return option.version == page.version 524 return option.version == page.version
531 }); 525 });
532 } 526 }
533 527
534 function showEntry(entry) { 528 function showEntry(entry) {
535 selectedEntry = entry; 529 selectedEntry = entry;
536 selectEntry(entry, true); 530 selectEntry(entry, true);
537 } 531 }
538 532
539 function selectEntry(entry, updateSelectedPage) { 533 function selectEntry(entry, updateSelectedPage) {
540 if (updateSelectedPage) { 534 if (updateSelectedPage) {
541 entry = selectedPage.version.getEntry(entry); 535 entry = selectedPage.version.getEntry(entry);
542 } 536 }
543 var rowIndex = 0; 537 var rowIndex = 0;
544 var needsPageSwitch = updateSelectedPage && entry.page != selectedPage; 538 var needsPageSwitch = updateSelectedPage && entry.page != selectedPage;
545 // If clicked in the detail row change the first column to that page. 539 // If clicked in the detail row change the first column to that page.
546 if (needsPageSwitch) showPage(entry.page); 540 if (needsPageSwitch) showPage(entry.page);
547 var childNodes = $('column_0').querySelector('.list tbody').childNodes; 541 var childNodes = $('column_0').querySelector('.list tbody').childNodes;
548 for (var i = 0; i < childNodes.length; i++) { 542 for (var i = 0; i < childNodes.length; i++) {
549 if (childNodes[i].entry.name == entry.name) { 543 if (childNodes[i].entry !== undefined &&
544 childNodes[i].entry.name == entry.name) {
550 rowIndex = i; 545 rowIndex = i;
551 break; 546 break;
552 } 547 }
553 } 548 }
554 var firstEntry = childNodes[rowIndex].entry; 549 var firstEntry = childNodes[rowIndex].entry;
555 if (rowIndex) { 550 if (rowIndex) {
556 if (firstEntry.parent) showGroup(firstEntry.parent); 551 if (firstEntry.parent) showGroup(firstEntry.parent);
557 } 552 }
558 // Deselect all 553 // Deselect all
559 $('view').querySelectorAll('.list tbody tr').forEach((tr) => { 554 $('view').querySelectorAll('.list tbody tr').forEach((tr) => {
(...skipping 13 matching lines...) Expand all
573 showEntryDetail(entry); 568 showEntryDetail(entry);
574 } 569 }
575 570
576 function showEntryDetail(entry) { 571 function showEntryDetail(entry) {
577 showVersionDetails(entry); 572 showVersionDetails(entry);
578 showPageDetails(entry); 573 showPageDetails(entry);
579 showImpactList(entry.page); 574 showImpactList(entry.page);
580 showGraphs(entry.page); 575 showGraphs(entry.page);
581 pushHistoryState(); 576 pushHistoryState();
582 } 577 }
583 578
584 function showVersionDetails(entry) { 579 function showVersionDetails(entry) {
585 var table, tbody, entries; 580 var table, tbody, entries;
586 table = $('detailView').querySelector('.versionDetailTable'); 581 table = $('detailView').querySelector('.versionDetailTable');
587 tbody = document.createElement('tbody'); 582 tbody = document.createElement('tbody');
588 if (entry !== undefined) { 583 if (entry !== undefined) {
589 $('detailView').querySelector('.versionDetail h3 span').textContent = 584 $('detailView').querySelector('.versionDetail h3 span').textContent =
590 entry.name + ' in ' + entry.page.name; 585 entry.name + ' in ' + entry.page.name;
591 entries = versions.getPageVersions(entry.page).map( 586 entries = versions.getPageVersions(entry.page).map(
592 (page) => { 587 (page) => {
593 return page.get(entry.name) 588 return page.get(entry.name)
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 } 667 }
673 var isCompareView = baselineVersion !== undefined; 668 var isCompareView = baselineVersion !== undefined;
674 entries = entries.filter((entry) => { 669 entries = entries.filter((entry) => {
675 if (isCompareView) { 670 if (isCompareView) {
676 var impact = entry.getTimeImpact(); 671 var impact = entry.getTimeImpact();
677 return impact < -1 || 1 < impact 672 return impact < -1 || 1 < impact
678 } 673 }
679 return entry.getTimePercentImpact() > 0.1; 674 return entry.getTimePercentImpact() > 0.1;
680 }); 675 });
681 entries.sort((a, b) => { 676 entries.sort((a, b) => {
682 var cmp = b.getTimePercentImpact() - a.getTimePercentImpact(); 677 var cmp = b.getTimePercentImpact() - a.getTimePercentImpact();
683 if (isCompareView || cmp.toFixed(1) == 0) { 678 if (isCompareView || cmp.toFixed(1) == 0) {
684 return b.getTimeImpact() - a.getTimeImpact(); 679 return b.getTimeImpact() - a.getTimeImpact();
685 } 680 }
686 return cmp 681 return cmp
687 }); 682 });
688 entries.forEach((entry) => { 683 entries.forEach((entry) => {
689 var tr = document.createElement('tr'); 684 var tr = document.createElement('tr');
690 tr.entry = entry; 685 tr.entry = entry;
691 td(tr, entry.name, 'name'); 686 td(tr, entry.name, 'name');
692 td(tr, ms(entry.getTimeImpact()), 'value time'); 687 td(tr, ms(entry.getTimeImpact()), 'value time');
693 var percentImpact = entry.getTimePercentImpact(); 688 var percentImpact = entry.getTimePercentImpact();
694 td(tr, percentImpact > 1000 ? '-' : percent(percentImpact), 'value time' ); 689 td(tr, percentImpact > 1000 ? '-' : percent(percentImpact), 'value time' );
695 var topPages = entry.getPagesByPercentImpact().slice(0, 3) 690 var topPages = entry.getPagesByPercentImpact().slice(0, 3)
696 .map((each) => { 691 .map((each) => {
697 return each.name + ' (' + percent(each.getEntry(entry).timePercent) + 692 return each.name + ' (' + percent(each.getEntry(entry).timePercent) +
698 ')' 693 ')'
699 }); 694 });
700 td(tr, topPages.join(', '), 'name'); 695 td(tr, topPages.join(', '), 'name');
701 tbody.appendChild(tr); 696 tbody.appendChild(tr);
702 }); 697 });
703 table.replaceChild(tbody, table.querySelector('tbody')); 698 table.replaceChild(tbody, table.querySelector('tbody'));
704 } 699 }
705 700
706 function showGraphs(page) { 701 function showGraphs(page) {
707 var groups = page.groups.slice(); 702 var groups = page.groups.slice();
708 // Sort groups by the biggest impact 703 // Sort groups by the biggest impact
709 groups.sort((a, b) => { 704 groups.sort((a, b) => {
710 return b.getTimeImpact() - a.getTimeImpact(); 705 return b.getTimeImpact() - a.getTimeImpact();
711 }); 706 });
712 if (selectedGroup == undefined) { 707 if (selectedGroup == undefined) {
713 selectedGroup = groups[0]; 708 selectedGroup = groups[0];
714 } else { 709 } else {
715 groups = groups.filter(each => each.enabled && each.name != selectedGrou p.name); 710 groups = groups.filter(each => each.enabled && each.name != selectedGrou p.name);
716 groups.unshift(selectedGroup); 711 groups.unshift(selectedGroup);
717 } 712 }
718 showPageGraph(groups, page); 713 showPageGraph(groups, page);
719 showVersionGraph(groups, page); 714 showVersionGraph(groups, page);
720 showPageVersionGraph(groups, page); 715 showPageVersionGraph(groups, page);
721 } 716 }
722 717
723 function getGraphDataTable(groups) { 718 function getGraphDataTable(groups) {
724 var dataTable = new google.visualization.DataTable(); 719 var dataTable = new google.visualization.DataTable();
725 dataTable.addColumn('string', 'Name'); 720 dataTable.addColumn('string', 'Name');
726 groups.forEach(group => { 721 groups.forEach(group => {
727 var column = dataTable.addColumn('number', group.name.substring(6)); 722 var column = dataTable.addColumn('number', group.name.substring(6));
728 dataTable.setColumnProperty(column, 'group', group); 723 dataTable.setColumnProperty(column, 'group', group);
729 }); 724 });
730 return dataTable; 725 return dataTable;
731 } 726 }
732 727
(...skipping 18 matching lines...) Expand all
751 groups.forEach(group => { 746 groups.forEach(group => {
752 var value = group.getTimePercentImpact() - 747 var value = group.getTimePercentImpact() -
753 page.getEntry(group).timePercent; 748 page.getEntry(group).timePercent;
754 sum += value * value; 749 sum += value * value;
755 }); 750 });
756 return sum; 751 return sum;
757 } 752 }
758 if (isDiffView) { 753 if (isDiffView) {
759 pages.sort((a, b) => { 754 pages.sort((a, b) => {
760 return b.getEntry(selectedGroup).time- 755 return b.getEntry(selectedGroup).time-
761 a.getEntry(selectedGroup).time; 756 a.getEntry(selectedGroup).time;
762 }); 757 });
763 } else { 758 } else {
764 pages.sort((a, b) => { 759 pages.sort((a, b) => {
765 return b.getEntry(selectedGroup).timePercent - 760 return b.getEntry(selectedGroup).timePercent -
766 a.getEntry(selectedGroup).timePercent; 761 a.getEntry(selectedGroup).timePercent;
767 }); 762 });
768 } 763 }
769 // Sort by sum of squared distance to the average. 764 // Sort by sum of squared distance to the average.
770 // pages.sort((a, b) => { 765 // pages.sort((a, b) => {
771 // return a.distanceFromTotalPercent() - b.distanceFromTotalPercent(); 766 // return a.distanceFromTotalPercent() - b.distanceFromTotalPercent();
772 // }); 767 // });
773 // Calculate the entries for the pages 768 // Calculate the entries for the pages
774 pages.forEach((page) => { 769 pages.forEach((page) => {
775 row = [page.name]; 770 row = [page.name];
776 groups.forEach((group) => { 771 groups.forEach((group) => {
777 row.push(group.isTotal ? 0 : page.getEntry(group).time); 772 row.push(group.isTotal ? 0 : page.getEntry(group).time);
778 }); 773 });
779 var rowIndex = dataTable.addRow(row); 774 var rowIndex = dataTable.addRow(row);
780 dataTable.setRowProperty(rowIndex, 'page', page); 775 dataTable.setRowProperty(rowIndex, 'page', page);
781 }); 776 });
782 renderGraph('Pages for ' + page.version.name, groups, dataTable, 777 renderGraph('Pages for ' + page.version.name, groups, dataTable,
783 'pageGraph', isDiffView ? true : 'percent'); 778 'pageGraph', isDiffView ? true : 'percent');
784 } 779 }
785 780
786 function showVersionGraph(groups, page) { 781 function showVersionGraph(groups, page) {
787 var dataTable = getGraphDataTable(groups); 782 var dataTable = getGraphDataTable(groups);
788 var row; 783 var row;
789 var vs = versions.versions.filter(version => version.enabled); 784 var vs = versions.versions.filter(version => version.enabled);
790 vs.sort((a, b) => { 785 vs.sort((a, b) => {
791 return b.getEntry(selectedGroup).getTimeImpact() - 786 return b.getEntry(selectedGroup).getTimeImpact() -
792 a.getEntry(selectedGroup).getTimeImpact(); 787 a.getEntry(selectedGroup).getTimeImpact();
793 }); 788 });
794 // Calculate the entries for the versions 789 // Calculate the entries for the versions
795 vs.forEach((version) => { 790 vs.forEach((version) => {
796 row = [version.name]; 791 row = [version.name];
797 groups.forEach((group) => { 792 groups.forEach((group) => {
798 row.push(group.isTotal ? 0 : version.getEntry(group).getTimeImpact()); 793 row.push(group.isTotal ? 0 : version.getEntry(group).getTimeImpact());
799 }); 794 });
800 var rowIndex = dataTable.addRow(row); 795 var rowIndex = dataTable.addRow(row);
801 dataTable.setRowProperty(rowIndex, 'page', page); 796 dataTable.setRowProperty(rowIndex, 'page', page);
802 }); 797 });
803 renderGraph('Versions Total Time over all Pages', groups, dataTable, 798 renderGraph('Versions Total Time over all Pages', groups, dataTable,
804 'versionGraph', true); 799 'versionGraph', true);
805 } 800 }
806 801
807 function showPageVersionGraph(groups, page) { 802 function showPageVersionGraph(groups, page) {
808 var dataTable = getGraphDataTable(groups); 803 var dataTable = getGraphDataTable(groups);
809 var row; 804 var row;
810 var vs = versions.getPageVersions(page); 805 var vs = versions.getPageVersions(page);
811 vs.sort((a, b) => { 806 vs.sort((a, b) => {
812 return b.getEntry(selectedGroup).time - a.getEntry(selectedGroup).time; 807 return b.getEntry(selectedGroup).time - a.getEntry(selectedGroup).time;
813 }); 808 });
814 // Calculate the entries for the versions 809 // Calculate the entries for the versions
815 vs.forEach((page) => { 810 vs.forEach((page) => {
816 row = [page.version.name]; 811 row = [page.version.name];
817 groups.forEach((group) => { 812 groups.forEach((group) => {
818 row.push(group.isTotal ? 0 : page.getEntry(group).time); 813 row.push(group.isTotal ? 0 : page.getEntry(group).time);
819 }); 814 });
820 var rowIndex = dataTable.addRow(row); 815 var rowIndex = dataTable.addRow(row);
821 dataTable.setRowProperty(rowIndex, 'page', page); 816 dataTable.setRowProperty(rowIndex, 'page', page);
822 }); 817 });
823 renderGraph('Versions for ' + page.name, groups, dataTable, 818 renderGraph('Versions for ' + page.name, groups, dataTable,
824 'pageVersionGraph', true); 819 'pageVersionGraph', true);
825 } 820 }
826 821
827 function renderGraph(title, groups, dataTable, id, isStacked) { 822 function renderGraph(title, groups, dataTable, id, isStacked) {
828 var isDiffView = baselineVersion !== undefined; 823 var isDiffView = baselineVersion !== undefined;
829 var formatter = new google.visualization.NumberFormat({ 824 var formatter = new google.visualization.NumberFormat({
830 suffix: (isDiffView ? 'msΔ' : 'ms'), 825 suffix: (isDiffView ? 'msΔ' : 'ms'),
831 negativeColor: 'red', 826 negativeColor: 'red',
832 groupingSymbol: "'" 827 groupingSymbol: "'"
833 }); 828 });
834 for (var i = 1; i < dataTable.getNumberOfColumns(); i++) { 829 for (var i = 1; i < dataTable.getNumberOfColumns(); i++) {
835 formatter.format(dataTable, i); 830 formatter.format(dataTable, i);
836 } 831 }
837 var height = 85 + 28 * dataTable.getNumberOfRows(); 832 var height = 85 + 28 * dataTable.getNumberOfRows();
838 var options = { 833 var options = {
839 isStacked: isStacked, 834 isStacked: isStacked,
840 height: height, 835 height: height,
841 hAxis: { 836 hAxis: {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 node('.timeImpact').textContent = '-'; 926 node('.timeImpact').textContent = '-';
932 node('.timePercentImpact').textContent = '-'; 927 node('.timePercentImpact').textContent = '-';
933 } else { 928 } else {
934 node('.version').textContent = entry.page.version.name; 929 node('.version').textContent = entry.page.version.name;
935 node('.time').textContent = ms(entry._time, false); 930 node('.time').textContent = ms(entry._time, false);
936 node('.timeVariance').textContent 931 node('.timeVariance').textContent
937 = percent(entry.timeVariancePercent, false); 932 = percent(entry.timeVariancePercent, false);
938 node('.percent').textContent = percent(entry.timePercent, false); 933 node('.percent').textContent = percent(entry.timePercent, false);
939 node('.percentPerEntry').textContent 934 node('.percentPerEntry').textContent
940 = percent(entry.timePercentPerEntry, false); 935 = percent(entry.timePercentPerEntry, false);
941 node('.percentVariance').textContent 936 node('.percentVariance').textContent
942 = percent(entry.timePercentVariancePercent, false); 937 = percent(entry.timePercentVariancePercent, false);
943 node('.count').textContent = count(entry._count, false); 938 node('.count').textContent = count(entry._count, false);
944 node('.countVariance').textContent 939 node('.countVariance').textContent
945 = percent(entry.timeVariancePercent, false); 940 = percent(entry.timeVariancePercent, false);
946 node('.timeImpact').textContent 941 node('.timeImpact').textContent
947 = ms(entry.getTimeImpact(false), false); 942 = ms(entry.getTimeImpact(false), false);
948 node('.timePercentImpact').textContent 943 node('.timePercentImpact').textContent
949 = percent(entry.getTimeImpactVariancePercent(false), false); 944 = percent(entry.getTimeImpactVariancePercent(false), false);
950 } 945 }
951 } 946 }
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 // Calculate the overall error for a given entry name 1365 // Calculate the overall error for a given entry name
1371 var sum = 0; 1366 var sum = 0;
1372 this.forEachPage((page) => { 1367 this.forEachPage((page) => {
1373 var entry = page.get(name); 1368 var entry = page.get(name);
1374 if (entry === undefined) return; 1369 if (entry === undefined) return;
1375 sum += entry.timeVariance * entry.timeVariance; 1370 sum += entry.timeVariance * entry.timeVariance;
1376 }); 1371 });
1377 return Math.sqrt(sum); 1372 return Math.sqrt(sum);
1378 } 1373 }
1379 getTotalTimeVariancePercent(name, showDiff) { 1374 getTotalTimeVariancePercent(name, showDiff) {
1380 return this.getTotalTimeVariance(name, showDiff) / 1375 return this.getTotalTimeVariance(name, showDiff) /
1381 this.getTotalTime(name, showDiff) * 100; 1376 this.getTotalTime(name, showDiff) * 100;
1382 } 1377 }
1383 getTotalCount(name, showDiff) { 1378 getTotalCount(name, showDiff) {
1384 return this.getTotalValue(name, showDiff === false ? '_count' : 'count') ; 1379 return this.getTotalValue(name, showDiff === false ? '_count' : 'count') ;
1385 } 1380 }
1386 getAverageTimeImpact(name, showDiff) { 1381 getAverageTimeImpact(name, showDiff) {
1387 return this.getTotalTime(name, showDiff) / this.pages.length; 1382 return this.getTotalTime(name, showDiff) / this.pages.length;
1388 } 1383 }
1389 getPagesByPercentImpact(name) { 1384 getPagesByPercentImpact(name) {
1390 var sortedPages = 1385 var sortedPages =
(...skipping 10 matching lines...) Expand all
1401 } 1396 }
1402 } 1397 }
1403 Version.fromJSON = function(name, data) { 1398 Version.fromJSON = function(name, data) {
1404 var version = new Version(name); 1399 var version = new Version(name);
1405 for (var pageName in data) { 1400 for (var pageName in data) {
1406 version.add(PageVersion.fromJSON(version, pageName, data[pageName])); 1401 version.add(PageVersion.fromJSON(version, pageName, data[pageName]));
1407 } 1402 }
1408 version.sort(); 1403 version.sort();
1409 return version; 1404 return version;
1410 } 1405 }
1411 1406
1412 class Pages extends Map { 1407 class Pages extends Map {
1413 get(name) { 1408 get(name) {
1414 if (name.indexOf('www.') == 0) { 1409 if (name.indexOf('www.') == 0) {
1415 name = name.substring(4); 1410 name = name.substring(4);
1416 } 1411 }
1417 if (!this.has(name)) { 1412 if (!this.has(name)) {
1418 this.set(name, new Page(name)); 1413 this.set(name, new Page(name));
1419 } 1414 }
1420 return super.get(name); 1415 return super.get(name);
1421 } 1416 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 return b.time - a.time; 1512 return b.time - a.time;
1518 }); 1513 });
1519 this.groups.forEach((group) => { 1514 this.groups.forEach((group) => {
1520 group.sort() 1515 group.sort()
1521 }); 1516 });
1522 } 1517 }
1523 distanceFromTotalPercent() { 1518 distanceFromTotalPercent() {
1524 var sum = 0; 1519 var sum = 0;
1525 this.groups.forEach(group => { 1520 this.groups.forEach(group => {
1526 if (group == this.total) return; 1521 if (group == this.total) return;
1527 var value = group.getTimePercentImpact() - 1522 var value = group.getTimePercentImpact() -
1528 this.getEntry(group).timePercent; 1523 this.getEntry(group).timePercent;
1529 sum += value * value; 1524 sum += value * value;
1530 }); 1525 });
1531 return sum; 1526 return sum;
1532 } 1527 }
1533 getNextPage() { 1528 getNextPage() {
1534 return this.version.getNextPage(this); 1529 return this.version.getNextPage(this);
1535 } 1530 }
1536 } 1531 }
1537 PageVersion.fromJSON = function(version, name, data) { 1532 PageVersion.fromJSON = function(version, name, data) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1627 return this._timeVariance 1622 return this._timeVariance
1628 } 1623 }
1629 get timeVariancePercent() { 1624 get timeVariancePercent() {
1630 return this._timeVariancePercent 1625 return this._timeVariancePercent
1631 } 1626 }
1632 } 1627 }
1633 Entry.fromJSON = function(position, data) { 1628 Entry.fromJSON = function(position, data) {
1634 return new Entry(position, ...data); 1629 return new Entry(position, ...data);
1635 } 1630 }
1636 1631
1637 class Group { 1632 class Group {
1638 constructor(name, regexp, color) { 1633 constructor(name, regexp, color) {
1639 this.name = name; 1634 this.name = name;
1640 this.regexp = regexp; 1635 this.regexp = regexp;
1641 this.color = color; 1636 this.color = color;
1642 this.enabled = true; 1637 this.enabled = true;
1643 } 1638 }
1644 entry() { return new GroupedEntry(this) }; 1639 entry() { return new GroupedEntry(this) };
1645 } 1640 }
1646 Group.groups = new Map(); 1641 Group.groups = new Map();
1647 Group.add = function(name, group) { 1642 Group.add = function(name, group) {
1648 this.groups.set(name, group); 1643 this.groups.set(name, group);
1649 return group; 1644 return group;
1650 } 1645 }
1651 Group.add('total', new Group('Total', /.*Total.*/, '#BBB')); 1646 Group.add('total', new Group('Total', /.*Total.*/, '#BBB'));
1652 Group.add('ic', new Group('IC', /.*IC_.*/, "#3366CC")); 1647 Group.add('ic', new Group('IC', /.*IC_.*/, "#3366CC"));
1653 Group.add('optimize', new Group('Optimize', 1648 Group.add('optimize', new Group('Optimize',
1654 /StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/, "#DC3912")); 1649 /StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/, "#DC3912"));
1655 Group.add('compile-background', new Group('Compile-Background', 1650 Group.add('compile-background', new Group('Compile-Background',
1656 /(.*CompileBackground.*)/, "#b9a720")); 1651 /(.*CompileBackground.*)/, "#b9a720"));
1657 Group.add('compile', new Group('Compile', 1652 Group.add('compile', new Group('Compile',
1658 /(^Compile.*)|(.*_Compile.*)/, "#FFAA00")); 1653 /(^Compile.*)|(.*_Compile.*)/, "#FFAA00"));
1659 Group.add('parse-background', 1654 Group.add('parse-background',
1660 new Group('Parse-Background', /.*ParseBackground.*/, "#af744d")); 1655 new Group('Parse-Background', /.*ParseBackground.*/, "#af744d"));
1661 Group.add('parse', new Group('Parse', /.*Parse.*/, "#FF6600")); 1656 Group.add('parse', new Group('Parse', /.*Parse.*/, "#FF6600"));
1662 Group.add('callback', new Group('Blink C++', /.*Callback.*/, "#109618")); 1657 Group.add('callback', new Group('Blink C++', /.*Callback.*/, "#109618"));
1663 Group.add('api', new Group('API', /.*API.*/, "#990099")); 1658 Group.add('api', new Group('API', /.*API.*/, "#990099"));
1664 Group.add('gc', new Group('GC', /GC|AllocateInTargetSpace/, "#0099C6")); 1659 Group.add('gc', new Group('GC', /GC|AllocateInTargetSpace/, "#0099C6"));
1665 Group.add('javascript', new Group('JavaScript', /JS_Execution/, "#DD4477")); 1660 Group.add('javascript', new Group('JavaScript', /JS_Execution/, "#DD4477"));
1666 Group.add('runtime', new Group('V8 C++', /.*/, "#88BB00")); 1661 Group.add('runtime', new Group('V8 C++', /.*/, "#88BB00"));
1667 var group = 1662 var group =
1668 Group.add('unclassified', new Group('Unclassified', /.*/, "#000")); 1663 Group.add('unclassified', new Group('Unclassified', /.*/, "#000"));
1669 group.enabled = false; 1664 group.enabled = false;
1670 1665
1671 class GroupedEntry extends Entry { 1666 class GroupedEntry extends Entry {
1672 constructor(group) { 1667 constructor(group) {
1673 super(0, GroupedEntry.prefix + group.name, 0, 0, 0, 0, 0, 0); 1668 super(0, GroupedEntry.prefix + group.name, 0, 0, 0, 0, 0, 0);
1674 this.group = group; 1669 this.group = group;
1675 this.entries = []; 1670 this.entries = [];
1676 } 1671 }
1677 get regexp() { return this.group.regexp } 1672 get regexp() { return this.group.regexp }
1678 get color() { return this.group.color } 1673 get color() { return this.group.color }
1679 get enabled() { return this.group.enabled } 1674 get enabled() { return this.group.enabled }
1680 add(entry) { 1675 add(entry) {
1681 if (!this.regexp.test(entry.name)) return false; 1676 if (!this.regexp.test(entry.name)) return false;
1682 this._time += entry.time; 1677 this._time += entry.time;
1683 this._count += entry.count; 1678 this._count += entry.count;
1684 // TODO: sum up variance 1679 // TODO: sum up variance
1685 this.entries.push(entry); 1680 this.entries.push(entry);
1686 entry.parent = this; 1681 entry.parent = this;
1687 return true; 1682 return true;
1688 } 1683 }
1689 forEach(fun) { 1684 forEach(fun) {
1690 if (baselineVersion === undefined) { 1685 // Show also all entries which are in at least one version.
1691 this.entries.forEach(fun); 1686 var dummyEntryNames = new Set();
1692 return; 1687 versions.forEach((version) => {
1693 } 1688 var groupEntry = version.getEntry(this);
1694 // If we have a baslineVersion to compare against show also all entries 1689 if (groupEntry != this) {
1695 // from the other group. 1690 for (var entry of groupEntry.entries) {
1696 var tmpEntries = baselineVersion.getEntry(this) 1691 if (this.page.get(entry.name) == undefined) {
1697 .entries.filter((entry) => { 1692 dummyEntryNames.add(entry.name);
1698 return this.page.get(entry.name) == undefined 1693 }
1699 }); 1694 }
1695 }
1696 });
1697 var tmpEntries = [];
1698 for (var name of dummyEntryNames) {
1699 var tmpEntry = new Entry(0, name, 0, 0, 0, 0, 0, 0);
1700 tmpEntry.page = this.page;
1701 tmpEntries.push(tmpEntry);
1702 };
1703
1704 // Concatenate our real entries.
1705 tmpEntries = tmpEntries.concat(this.entries);
1700 1706
1701 // The compared entries are sorted by absolute impact. 1707 // The compared entries are sorted by absolute impact.
1702 tmpEntries = tmpEntries.map((entry) => {
1703 var tmpEntry = new Entry(0, entry.name, 0, 0, 0, 0, 0, 0);
1704 tmpEntry.page = this.page;
1705 return tmpEntry;
1706 });
1707 tmpEntries = tmpEntries.concat(this.entries);
1708 tmpEntries.sort((a, b) => { 1708 tmpEntries.sort((a, b) => {
1709 return a.time - b.time 1709 return a.time - b.time
1710 }); 1710 });
1711 tmpEntries.forEach(fun); 1711 tmpEntries.forEach(fun);
1712 } 1712 }
1713 sort() { 1713 sort() {
1714 this.entries.sort((a, b) => { 1714 this.entries.sort((a, b) => {
1715 return b.time - a.time; 1715 return b.time - a.time;
1716 }); 1716 });
1717 } 1717 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 </div> 1795 </div>
1796 1796
1797 <div class="inline hidden"> 1797 <div class="inline hidden">
1798 <h2>Result</h2> 1798 <h2>Result</h2>
1799 <div class="compareSelector inline"> 1799 <div class="compareSelector inline">
1800 Compare against:&nbsp;<select id="baseline" onchange="handleSelectBaseli ne(this, event)"></select><br/> 1800 Compare against:&nbsp;<select id="baseline" onchange="handleSelectBaseli ne(this, event)"></select><br/>
1801 <span style="color: #060">Green</span> the selected version above perfor ms 1801 <span style="color: #060">Green</span> the selected version above perfor ms
1802 better on this measurement. 1802 better on this measurement.
1803 </div> 1803 </div>
1804 </div> 1804 </div>
1805 1805
1806 <div id="versionSelector" class="inline toggleContentVisibility"> 1806 <div id="versionSelector" class="inline toggleContentVisibility">
1807 <h2>Versions</h2> 1807 <h2>Versions</h2>
1808 <div class="content hidden"> 1808 <div class="content hidden">
1809 <ul></ul> 1809 <ul></ul>
1810 </div> 1810 </div>
1811 </div> 1811 </div>
1812 1812
1813 <div id="pageSelector" class="inline toggleContentVisibility"> 1813 <div id="pageSelector" class="inline toggleContentVisibility">
1814 <h2>Pages</h2> 1814 <h2>Pages</h2>
1815 <div class="content hidden"> 1815 <div class="content hidden">
1816 <ul></ul> 1816 <ul></ul>
1817 </div> 1817 </div>
1818 </div> 1818 </div>
1819 1819
1820 <div id="groupSelector" class="inline toggleContentVisibility"> 1820 <div id="groupSelector" class="inline toggleContentVisibility">
1821 <h2>Groups</h2> 1821 <h2>Groups</h2>
1822 <div class="content hidden"> 1822 <div class="content hidden">
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 </tr> 1981 </tr>
1982 <tr> 1982 <tr>
1983 <td>Overall Impact:</td> 1983 <td>Overall Impact:</td>
1984 <td class="timeImpact"></td><td>±</td><td class="timePercentImpact"></td > 1984 <td class="timeImpact"></td><td>±</td><td class="timePercentImpact"></td >
1985 <td class="compare timeImpact"></td><td class="compare"> ± </td><td clas s="compare timePercentImpact"></td> 1985 <td class="compare timeImpact"></td><td class="compare"> ± </td><td clas s="compare timePercentImpact"></td>
1986 </tr> 1986 </tr>
1987 </table> 1987 </table>
1988 </div> 1988 </div>
1989 </body> 1989 </body>
1990 </html> 1990 </html>
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698