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> samples, 36 <span id="hadnans"><span id="nnans"></span> non-numeric samples, 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