| <!DOCTYPE html> |
| <!-- |
| Copyright (c) 2013 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. |
| --> |
| |
| <link rel="import" href="/tracing/base/base.html"> |
| <link rel="import" href="/tracing/ui/analysis/analysis_sub_view.html"> |
| <link rel="import" href="/tracing/ui/analysis/multi_event_summary_table.html"> |
| <link rel="import" href="/tracing/ui/analysis/selection_summary_table.html"> |
| <link rel="import" href="/tracing/ui/base/radio_picker.html"> |
| <link rel="import" href="/tracing/ui/base/table.html"> |
| <link rel="import" href="/tracing/ui/base/ui.html"> |
| <link rel="import" href="/tracing/value/diagnostics/scalar.html"> |
| <link rel="import" href="/tracing/value/histogram.html"> |
| <link rel="import" href="/tracing/value/ui/histogram_span.html"> |
| |
| <dom-module id='tr-ui-a-multi-event-sub-view'> |
| <template> |
| <style> |
| :host { |
| display: flex; |
| overflow: auto; |
| } |
| #content { |
| display: flex; |
| flex-direction: column; |
| flex: 0 1 auto; |
| align-self: stretch; |
| } |
| #content > * { |
| flex: 0 0 auto; |
| align-self: stretch; |
| } |
| #histogramContainer { |
| display: flex; |
| } |
| |
| tr-ui-a-multi-event-summary-table { |
| border-bottom: 1px solid #aaa; |
| } |
| |
| tr-ui-a-selection-summary-table { |
| margin-top: 1.25em; |
| border-top: 1px solid #aaa; |
| background-color: #eee; |
| font-weight: bold; |
| margin-bottom: 1.25em; |
| border-bottom: 1px solid #aaa; |
| } |
| </style> |
| <div id="content"> |
| <tr-ui-a-multi-event-summary-table id="eventSummaryTable"> |
| </tr-ui-a-multi-event-summary-table> |
| <tr-ui-a-selection-summary-table id="selectionSummaryTable"> |
| </tr-ui-a-selection-summary-table> |
| <tr-ui-b-radio-picker id="radioPicker"> |
| </tr-ui-b-radio-picker> |
| <div id="histogramContainer"> |
| <tr-v-ui-histogram-span id="histogramSpan"> |
| </tr-v-ui-histogram-span> |
| </div> |
| </div> |
| </template> |
| </dom-module> |
| <script> |
| 'use strict'; |
| |
| tr.exportTo('tr.ui.analysis', function() { |
| var EVENT_FIELD = [ |
| {key: 'start', label: 'Start'}, |
| {key: 'cpuDuration', label: 'CPU Duration'}, |
| {key: 'duration', label: 'Duration'}, |
| {key: 'cpuSelfTime', label: 'CPU Self Time'}, |
| {key: 'selfTime', label: 'Self Time'} |
| ]; |
| |
| function buildDiagnostics_(slice) { |
| var diagnostics = {}; |
| for (var item of EVENT_FIELD) { |
| var fieldName = item.key; |
| if (slice[fieldName] === undefined) |
| continue; |
| diagnostics[fieldName] = new tr.v.d.Scalar(new tr.b.Scalar( |
| tr.b.Unit.byName.timeDurationInMs, slice[fieldName])); |
| } |
| diagnostics['args'] = new tr.v.d.Generic(slice.args); |
| diagnostics['event'] = new tr.v.d.RelatedEventSet(slice); |
| return diagnostics; |
| } |
| |
| Polymer({ |
| is: 'tr-ui-a-multi-event-sub-view', |
| behaviors: [tr.ui.analysis.AnalysisSubView], |
| |
| created() { |
| this.currentSelection_ = undefined; |
| this.eventsHaveDuration_ = true; |
| this.eventsHaveSubRows_ = true; |
| }, |
| |
| ready() { |
| this.$.radioPicker.style.display = 'none'; |
| this.$.radioPicker.items = EVENT_FIELD; |
| this.$.radioPicker.select('cpuSelfTime'); |
| this.$.radioPicker.addEventListener('change', () => { |
| if (this.isAttached) this.updateContents_(); |
| }); |
| |
| this.$.histogramSpan.graphWidth = 400; |
| this.$.histogramSpan.canMergeSampleDiagnostics = false; |
| this.$.histogramContainer.style.display = 'none'; |
| }, |
| |
| attached() { |
| if (this.currentSelection_ !== undefined) this.updateContents_(); |
| }, |
| |
| set selection(selection) { |
| if (selection.length <= 1) |
| throw new Error('Only supports multiple items'); |
| this.setSelectionWithoutErrorChecks(selection); |
| }, |
| |
| get selection() { |
| return this.currentSelection_; |
| }, |
| |
| setSelectionWithoutErrorChecks(selection) { |
| this.currentSelection_ = selection; |
| if (this.isAttached) this.updateContents_(); |
| }, |
| |
| get eventsHaveDuration() { |
| return this.eventsHaveDuration_; |
| }, |
| |
| set eventsHaveDuration(eventsHaveDuration) { |
| this.eventsHaveDuration_ = eventsHaveDuration; |
| if (this.isAttached) this.updateContents_(); |
| }, |
| |
| get eventsHaveSubRows() { |
| return this.eventsHaveSubRows_; |
| }, |
| |
| set eventsHaveSubRows(eventsHaveSubRows) { |
| this.eventsHaveSubRows_ = eventsHaveSubRows; |
| if (this.isAttached) this.updateContents_(); |
| }, |
| |
| buildHistogram_(selectedKey) { |
| var leftBoundary = Number.MAX_VALUE; |
| var rightBoundary = tr.b.math.Statistics.percentile( |
| this.currentSelection_, 0.95, |
| function(value) { |
| leftBoundary = Math.min(leftBoundary, value[selectedKey]); |
| return value[selectedKey]; |
| }); |
| |
| if (leftBoundary === rightBoundary) rightBoundary += 1; |
| var histogram = new tr.v.Histogram( |
| '', |
| tr.b.Unit.byName.timeDurationInMs, |
| tr.v.HistogramBinBoundaries.createLinear( |
| leftBoundary, rightBoundary, |
| Math.ceil(Math.sqrt(this.currentSelection_.length)))); |
| histogram.customizeSummaryOptions({sum: false}); |
| for (var slice of this.currentSelection_) { |
| histogram.addSample(slice[selectedKey], |
| buildDiagnostics_(slice)); |
| } |
| |
| return histogram; |
| }, |
| |
| updateContents_() { |
| var selection = this.currentSelection_; |
| if (!selection) return; |
| |
| var eventsByTitle = selection.getEventsOrganizedByTitle(); |
| var numTitles = tr.b.dictionaryLength(eventsByTitle); |
| |
| this.$.eventSummaryTable.configure({ |
| showTotals: numTitles > 1, |
| eventsByTitle: eventsByTitle, |
| eventsHaveDuration: this.eventsHaveDuration_, |
| eventsHaveSubRows: this.eventsHaveSubRows_ |
| }); |
| |
| this.$.selectionSummaryTable.selection = this.currentSelection_; |
| |
| if (numTitles === 1) { |
| this.$.radioPicker.style.display = 'block'; |
| this.$.histogramContainer.style.display = 'flex'; |
| this.$.histogramSpan.histogram = |
| this.buildHistogram_(this.$.radioPicker.selectedKey); |
| if (this.$.histogramSpan.histogram.numValues === 0) { |
| this.$.histogramContainer.style.display = 'none'; |
| } |
| } else { |
| this.$.radioPicker.style.display = 'none'; |
| this.$.histogramContainer.style.display = 'none'; |
| } |
| } |
| }); |
| |
| return {}; |
| }); |
| </script> |