Home | History | Annotate | Download | only in analysis
      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 
      7 base.requireStylesheet('tracing.analysis.analysis_results');
      8 
      9 base.require('tracing.analysis.util');
     10 base.require('tracing.analysis.analysis_link');
     11 base.require('tracing.analysis.generic_object_view');
     12 base.require('ui');
     13 
     14 base.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