| <!DOCTYPE html> |
| <!-- |
| Copyright (c) 2015 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/statistics.html"> |
| <link rel="import" href="/tracing/ui/base/bar_chart.html"> |
| <link rel="import" href="/tracing/value/ui/scalar_span.html"> |
| |
| <polymer-element name="tr-v-ui-histogram-span"> |
| <template> |
| <style> |
| :host { |
| display: flex; |
| flex-direction: column; |
| } |
| |
| #stats { |
| display: flex; |
| flex-direction: row; |
| flex: 0 0 auto; |
| font-weight: bold; |
| } |
| |
| #nnans { |
| color: red; |
| } |
| #table { |
| flex: 1 1 auto; |
| } |
| </style> |
| <div id="stats"> |
| <span id="nsamples"></span> samples, |
| <span id="hadnans"><span id="nnans"></span> non-numeric samples, |
| </span> |
| average=<tr-v-ui-scalar-span id="average"></tr-v-ui-scalar-span> |
| </div> |
| <div id="container"></div> |
| </template> |
| <script> |
| 'use strict'; |
| |
| Polymer({ |
| created: function() { |
| this.histogram_ = undefined; |
| this.chart_ = new tr.ui.b.BarChart(); |
| this.chart_.width = 400; |
| this.chart_.height = 200; |
| this.mouseDownBin_ = undefined; |
| this.brushedBins_ = []; |
| this.chart_.addEventListener('item-mousedown', |
| this.onMouseDown_.bind(this)); |
| this.chart_.addEventListener('item-mousemove', |
| this.onMouseMove_.bind(this)); |
| this.chart_.addEventListener('item-mouseup', |
| this.onMouseUp_.bind(this)); |
| }, |
| |
| ready: function() { |
| this.$.container.appendChild(this.chart_); |
| }, |
| |
| get brushedBins() { |
| return this.brushedBins_; |
| }, |
| |
| updateBrushedRange_: function(currentX) { |
| this.brushedBins_ = [this.histogram_.getBinForValue(currentX)]; |
| var r = new tr.b.Range(); |
| r.addValue(this.mouseDownX_); |
| r.addValue(currentX); |
| |
| // Collect bins: |
| var centralMin = Number.MAX_VALUE; |
| var centralMax = -Number.MAX_VALUE; |
| this.histogram_.centralBins.forEach(function(bin) { |
| centralMin = Math.min(centralMin, bin.range.min); |
| centralMax = Math.max(centralMax, bin.range.max); |
| if ((bin.range.max > r.min) && |
| (bin.range.min < r.max) && |
| (this.brushedBins_.indexOf(bin) < 0)) |
| this.brushedBins_.push(bin); |
| }, this); |
| if ((this.histogram_.underflowBin.max > r.min) && |
| (this.brushedBins_.indexOf(this.histogram_.underflowBin) < 0)) { |
| this.brushedBins_.push(this.histogram_.underflowBin); |
| } |
| if ((this.histogram_.overflowBin.min < r.max) && |
| (this.brushedBins_.indexOf(this.histogram_.overflowBin) < 0)) { |
| this.brushedBins_.push(this.histogram_.overflowBin); |
| } |
| this.brushedBins_.sort(function(a, b) { |
| return a.range.min - b.range.min; |
| }); |
| |
| // Prevent Infinity: |
| var minBin = this.histogram_.getBinForValue(r.min); |
| var maxBin = this.histogram_.getBinForValue(r.max); |
| var binWidth = this.histogram_.centralBins[0].range.range; |
| r.min = minBin ? Math.max(centralMin - binWidth, minBin.range.min) : |
| centralMin - binWidth; |
| r.max = maxBin ? Math.min(centralMax + binWidth, maxBin.range.max) : |
| centralMax + binWidth; |
| |
| this.chart_.brushedRange = r; |
| |
| this.dispatchEvent(new tr.b.Event('brushed-bins-changed')); |
| }, |
| |
| onMouseDown_: function(chartEvent) { |
| chartEvent.stopPropagation(); |
| if (!this.histogram_) |
| return; |
| this.mouseDownX_ = chartEvent.x; |
| this.updateBrushedRange_(chartEvent.x); |
| }, |
| |
| onMouseMove_: function(chartEvent) { |
| chartEvent.stopPropagation(); |
| if (!this.histogram_) |
| return; |
| this.updateBrushedRange_(chartEvent.x); |
| }, |
| |
| onMouseUp_: function(chartEvent) { |
| chartEvent.stopPropagation(); |
| if (!this.histogram_) |
| return; |
| this.updateBrushedRange_(chartEvent.x); |
| this.mouseDownX_ = undefined; |
| }, |
| |
| get histogram() { |
| return this.histogram_; |
| }, |
| |
| set histogram(histogram) { |
| this.histogram_ = histogram; |
| this.updateContents_(); |
| }, |
| |
| set isYLogScale(logScale) { |
| this.chart_.isYLogScale = logScale; |
| }, |
| |
| updateContents_: function() { |
| this.$.container.style.display = this.histogram_ ? '' : 'none'; |
| if (!this.histogram_) { |
| this.$.nsamples.textContent = 0; |
| this.$.average.setValueAndUnit(undefined, undefined); |
| return; |
| } |
| |
| this.$.nsamples.textContent = this.histogram_.numValues; |
| this.$.average.setValueAndUnit(this.histogram_.average, |
| this.histogram_.unit); |
| if (this.histogram_.numNans > 0) { |
| this.$.hadnans.style.display = ''; |
| this.$.nnans.textContent = this.histogram_.numNans; |
| } else { |
| this.$.hadnans.style.display = 'none'; |
| } |
| |
| var maximumBinValue = tr.b.Statistics.max(this.histogram_.allBins, |
| function(bin) { |
| return bin.count; |
| }); |
| var chartData = []; |
| var binWidth = this.histogram_.centralBins[0].range.range; |
| this.histogram_.allBins.forEach(function(bin) { |
| var x = bin.range.min; |
| if (x === -Number.MAX_VALUE) { |
| if (!bin.count) |
| return; |
| x = bin.range.max - binWidth; |
| } |
| chartData.push({x: x, |
| y: bin.count}); |
| }); |
| chartData.sort(function(x, y) { |
| return x.x - y.x; |
| }); |
| this.$.container.style.display = chartData.length ? '' : 'none'; |
| this.chart_.data = chartData; |
| this.brushedBins_ = []; |
| this.chart_.brushedRange = new tr.b.Range(); |
| } |
| }); |
| </script> |
| </polymer-element> |