3 Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
7 <link rel="stylesheet" href="/tracing/analysis/analysis_results.css">
9 <link rel="import" href="/base/ui.html">
10 <link rel="import" href="/tracing/analysis/util.html">
11 <link rel="import" href="/tracing/analysis/analysis_link.html">
12 <link rel="import" href="/tracing/analysis/generic_object_view.html">
17 tv.exportTo('tracing.analysis', function() {
18 var AnalysisResults = tv.ui.define('div');
20 AnalysisResults.prototype = {
21 __proto__: HTMLDivElement.prototype,
23 decorate: function() {
24 this.className = 'analysis-results';
27 get requiresTallView() {
32 this.textContent = '';
35 createSelectionChangingLink: function(text, selectionGenerator,
37 var el = this.ownerDocument.createElement('a');
38 tracing.analysis.AnalysisLink.decorate(el);
39 el.textContent = text;
40 el.selectionGenerator = selectionGenerator;
42 el.title = opt_tooltip;
46 appendElement_: function(parent, tagName, opt_text) {
47 var n = parent.ownerDocument.createElement(tagName);
48 parent.appendChild(n);
49 if (opt_text != undefined)
50 n.textContent = opt_text;
54 appendText_: function(parent, text) {
55 var textElement = parent.ownerDocument.createTextNode(text);
56 parent.appendChild(textNode);
60 appendTableCell_: function(table, row, cellnum, text, opt_warning) {
61 var td = this.appendElement_(row, 'td', text);
62 td.className = table.className + '-col-' + cellnum;
64 var span = document.createElement('span');
65 span.textContent = ' ' + String.fromCharCode(9888);
66 span.title = opt_warning;
73 * Creates and append a table cell at the end of the given row.
75 appendTableCell: function(table, row, text) {
76 return this.appendTableCell_(table, row, row.children.length, text);
79 appendTableCellWithTooltip_: function(table, row, cellnum, text, tooltip) {
81 var td = this.appendElement_(row, 'td');
82 td.className = table.className + '-col-' + cellnum;
83 var span = this.appendElement_(td, 'span', text);
84 span.className = 'tooltip';
88 return this.appendTableCell_(table, row, cellnum, text);
93 * Creates and appends a section header element.
95 appendHeader: function(label) {
96 var header = this.appendElement_(this, 'span', label);
97 header.className = 'analysis-header';
102 * Creates and appends a info element of the format "<b>label</b>value".
104 appendInfo: function(label, value) {
105 var div = this.appendElement_(this, 'div');
106 div.label = this.appendElement_(div, 'b', label);
107 div.value = this.appendElement_(div, 'span', value);
112 * Adds a table with the given className.
114 * @return {HTMLTableElement} The newly created table.
116 appendTable: function(className, numColumns) {
117 var table = this.appendElement_(this, 'table');
118 table.className = className + ' analysis-table';
119 table.numColumns = numColumns;
124 * Creates and appends a |tr| in |thead|, if |thead| does not exist, create
127 appendHeadRow: function(table) {
129 throw new Error('Only one header row allowed.');
130 if (table.tbody || table.tfoot)
132 'Cannot add a header row after data rows have been added.');
133 table.headerRow = this.appendElement_(
134 this.appendElement_(table, 'thead'), 'tr');
135 table.headerRow.className = 'analysis-table-header';
136 return table.headerRow;
140 * Creates and appends a |tr| in |tbody|, if |tbody| does not exist, create
143 appendBodyRow: function(table) {
146 'Cannot add a tbody row after footer rows have been added.');
148 table.tbody = this.appendElement_(table, 'tbody');
149 var row = this.appendElement_(table.tbody, 'tr');
151 row.className = 'analysis-table-row';
153 row.className = 'analysis-table-row-inverted';
158 * Creates and appends a |tr| in |tfoot|, if |tfoot| does not exist, create
161 appendFootRow: function(table) {
163 table.tfoot = this.appendElement_(table, 'tfoot');
164 table.tfoot.rowsClassName = (
165 (table.headerRow ? 1 : 0) +
166 (table.tbody ? table.tbody.rows.length : 0)) % 2 ?
167 'analysis-table-row' : 'analysis-table-row-inverted';
170 var row = this.appendElement_(table.tfoot, 'tr');
171 row.className = table.tfoot.rowsClassName;
176 * Adds a spacing row to spread out results.
178 appendSpacingRow: function(table, opt_inFoot) {
179 if (table.tfoot || opt_inFoot)
180 var row = this.appendFootRow(table);
182 var row = this.appendBodyRow(table);
183 for (var i = 0; i < table.numColumns; i++)
184 this.appendTableCell_(table, row, i, ' ');
188 * Creates and appends a row to |table| with a left-aligned |label] in the
189 * first column and an optional |opt_value| in the second column.
191 appendInfoRow: function(table, label, opt_value, opt_inFoot) {
192 if (table.tfoot || opt_inFoot)
193 var row = this.appendFootRow(table);
195 var row = this.appendBodyRow(table);
196 this.appendTableCell_(table, row, 0, label);
197 if (opt_value !== undefined) {
198 var objectView = new tracing.analysis.GenericObjectView();
199 objectView.object = opt_value;
200 objectView.classList.add('analysis-table-col-1');
201 objectView.style.display = 'table-cell';
202 row.appendChild(objectView);
204 this.appendTableCell_(table, row, 1, '');
206 for (var i = 2; i < table.numColumns; i++)
207 this.appendTableCell_(table, row, i, '');
211 * Creates and appends a row to |table| with a left-aligned |label] in the
212 * first column and a millisecond |time| value in the second column.
214 appendInfoRowTime: function(table, label, time, opt_inFoot, opt_warning) {
215 if (table.tfoot || opt_inFoot)
216 var row = this.appendFootRow(table);
218 var row = this.appendBodyRow(table);
219 this.appendTableCell_(table, row, 0, label);
220 this.appendTableCell_(
221 table, row, 1, tracing.analysis.tsRound(time) + ' ms', opt_warning);
225 * Creates and appends a row to |table| that summarizes a single slice or a
226 * single counter. The row has a left-aligned |start| in the first column,
227 * the |duration| of the data in the second, the number of |occurrences| in
230 * @param {object=} opt_statistics May be undefined, or an object which
231 * contains calculated staistics containing min/max/avg for slices,
232 * or min/max/avg/start/end for counters.
234 appendDetailsRow: function(table, start, duration, selfTime, args,
235 opt_selectionGenerator, opt_cpuDuration) {
236 var row = this.appendBodyRow(table);
238 if (opt_selectionGenerator) {
239 var labelEl = this.appendTableCell(table, row,
240 tracing.analysis.tsRound(start));
241 labelEl.textContent = '';
242 labelEl.appendChild(this.createSelectionChangingLink(
243 tracing.analysis.tsRound(start),
244 opt_selectionGenerator, ''));
246 this.appendTableCell(table, row, tracing.analysis.tsRound(start));
249 if (duration !== null)
250 this.appendTableCell(table, row, tracing.analysis.tsRound(duration));
253 this.appendTableCell(table, row,
254 opt_cpuDuration != '' ?
255 tracing.analysis.tsRound(opt_cpuDuration) :
258 if (selfTime !== null)
259 this.appendTableCell(table, row, tracing.analysis.tsRound(selfTime));
261 var argsCell = this.appendTableCell(table, row, '');
263 for (var argName in args) {
268 for (var argName in args) {
269 var argVal = args[argName];
270 var objectView = new tracing.analysis.GenericObjectView();
271 objectView.object = argVal;
272 var argsRow = this.appendElement_(
273 this.appendElement_(argsCell, 'table'), 'tr');
274 this.appendElement_(argsRow, 'td', argName + ':');
275 this.appendElement_(argsRow, 'td').appendChild(objectView);
281 * Creates and appends a row to |table| that summarizes one or more slices,
282 * or one or more counters. The row has a left-aligned |label| in the first
283 * column, the |duration| of the data in the second, the number of
284 * |occurrences| in the third.
286 * @param {object=} opt_statistics May be undefined, or an object which
287 * contains calculated staistics containing min/max/avg for slices,
288 * or min/max/avg/start/end for counters.
290 appendDataRow: function(table, label, opt_duration, opt_cpuDuration,
291 opt_selfTime, opt_cpuSelfTime, opt_occurences,
292 opt_percentage, opt_statistics,
293 opt_selectionGenerator, opt_inFoot) {
295 var tooltip = undefined;
296 if (opt_statistics) {
297 tooltip = 'Min Duration:\u0009' +
298 tracing.analysis.tsRound(opt_statistics.min) +
299 ' ms \u000DMax Duration:\u0009' +
300 tracing.analysis.tsRound(opt_statistics.max) +
301 ' ms \u000DAvg Duration:\u0009' +
302 tracing.analysis.tsRound(opt_statistics.avg) +
304 tracing.analysis.tsRound(opt_statistics.avg_stddev) + ')';
306 if (opt_statistics.start) {
307 tooltip += '\u000DStart Time:\u0009' +
308 tracing.analysis.tsRound(opt_statistics.start) + ' ms';
310 if (opt_statistics.end) {
311 tooltip += '\u000DEnd Time:\u0009' +
312 tracing.analysis.tsRound(opt_statistics.end) + ' ms';
314 if (opt_statistics.frequency && opt_statistics.frequency_stddev) {
315 tooltip += '\u000DFrequency:\u0009' +
316 tracing.analysis.tsRound(opt_statistics.frequency) +
317 ' occurrences/s (\u03C3 = ' +
318 tracing.analysis.tsRound(opt_statistics.frequency_stddev) + ')';
322 if (table.tfoot || opt_inFoot)
323 var row = this.appendFootRow(table);
325 var row = this.appendBodyRow(table);
328 if (!opt_selectionGenerator) {
329 this.appendTableCellWithTooltip_(table, row, cellNum, label, tooltip);
331 var labelEl = this.appendTableCellWithTooltip_(
332 table, row, cellNum, label, tooltip);
334 labelEl.textContent = '';
336 this.createSelectionChangingLink(label, opt_selectionGenerator,
342 if (opt_duration !== null) {
344 if (opt_duration instanceof Array) {
345 this.appendTableCellWithTooltip_(table, row, cellNum,
346 '[' + opt_duration.join(', ') + ']', tooltip);
348 this.appendTableCellWithTooltip_(table, row, cellNum,
349 tracing.analysis.tsRound(opt_duration), tooltip);
352 this.appendTableCell_(table, row, cellNum, '');
357 if (opt_cpuDuration !== null) {
358 if (opt_cpuDuration != '') {
359 this.appendTableCellWithTooltip_(table, row, cellNum,
360 tracing.analysis.tsRound(opt_cpuDuration), tooltip);
362 this.appendTableCell_(table, row, cellNum, '');
367 if (opt_selfTime !== null) {
369 this.appendTableCellWithTooltip_(table, row, cellNum,
370 tracing.analysis.tsRound(opt_selfTime), tooltip);
372 this.appendTableCell_(table, row, cellNum, '');
377 if (opt_cpuSelfTime !== null) {
378 if (opt_cpuSelfTime) {
379 this.appendTableCellWithTooltip_(table, row, cellNum,
380 tracing.analysis.tsRound(opt_cpuSelfTime), tooltip);
382 this.appendTableCell_(table, row, cellNum, '');
387 if (opt_percentage !== null) {
388 if (opt_percentage) {
389 this.appendTableCellWithTooltip_(table, row, cellNum,
390 opt_percentage, tooltip);
392 this.appendTableCell_(table, row, cellNum, '');
397 if (opt_occurences) {
398 this.appendTableCellWithTooltip_(table, row, cellNum,
399 String(opt_occurences), tooltip);
401 this.appendTableCell_(table, row, cellNum, '');
407 AnalysisResults: AnalysisResults