1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5'use strict'; 6 7base.requireStylesheet('tracing.analysis.analysis_results'); 8 9base.require('tracing.analysis.util'); 10base.require('tracing.analysis.analysis_link'); 11base.require('tracing.analysis.generic_object_view'); 12base.require('ui'); 13 14base.exportTo('tracing.analysis', function() { 15 var AnalysisResults = ui.define('div'); 16 17 AnalysisResults.prototype = { 18 __proto__: HTMLDivElement.prototype, 19 20 decorate: function() { 21 this.className = 'analysis-results'; 22 }, 23 24 clear: function() { 25 this.textContent = ''; 26 }, 27 28 createSelectionChangingLink: function(text, selectionGenerator, 29 opt_tooltip) { 30 var el = this.ownerDocument.createElement('a'); 31 tracing.analysis.AnalysisLink.decorate(el); 32 el.textContent = text; 33 el.selectionGenerator = selectionGenerator; 34 if (opt_tooltip) 35 el.title = opt_tooltip; 36 return el; 37 }, 38 39 appendElement_: function(parent, tagName, opt_text) { 40 var n = parent.ownerDocument.createElement(tagName); 41 parent.appendChild(n); 42 if (opt_text != undefined) 43 n.textContent = opt_text; 44 return n; 45 }, 46 47 appendText_: function(parent, text) { 48 var textElement = parent.ownerDocument.createTextNode(text); 49 parent.appendChild(textNode); 50 return textNode; 51 }, 52 53 appendTableCell_: function(table, row, cellnum, text) { 54 var td = this.appendElement_(row, 'td', text); 55 td.className = table.className + '-col-' + cellnum; 56 return td; 57 }, 58 59 appendTableCell: function(table, row, text) { 60 return this.appendTableCell_(table, row, row.children.length, text); 61 }, 62 63 appendTableCellWithTooltip_: function(table, row, cellnum, text, tooltip) { 64 if (tooltip) { 65 var td = this.appendElement_(row, 'td'); 66 td.className = table.className + '-col-' + cellnum; 67 var span = this.appendElement_(td, 'span', text); 68 span.className = 'tooltip'; 69 span.title = tooltip; 70 return td; 71 } else { 72 this.appendTableCell_(table, row, cellnum, text); 73 } 74 }, 75 76 /** 77 * Adds a table with the given className. 78 * @return {HTMLTableElement} The newly created table. 79 */ 80 appendTable: function(className, numColumns) { 81 var table = this.appendElement_(this, 'table'); 82 table.headerRow = this.appendElement_(table, 'tr'); 83 table.className = className + ' analysis-table'; 84 table.numColumns = numColumns; 85 return table; 86 }, 87 88 /** 89 * Creates and appends a row to |table| with a left-aligned |label] 90 * header that spans all columns. 91 */ 92 appendTableHeader: function(table, label) { 93 var th = this.appendElement_(table.headerRow, 'th', label); 94 th.className = 'analysis-table-header'; 95 }, 96 97 appendTableRow: function(table) { 98 return this.appendElement_(table, 'tr'); 99 }, 100 101 /** 102 * Creates and appends a row to |table| with a left-aligned |label] 103 * in the first column and an optional |opt_value| in the second 104 * column. 105 */ 106 appendSummaryRow: function(table, label, opt_value) { 107 var row = this.appendElement_(table, 'tr'); 108 row.className = 'analysis-table-row'; 109 110 this.appendTableCell_(table, row, 0, label); 111 112 if (opt_value !== undefined) { 113 var objectView = new tracing.analysis.GenericObjectView(); 114 objectView.object = opt_value; 115 objectView.classList.add('analysis-table-col-1'); 116 objectView.style.display = 'table-cell'; 117 row.appendChild(objectView); 118 } else { 119 this.appendTableCell_(table, row, 1, ''); 120 } 121 for (var i = 2; i < table.numColumns; i++) 122 this.appendTableCell_(table, row, i, ''); 123 }, 124 125 /** 126 * Adds a spacing row to spread out results. 127 */ 128 appendSpacingRow: function(table) { 129 var row = this.appendElement_(table, 'tr'); 130 row.className = 'analysis-table-row'; 131 for (var i = 0; i < table.numColumns; i++) 132 this.appendTableCell_(table, row, i, ' '); 133 }, 134 135 /** 136 * Creates and appends a row to |table| with a left-aligned |label] 137 * in the first column and a millisecvond |time| value in the second 138 * column. 139 */ 140 appendSummaryRowTime: function(table, label, time) { 141 this.appendSummaryRow(table, label, 142 tracing.analysis.tsRound(time) + ' ms'); 143 }, 144 145 /** 146 * Creates and appends a row to |table| that summarizes one or more slices, 147 * or one or more counters. 148 * The row has a left-aligned |label| in the first column, the |duration| 149 * of the data in the second, the number of |occurrences| in the third. 150 * @param {object=} opt_statistics May be undefined, or an object which 151 * contains calculated staistics containing min/max/avg for slices, or 152 * min/max/avg/start/end for counters. 153 */ 154 appendDataRow: function( 155 table, label, opt_duration, opt_occurences, 156 opt_statistics, opt_selectionGenerator) { 157 158 var tooltip = undefined; 159 if (opt_statistics) { 160 tooltip = 'Min Duration:\u0009' + 161 tracing.analysis.tsRound(opt_statistics.min) + 162 ' ms \u000DMax Duration:\u0009' + 163 tracing.analysis.tsRound(opt_statistics.max) + 164 ' ms \u000DAvg Duration:\u0009' + 165 tracing.analysis.tsRound(opt_statistics.avg) + 166 ' ms (\u03C3 = ' + 167 tracing.analysis.tsRound(opt_statistics.avg_stddev) + ')'; 168 169 if (opt_statistics.start) { 170 tooltip += '\u000DStart Time:\u0009' + 171 tracing.analysis.tsRound(opt_statistics.start) + ' ms'; 172 } 173 if (opt_statistics.end) { 174 tooltip += '\u000DEnd Time:\u0009' + 175 tracing.analysis.tsRound(opt_statistics.end) + ' ms'; 176 } 177 if (opt_statistics.frequency && opt_statistics.frequency_stddev) { 178 tooltip += '\u000DFrequency:\u0009' + 179 tracing.analysis.tsRound(opt_statistics.frequency) + 180 ' occurrences/s (\u03C3 = ' + 181 tracing.analysis.tsRound(opt_statistics.frequency_stddev) + ')'; 182 } 183 } 184 185 var row = this.appendElement_(table, 'tr'); 186 row.className = 'analysis-table-row'; 187 188 if (!opt_selectionGenerator) { 189 this.appendTableCellWithTooltip_(table, row, 0, label, tooltip); 190 } else { 191 var labelEl = this.appendTableCellWithTooltip_( 192 table, row, 0, label, tooltip); 193 labelEl.textContent = ''; 194 labelEl.appendChild( 195 this.createSelectionChangingLink(label, opt_selectionGenerator, 196 tooltip)); 197 } 198 199 if (opt_duration !== undefined) { 200 if (opt_duration instanceof Array) { 201 this.appendTableCellWithTooltip_(table, row, 1, 202 '[' + opt_duration.join(', ') + ']', tooltip); 203 } else { 204 this.appendTableCellWithTooltip_(table, row, 1, 205 tracing.analysis.tsRound(opt_duration) + ' ms', tooltip); 206 } 207 } else { 208 this.appendTableCell_(table, row, 1, ''); 209 } 210 211 if (opt_occurences !== undefined) { 212 this.appendTableCellWithTooltip_(table, row, 2, 213 String(opt_occurences) + ' occurrences', tooltip); 214 215 } else { 216 this.appendTableCell_(table, row, 2, ''); 217 } 218 } 219 }; 220 return { 221 AnalysisResults: AnalysisResults 222 }; 223}); 224