blob: 84a7f22dc8ce575f669904f518d9a4087286b442 [file] [log] [blame]
// Copyright (c) 2011 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.
/**
* @fileoverview TimelineView visualizes TRACE_EVENT events using the
* tracing.Timeline component.
*/
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;
}
/**
* TimelineView
* @constructor
* @extends {HTMLDivElement}
*/
TimelineView = cr.ui.define('div');
TimelineView.prototype = {
__proto__: HTMLDivElement.prototype,
decorate: function() {
this.classList.add('timeline-view');
this.timelineContainer_ = document.createElement('div');
this.timelineContainer_.className = 'timeline-container';
var summaryContainer_ = document.createElement('div');
summaryContainer_.className = 'summary-container';
this.summaryEl_ = document.createElement('pre');
this.summaryEl_.className = 'summary';
summaryContainer_.appendChild(this.summaryEl_);
this.appendChild(this.timelineContainer_);
this.appendChild(summaryContainer_);
this.onSelectionChangedBoundToThis_ = this.onSelectionChanged_.bind(this);
},
set traceData(traceData) {
this.model = new tracing.TimelineModel(traceData);
},
get model(model) {
return this.timelineModel_;
},
set model(model) {
this.timelineModel_ = model;
// remove old timeline
this.timelineContainer_.textContent = '';
// create new timeline if needed
if (this.timelineModel_.minTimestamp !== undefined) {
if (this.timeline_)
this.timeline_.detach();
this.timeline_ = new tracing.Timeline();
this.timeline_.model = this.timelineModel_;
this.timeline_.focusElement = this.parentElement;
this.timelineContainer_.appendChild(this.timeline_);
this.timeline_.addEventListener('selectionChange',
this.onSelectionChangedBoundToThis_);
this.onSelectionChanged_();
} else {
this.timeline_ = null;
}
},
get timeline() {
return this.timeline_;
},
onSelectionChanged_: function(e) {
var timeline = this.timeline_;
var selection = timeline.selection;
if (!selection.length) {
var oldScrollTop = this.timelineContainer_.scrollTop;
this.summaryEl_.textContent = timeline.keyHelp;
this.timelineContainer_.scrollTop = oldScrollTop;
return;
}
var text = '';
if (selection.length == 1) {
var c0Width = 14;
var slice = selection[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 {
var c0Width = 55;
var c1Width = 12;
var c2Width = 5;
text = 'Selection summary:\n';
var tsLo = Math.min.apply(Math, selection.map(
function(s) {return s.slice.start;}));
var tsHi = Math.max.apply(Math, selection.map(
function(s) {return s.slice.end;}));
// compute total selection duration
var titles = selection.map(function(i) { return i.slice.title; });
var slicesByTitle = {};
for (var i = 0; i < selection.length; i++) {
var slice = selection[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(selection.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';
}
// done
var oldScrollTop = this.timelineContainer_.scrollTop;
this.summaryEl_.textContent = text;
this.timelineContainer_.scrollTop = oldScrollTop;
}
};
return {
TimelineView: TimelineView
};
});