Javascript  |  161行  |  4.85 KB

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

/**
 * @fileoverview TimelineView visualizes TRACE_EVENT events using the
 * tracing.Timeline component and adds in selection summary and control buttons.
 */
cr.define('tracing', function() {
  function tsRound(ts) {
    return Math.round(ts * 1000.0) / 1000.0;
  }

  function getPadding(text, width) {
    width = width || 0;

    if (typeof text != 'string')
      text = String(text);

    if (text.length >= width)
      return '';

    var pad = '';
    for (var i = 0; i < width - text.length; i++)
      pad += ' ';
    return pad;
  }

  function leftAlign(text, width) {
    return text + getPadding(text, width);
  }

  function rightAlign(text, width) {
    return getPadding(text, width) + text;
  }


  function getTextForSelection(selection) {
    var text = '';
    var sliceHits = selection.getSliceHits();
    var counterSampleHits = selection.getCounterSampleHits();

    if (sliceHits.length == 1) {
      var c0Width = 14;
      var slice = sliceHits[0].slice;
      text = 'Selected item:\n';
      text += leftAlign('Title', c0Width) + ': ' + slice.title + '\n';
      text += leftAlign('Start', c0Width) + ': ' +
          tsRound(slice.start) + ' ms\n';
      text += leftAlign('Duration', c0Width) + ': ' +
          tsRound(slice.duration) + ' ms\n';
      if (slice.durationInUserTime)
        text += leftAlign('Duration (U)', c0Width) + ': ' +
            tsRound(slice.durationInUserTime) + ' ms\n';

      var n = 0;
      for (var argName in slice.args) {
        n += 1;
      }
      if (n > 0) {
        text += leftAlign('Args', c0Width) + ':\n';
        for (var argName in slice.args) {
          var argVal = slice.args[argName];
          text += leftAlign(' ' + argName, c0Width) + ': ' + argVal + '\n';
        }
      }
    } else if (sliceHits.length > 1) {
      var c0Width = 55;
      var c1Width = 12;
      var c2Width = 5;
      text = 'Slices:\n';
      var tsLo = sliceHits.range.min;
      var tsHi = sliceHits.range.max;

      // compute total sliceHits duration
      var titles = sliceHits.map(function(i) { return i.slice.title; });

      var slicesByTitle = {};
      for (var i = 0; i < sliceHits.length; i++) {
        var slice = sliceHits[i].slice;
        if (!slicesByTitle[slice.title])
          slicesByTitle[slice.title] = {
            slices: []
          };
        slicesByTitle[slice.title].slices.push(slice);
      }
      var totalDuration = 0;
      for (var sliceGroupTitle in slicesByTitle) {
        var sliceGroup = slicesByTitle[sliceGroupTitle];
        var duration = 0;
        for (i = 0; i < sliceGroup.slices.length; i++)
          duration += sliceGroup.slices[i].duration;
        totalDuration += duration;

        text += ' ' +
            leftAlign(sliceGroupTitle, c0Width) + ': ' +
            rightAlign(tsRound(duration) + 'ms', c1Width) + '   ' +
            rightAlign(String(sliceGroup.slices.length), c2Width) +
            ' occurrences' + '\n';
      }

      text += leftAlign('*Totals', c0Width) + ' : ' +
          rightAlign(tsRound(totalDuration) + 'ms', c1Width) + '   ' +
          rightAlign(String(sliceHits.length), c2Width) + ' occurrences' +
          '\n';

      text += '\n';

      text += leftAlign('Selection start', c0Width) + ' : ' +
          rightAlign(tsRound(tsLo) + 'ms', c1Width) +
          '\n';
      text += leftAlign('Selection extent', c0Width) + ' : ' +
          rightAlign(tsRound(tsHi - tsLo) + 'ms', c1Width) +
          '\n';
    }

    if (counterSampleHits.length == 1) {
      text = 'Selected counter:\n';
      var c0Width = 55;
      var hit = counterSampleHits[0];
      var ctr = hit.counter;
      var sampleIndex = hit.sampleIndex;
      var values = [];
      for (var i = 0; i < ctr.numSeries; ++i)
        values.push(ctr.samples[ctr.numSeries * sampleIndex + i]);
      text += leftAlign('Title', c0Width) + ': ' + ctr.name + '\n';
      text += leftAlign('Timestamp', c0Width) + ': ' +
        tsRound(ctr.timestamps[sampleIndex]) + ' ms\n';
      if (ctr.numSeries > 1)
        text += leftAlign('Values', c0Width) + ': ' + values.join('\n') + '\n';
      else
        text += leftAlign('Value', c0Width) + ': ' + values.join('\n') + '\n';

    } else if (counterSampleHits.length > 1 && sliceHits.length == 0) {
      text += 'Analysis of multiple counters not yet implemented. ' +
          'Pick a single counter.';
    }
    return text;
  }

  var TimelineAnalysisView = cr.ui.define('div');

  TimelineAnalysisView.prototype = {
    __proto__: HTMLDivElement.prototype,

    decorate: function() {
      this.className = 'timeline-analysis';
    },

    set selection(selection) {
      this.textContent = getTextForSelection(selection);
    }
  };

  return {
    TimelineAnalysisView: TimelineAnalysisView,
  };
});