histogram_span.html revision cef7893435aa41160dd1255c43cb8498279738cc
1<!DOCTYPE html>
2<!--
3Copyright (c) 2015 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/base/statistics.html">
9<link rel="import" href="/tracing/ui/base/bar_chart.html">
10<link rel="import" href="/tracing/value/ui/scalar_span.html">
11
12<polymer-element name="tr-v-ui-histogram-span">
13  <template>
14    <style>
15      :host {
16        display: flex;
17        flex-direction: column;
18      }
19
20      #stats {
21        display: flex;
22        flex-direction: row;
23        flex: 0 0 auto;
24        font-weight: bold;
25      }
26
27      #nnans {
28        color: red;
29      }
30      #table {
31        flex: 1 1 auto;
32      }
33    </style>
34    <div id="stats">
35      <span id="nsamples"></span>&nbsp;samples,&nbsp;
36      <span id="hadnans"><span id="nnans"></span> non-numeric samples,&nbsp;
37      </span>
38      average=<tr-v-ui-scalar-span id="average"></tr-v-ui-scalar-span>
39    </div>
40    <div id="container"></div>
41  </template>
42  <script>
43  'use strict';
44
45  Polymer({
46    created: function() {
47      this.histogram_ = undefined;
48      this.chart_ = new tr.ui.b.BarChart();
49      this.chart_.width = 400;
50      this.chart_.height = 200;
51      this.mouseDownBin_ = undefined;
52      this.brushedBins_ = [];
53      this.chart_.addEventListener('item-mousedown',
54          this.onMouseDown_.bind(this));
55      this.chart_.addEventListener('item-mousemove',
56          this.onMouseMove_.bind(this));
57      this.chart_.addEventListener('item-mouseup',
58          this.onMouseUp_.bind(this));
59    },
60
61    ready: function() {
62      this.$.container.appendChild(this.chart_);
63    },
64
65    get brushedBins() {
66      return this.brushedBins_;
67    },
68
69    updateBrushedRange_: function(currentX) {
70      this.brushedBins_ = [this.histogram_.getBinForValue(currentX)];
71      var r = new tr.b.Range();
72      r.addValue(this.mouseDownX_);
73      r.addValue(currentX);
74
75      // Collect bins:
76      var centralMin = Number.MAX_VALUE;
77      var centralMax = -Number.MAX_VALUE;
78      this.histogram_.centralBins.forEach(function(bin) {
79        centralMin = Math.min(centralMin, bin.range.min);
80        centralMax = Math.max(centralMax, bin.range.max);
81        if ((bin.range.max > r.min) &&
82            (bin.range.min < r.max) &&
83            (this.brushedBins_.indexOf(bin) < 0))
84          this.brushedBins_.push(bin);
85      }, this);
86      if ((this.histogram_.underflowBin.max > r.min) &&
87          (this.brushedBins_.indexOf(this.histogram_.underflowBin) < 0)) {
88        this.brushedBins_.push(this.histogram_.underflowBin);
89      }
90      if ((this.histogram_.overflowBin.min < r.max) &&
91          (this.brushedBins_.indexOf(this.histogram_.overflowBin) < 0)) {
92        this.brushedBins_.push(this.histogram_.overflowBin);
93      }
94      this.brushedBins_.sort(function(a, b) {
95        return a.range.min - b.range.min;
96      });
97
98      // Prevent Infinity:
99      var minBin = this.histogram_.getBinForValue(r.min);
100      var maxBin = this.histogram_.getBinForValue(r.max);
101      var binWidth = this.histogram_.centralBins[0].range.range;
102      r.min = minBin ? Math.max(centralMin - binWidth, minBin.range.min) :
103        centralMin - binWidth;
104      r.max = maxBin ? Math.min(centralMax + binWidth, maxBin.range.max) :
105        centralMax + binWidth;
106
107      this.chart_.brushedRange = r;
108
109      this.dispatchEvent(new tr.b.Event('brushed-bins-changed'));
110    },
111
112    onMouseDown_: function(chartEvent) {
113      chartEvent.stopPropagation();
114      if (!this.histogram_)
115        return;
116      this.mouseDownX_ = chartEvent.x;
117      this.updateBrushedRange_(chartEvent.x);
118    },
119
120    onMouseMove_: function(chartEvent) {
121      chartEvent.stopPropagation();
122      if (!this.histogram_)
123        return;
124      this.updateBrushedRange_(chartEvent.x);
125    },
126
127    onMouseUp_: function(chartEvent) {
128      chartEvent.stopPropagation();
129      if (!this.histogram_)
130        return;
131      this.updateBrushedRange_(chartEvent.x);
132      this.mouseDownX_ = undefined;
133    },
134
135    get histogram() {
136      return this.histogram_;
137    },
138
139    set histogram(histogram) {
140      this.histogram_ = histogram;
141      this.updateContents_();
142    },
143
144    set isYLogScale(logScale) {
145      this.chart_.isYLogScale = logScale;
146    },
147
148    updateContents_: function() {
149      this.$.container.style.display = this.histogram_ ? '' : 'none';
150      if (!this.histogram_) {
151        this.$.nsamples.textContent = 0;
152        this.$.average.setValueAndUnit(undefined, undefined);
153        return;
154      }
155
156      this.$.nsamples.textContent = this.histogram_.numValues;
157      this.$.average.setValueAndUnit(this.histogram_.average,
158                                     this.histogram_.unit);
159      if (this.histogram_.numNans > 0) {
160        this.$.hadnans.style.display = '';
161        this.$.nnans.textContent = this.histogram_.numNans;
162      } else {
163        this.$.hadnans.style.display = 'none';
164      }
165
166      var maximumBinValue = tr.b.Statistics.max(this.histogram_.allBins,
167                                                function(bin) {
168                                                  return bin.count;
169                                                });
170      var chartData = [];
171      var binWidth = this.histogram_.centralBins[0].range.range;
172      this.histogram_.allBins.forEach(function(bin) {
173        var x = bin.range.min;
174        if (x === -Number.MAX_VALUE) {
175          if (!bin.count)
176            return;
177          x = bin.range.max - binWidth;
178        }
179        chartData.push({x: x,
180                        y: bin.count});
181      });
182      chartData.sort(function(x, y) {
183        return x.x - y.x;
184      });
185      this.$.container.style.display = chartData.length ? '' : 'none';
186      this.chart_.data = chartData;
187      this.brushedBins_ = [];
188      this.chart_.brushedRange = new tr.b.Range();
189    }
190  });
191  </script>
192</polymer-element>
193