1<!DOCTYPE html> 2<!-- 3Copyright (c) 2013 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7 8<link rel="import" href="/tracing/base/base.html"> 9<link rel="import" href="/tracing/model/event_set.html"> 10<link rel="import" href="/tracing/ui/analysis/generic_object_view.html"> 11<link rel="import" href="/tracing/ui/analysis/multi_event_summary.html"> 12<link rel="import" href="/tracing/ui/base/table.html"> 13<link rel="import" href="/tracing/value/ui/scalar_span.html"> 14<link rel="import" href="/tracing/value/unit.html"> 15 16<polymer-element name='tr-ui-a-multi-event-details-table'> 17 <template> 18 <style> 19 :host { 20 display: flex; 21 flex-direction: column; 22 } 23 #table { 24 flex: 1 1 auto; 25 align-self: stretch; 26 } 27 28 #titletable { 29 font-weight: bold; 30 } 31 32 #title-info { 33 font-size: 12px; 34 } 35 </style> 36 <tr-ui-b-table id="titletable"> 37 </tr-ui-b-table> 38 <tr-ui-b-table id="table"> 39 </tr-ui-b-table> 40 </template> 41 42 <script> 43 'use strict'; 44 45 Polymer({ 46 created: function() { 47 this.selection_ = undefined; 48 this.eventsHaveDuration_ = true; 49 this.eventsHaveSubRows_ = true; 50 }, 51 52 ready: function() { 53 this.initTitleTable_(); 54 }, 55 56 get eventsHaveDuration() { 57 return this.eventsHaveDuration_; 58 }, 59 60 set eventsHaveDuration(eventsHaveDuration) { 61 this.eventsHaveDuration_ = eventsHaveDuration; 62 this.updateContents_(); 63 }, 64 65 get eventsHaveSubRows() { 66 return this.eventsHaveSubRows_; 67 }, 68 69 set eventsHaveSubRows(eventsHaveSubRows) { 70 this.eventsHaveSubRows_ = eventsHaveSubRows; 71 this.updateContents_(); 72 }, 73 74 get selection() { 75 return this.selection_; 76 }, 77 78 set selection(selection) { 79 this.selection_ = selection; 80 this.updateContents_(); 81 }, 82 83 updateContents_: function() { 84 var selection = this.selection_; 85 86 this.updateTitleTable_(); 87 88 if (this.selection_ === undefined) { 89 this.$.table.tableRows = []; 90 this.$.table.tableFooterRows = []; 91 this.$.table.rebuild(); 92 return; 93 } 94 95 var summary = new tr.ui.analysis.MultiEventSummary( 96 'Totals', this.selection_); 97 this.updateColumns_(summary); 98 this.updateRows_(summary); 99 this.$.table.rebuild(); 100 }, 101 102 initTitleTable_: function() { 103 var table = this.$.titletable; 104 105 table.showHeader = false; 106 table.tableColumns = [ 107 { 108 title: 'Title', 109 value: function(row) { return row.title; }, 110 width: '350px' 111 }, 112 { 113 title: 'Value', 114 width: '100%', 115 value: function(row) { 116 return row.value; 117 } 118 } 119 ]; 120 }, 121 122 updateTitleTable_: function() { 123 var title; 124 if (this.selection_ && this.selection_.length) 125 title = this.selection_[0].title; 126 else 127 title = '<No selection>'; 128 129 var table = this.$.titletable; 130 table.tableRows = [{ 131 title: 'Title', 132 value: title 133 }]; 134 }, 135 136 updateColumns_: function(summary) { 137 var hasCpuData; 138 if (summary.cpuDuration !== undefined) 139 hasCpuData = true; 140 if (summary.cpuSelfTime !== undefined) 141 hasCpuData = true; 142 143 var colWidthPercentage; 144 if (hasCpuData) 145 colWidthPercentage = '20%'; 146 else 147 colWidthPercentage = '33.3333%'; 148 149 var ownerDocument = this.ownerDocument; 150 var columns = []; 151 152 columns.push({ 153 title: 'Start', 154 value: function(row) { 155 if (row.__proto__ === tr.ui.analysis.MultiEventSummary.prototype) { 156 return row.title; 157 } 158 159 var linkEl = document.createElement('tr-ui-a-analysis-link'); 160 linkEl.setSelectionAndContent(function() { 161 return new tr.model.EventSet(row.event); 162 }); 163 linkEl.appendChild(tr.v.ui.createScalarSpan(row.start, { 164 unit: tr.v.Unit.byName.timeStampInMs, 165 ownerDocument: ownerDocument 166 })); 167 return linkEl; 168 }, 169 width: '350px', 170 cmp: function(rowA, rowB) { 171 return rowA.start - rowB.start; 172 } 173 }); 174 175 if (this.eventsHaveDuration_) { 176 columns.push({ 177 title: 'Wall Duration (ms)', 178 value: function(row) { 179 return tr.v.ui.createScalarSpan(row.duration, { 180 unit: tr.v.Unit.byName.timeDurationInMs, 181 ownerDocument: ownerDocument 182 }); 183 }, 184 width: '<upated further down>', 185 cmp: function(rowA, rowB) { 186 return rowA.duration - rowB.duration; 187 } 188 }); 189 } 190 191 if (this.eventsHaveDuration_ && hasCpuData) { 192 columns.push({ 193 title: 'CPU Duration (ms)', 194 value: function(row) { 195 return tr.v.ui.createScalarSpan(row.cpuDuration, { 196 unit: tr.v.Unit.byName.timeDurationInMs, 197 ownerDocument: ownerDocument 198 }); 199 }, 200 width: '<upated further down>', 201 cmp: function(rowA, rowB) { 202 return rowA.cpuDuration - rowB.cpuDuration; 203 } 204 }); 205 } 206 207 if (this.eventsHaveSubRows_ && this.eventsHaveDuration_) { 208 columns.push({ 209 title: 'Self time (ms)', 210 value: function(row) { 211 return tr.v.ui.createScalarSpan(row.selfTime, { 212 unit: tr.v.Unit.byName.timeDurationInMs, 213 ownerDocument: ownerDocument 214 }); 215 }, 216 width: '<upated further down>', 217 cmp: function(rowA, rowB) { 218 return rowA.selfTime - rowB.selfTime; 219 } 220 }); 221 } 222 223 if (this.eventsHaveSubRows_ && this.eventsHaveDuration_ && hasCpuData) { 224 columns.push({ 225 title: 'CPU Self Time (ms)', 226 value: function(row) { 227 return tr.v.ui.createScalarSpan(row.cpuSelfTime, { 228 unit: tr.v.Unit.byName.timeDurationInMs, 229 ownerDocument: ownerDocument 230 }); 231 }, 232 width: '<upated further down>', 233 cmp: function(rowA, rowB) { 234 return rowA.cpuSelfTime - rowB.cpuSelfTime; 235 } 236 }); 237 } 238 239 var argKeys = tr.b.dictionaryKeys(summary.totalledArgs); 240 argKeys.sort(); 241 242 var otherKeys = summary.untotallableArgs.slice(0); 243 otherKeys.sort(); 244 245 argKeys.push.apply(argKeys, otherKeys); 246 var keysWithColumns = argKeys.slice(0, 4); 247 var keysInOtherColumn = argKeys.slice(4); 248 249 keysWithColumns.forEach(function(argKey) { 250 251 var hasTotal = summary.totalledArgs[argKey]; 252 var colDesc = { 253 title: 'Arg: ' + argKey, 254 value: function(row) { 255 if (row.__proto__ !== tr.ui.analysis.MultiEventSummary.prototype) { 256 var argView = 257 document.createElement('tr-ui-a-generic-object-view'); 258 argView.object = row.args[argKey]; 259 return argView; 260 } 261 if (hasTotal) 262 return row.totalledArgs[argKey]; 263 return ''; 264 }, 265 width: '<upated further down>' 266 }; 267 if (hasTotal) { 268 colDesc.cmp = function(rowA, rowB) { 269 return rowA.args[argKey] - rowB.args[argKey]; 270 }; 271 } 272 columns.push(colDesc); 273 }); 274 275 if (keysInOtherColumn.length) { 276 columns.push({ 277 title: 'Other Args', 278 value: function(row) { 279 if (row.__proto__ === tr.ui.analysis.MultiEventSummary.prototype) 280 return ''; 281 var argView = 282 document.createElement('tr-ui-a-generic-object-view'); 283 var obj = {}; 284 for (var i = 0; i < keysInOtherColumn.length; i++) 285 obj[keysInOtherColumn[i]] = row.args[keysInOtherColumn[i]]; 286 argView.object = obj; 287 return argView; 288 }, 289 width: '<upated further down>' 290 }); 291 } 292 293 var colWidthPercentage; 294 if (columns.length == 1) 295 colWidthPercentage = '100%'; 296 else 297 colWidthPercentage = (100 / (columns.length - 1)).toFixed(3) + '%'; 298 299 for (var i = 1; i < columns.length; i++) 300 columns[i].width = colWidthPercentage; 301 302 this.$.table.tableColumns = columns; 303 }, 304 305 updateRows_: function(summary) { 306 this.$.table.sortColumnIndex = 0; 307 function Row(event) { 308 this.event = event; 309 } 310 Row.prototype = { 311 get start() { return this.event.start; }, 312 get duration() { return this.event.duration; }, 313 get cpuDuration() { return this.event.cpuDuration; }, 314 get selfTime() { return this.event.selfTime; }, 315 get cpuSelfTime() { return this.event.cpuSelfTime; }, 316 get args() { return this.event.args; } 317 }; 318 319 this.$.table.tableRows = this.selection_.map(function(event) { 320 return new Row(event); 321 }); 322 this.$.table.footerRows = [summary]; 323 } 324 }); 325</script> 326</polymer-element> 327 328 329