Home | History | Annotate | Download | only in tracing
      1 // Copyright (c) 2012 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 /**
      8  * @fileoverview TimelineView visualizes TRACE_EVENT events using the
      9  * tracing.Timeline component and adds in selection summary and control buttons.
     10  */
     11 cr.define('tracing', function() {
     12   function tsRound(ts) {
     13     return Math.round(ts * 1000.0) / 1000.0;
     14   }
     15 
     16   function getPadding(text, width) {
     17     width = width || 0;
     18 
     19     if (typeof text != 'string')
     20       text = String(text);
     21 
     22     if (text.length >= width)
     23       return '';
     24 
     25     var pad = '';
     26     for (var i = 0; i < width - text.length; i++)
     27       pad += ' ';
     28     return pad;
     29   }
     30 
     31   function leftAlign(text, width) {
     32     return text + getPadding(text, width);
     33   }
     34 
     35   function rightAlign(text, width) {
     36     return getPadding(text, width) + text;
     37   }
     38 
     39 
     40   function getTextForSelection(selection) {
     41     var text = '';
     42     var sliceHits = selection.getSliceHits();
     43     var counterSampleHits = selection.getCounterSampleHits();
     44 
     45     if (sliceHits.length == 1) {
     46       var c0Width = 14;
     47       var slice = sliceHits[0].slice;
     48       text = 'Selected item:\n';
     49       text += leftAlign('Title', c0Width) + ': ' + slice.title + '\n';
     50       text += leftAlign('Start', c0Width) + ': ' +
     51           tsRound(slice.start) + ' ms\n';
     52       text += leftAlign('Duration', c0Width) + ': ' +
     53           tsRound(slice.duration) + ' ms\n';
     54       if (slice.durationInUserTime)
     55         text += leftAlign('Duration (U)', c0Width) + ': ' +
     56             tsRound(slice.durationInUserTime) + ' ms\n';
     57 
     58       var n = 0;
     59       for (var argName in slice.args) {
     60         n += 1;
     61       }
     62       if (n > 0) {
     63         text += leftAlign('Args', c0Width) + ':\n';
     64         for (var argName in slice.args) {
     65           var argVal = slice.args[argName];
     66           text += leftAlign(' ' + argName, c0Width) + ': ' + argVal + '\n';
     67         }
     68       }
     69     } else if (sliceHits.length > 1) {
     70       var c0Width = 55;
     71       var c1Width = 12;
     72       var c2Width = 5;
     73       text = 'Slices:\n';
     74       var tsLo = sliceHits.range.min;
     75       var tsHi = sliceHits.range.max;
     76 
     77       // compute total sliceHits duration
     78       var titles = sliceHits.map(function(i) { return i.slice.title; });
     79 
     80       var slicesByTitle = {};
     81       for (var i = 0; i < sliceHits.length; i++) {
     82         var slice = sliceHits[i].slice;
     83         if (!slicesByTitle[slice.title])
     84           slicesByTitle[slice.title] = {
     85             slices: []
     86           };
     87         slicesByTitle[slice.title].slices.push(slice);
     88       }
     89       var totalDuration = 0;
     90       for (var sliceGroupTitle in slicesByTitle) {
     91         var sliceGroup = slicesByTitle[sliceGroupTitle];
     92         var duration = 0;
     93         for (i = 0; i < sliceGroup.slices.length; i++)
     94           duration += sliceGroup.slices[i].duration;
     95         totalDuration += duration;
     96 
     97         text += ' ' +
     98             leftAlign(sliceGroupTitle, c0Width) + ': ' +
     99             rightAlign(tsRound(duration) + 'ms', c1Width) + '   ' +
    100             rightAlign(String(sliceGroup.slices.length), c2Width) +
    101             ' occurrences' + '\n';
    102       }
    103 
    104       text += leftAlign('*Totals', c0Width) + ' : ' +
    105           rightAlign(tsRound(totalDuration) + 'ms', c1Width) + '   ' +
    106           rightAlign(String(sliceHits.length), c2Width) + ' occurrences' +
    107           '\n';
    108 
    109       text += '\n';
    110 
    111       text += leftAlign('Selection start', c0Width) + ' : ' +
    112           rightAlign(tsRound(tsLo) + 'ms', c1Width) +
    113           '\n';
    114       text += leftAlign('Selection extent', c0Width) + ' : ' +
    115           rightAlign(tsRound(tsHi - tsLo) + 'ms', c1Width) +
    116           '\n';
    117     }
    118 
    119     if (counterSampleHits.length == 1) {
    120       text = 'Selected counter:\n';
    121       var c0Width = 55;
    122       var hit = counterSampleHits[0];
    123       var ctr = hit.counter;
    124       var sampleIndex = hit.sampleIndex;
    125       var values = [];
    126       for (var i = 0; i < ctr.numSeries; ++i)
    127         values.push(ctr.samples[ctr.numSeries * sampleIndex + i]);
    128       text += leftAlign('Title', c0Width) + ': ' + ctr.name + '\n';
    129       text += leftAlign('Timestamp', c0Width) + ': ' +
    130         tsRound(ctr.timestamps[sampleIndex]) + ' ms\n';
    131       if (ctr.numSeries > 1)
    132         text += leftAlign('Values', c0Width) + ': ' + values.join('\n') + '\n';
    133       else
    134         text += leftAlign('Value', c0Width) + ': ' + values.join('\n') + '\n';
    135 
    136     } else if (counterSampleHits.length > 1 && sliceHits.length == 0) {
    137       text += 'Analysis of multiple counters not yet implemented. ' +
    138           'Pick a single counter.';
    139     }
    140     return text;
    141   }
    142 
    143   var TimelineAnalysisView = cr.ui.define('div');
    144 
    145   TimelineAnalysisView.prototype = {
    146     __proto__: HTMLDivElement.prototype,
    147 
    148     decorate: function() {
    149       this.className = 'timeline-analysis';
    150     },
    151 
    152     set selection(selection) {
    153       this.textContent = getTextForSelection(selection);
    154     }
    155   };
    156 
    157   return {
    158     TimelineAnalysisView: TimelineAnalysisView,
    159   };
    160 });
    161