Index: chrome/browser/resources/tracing/timeline_analysis.js |
diff --git a/chrome/browser/resources/tracing/timeline_analysis.js b/chrome/browser/resources/tracing/timeline_analysis.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a59a631d800a7a879c40d4d7fd44db54447570d2 |
--- /dev/null |
+++ b/chrome/browser/resources/tracing/timeline_analysis.js |
@@ -0,0 +1,160 @@ |
+// 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, |
+ }; |
+}); |