OLD | NEW |
(Empty) | |
| 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 }); |
OLD | NEW |