Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: tracing/tracing/ui/base/bar_chart.html

Issue 2162963002: [polymer] Merge of master into polymer10-migration (Closed) Base URL: git@github.com:catapult-project/catapult.git@polymer10-migration
Patch Set: Sync to head Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <!-- 2 <!--
3 Copyright (c) 2014 The Chromium Authors. All rights reserved. 3 Copyright (c) 2014 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be 4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file. 5 found in the LICENSE file.
6 --> 6 -->
7 7
8 <link rel="import" href="/tracing/ui/base/chart_base_2d_brushable_x.html"> 8 <link rel="import" href="/tracing/ui/base/chart_base_2d_brushable_x.html">
9 9
10 <script> 10 <script>
11 'use strict'; 11 'use strict';
12 12
13 tr.exportTo('tr.ui.b', function() { 13 tr.exportTo('tr.ui.b', function() {
14 var ColorScheme = tr.b.ColorScheme; 14 var ColorScheme = tr.b.ColorScheme;
15 var ChartBase2DBrushX = tr.ui.b.ChartBase2DBrushX; 15 var ChartBase2DBrushX = tr.ui.b.ChartBase2DBrushX;
16 var getColorOfKey = tr.ui.b.getColorOfKey; 16 var getColorOfKey = tr.ui.b.getColorOfKey;
17 17
18 // @constructor 18 // @constructor
19 var BarChart = tr.ui.b.define('bar-chart', ChartBase2DBrushX); 19 var BarChart = tr.ui.b.define('bar-chart', ChartBase2DBrushX);
20 20
21 BarChart.prototype = { 21 BarChart.prototype = {
22 __proto__: ChartBase2DBrushX.prototype, 22 __proto__: ChartBase2DBrushX.prototype,
23 23
24 decorate: function() { 24 decorate: function() {
25 ChartBase2DBrushX.prototype.decorate.call(this); 25 ChartBase2DBrushX.prototype.decorate.call(this);
26 Polymer.dom(this).classList.add('bar-chart'); 26 Polymer.dom(this).classList.add('bar-chart');
27 this.xCushion_ = 0; 27
28 // BarChart allows bars to have arbitrary, non-uniform widths. Bars need
29 // not all be the same width. The width of each bar is automatically
30 // computed from the bar's x-coordinate and that of the next bar, which
31 // can not define the width of the last bar. This is the width (in the
32 // xScale's domain (as opposed to the xScale's range (which is measured in
33 // pixels))) of the last bar. When there are at least 2 bars, this is
34 // computed as the average width of the bars. When there is a single bar,
35 // this must default to a non-zero number so that the width of the only
36 // bar will not be zero.
37 this.xCushion_ = 1;
38
39 this.isStacked_ = false;
40 },
41
42 set isStacked(stacked) {
43 this.isStacked_ = true;
44 this.updateContents_();
45 },
46
47 get isStacked() {
48 return this.isStacked_;
28 }, 49 },
29 50
30 isDatumFieldSeries_: function(fieldName) { 51 isDatumFieldSeries_: function(fieldName) {
31 return fieldName != 'x'; 52 return fieldName != 'x';
32 }, 53 },
33 54
34 getXForDatum_: function(datum, index) { 55 getXForDatum_: function(datum, index) {
35 return datum.x; 56 return datum.x;
36 }, 57 },
37 58
38 updateScales_: function() { 59 updateScales_: function() {
39 if (this.data_.length === 0) 60 if (this.data_.length === 0)
40 return; 61 return;
41 62
42 var xDifferences = 0; 63 var xDifferences = 0;
43 var currentX = undefined; 64 var currentX = undefined;
44 var previousX = undefined; 65 var previousX = undefined;
45 var yRange = new tr.b.Range(); 66 var yRange = new tr.b.Range();
46 this.data_.forEach(function(datum, index) { 67 this.data_.forEach(function(datum, index) {
47 previousX = currentX; 68 previousX = currentX;
48 currentX = this.getXForDatum_(datum, index); 69 currentX = this.getXForDatum_(datum, index);
49 if (previousX !== undefined) { 70 if (previousX !== undefined) {
50 xDifferences += currentX - previousX; 71 xDifferences += currentX - previousX;
51 } 72 }
52 73
53 this.seriesKeys_.forEach(function(key) { 74 for (var [key, series] of this.seriesByKey_) {
54 // Allow for sparse data 75 // Allow for sparse data
55 if (datum[key] !== undefined) 76 if (datum[key] !== undefined)
56 yRange.addValue(datum[key]); 77 yRange.addValue(datum[key]);
57 }); 78 }
58 }, this); 79 }, this);
59 80
60 // X. 81 // X.
61 // Leave a cushion on the right so that the last rect doesn't 82 // Leave a cushion on the right so that the last rect doesn't
62 // exceed the chart boundaries. The last rect's width is set to the 83 // exceed the chart boundaries. The last rect's width is set to the
63 // average width of the rects, which is chart.width / data.length. 84 // average width of the rects, which is chart.width / data.length.
64 var width = this.chartAreaSize.width; 85 var width = this.chartAreaSize.width;
65 this.xScale_.range([0, width]); 86 this.xScale_.range([0, width]);
66 var domain = d3.extent(this.data_, this.getXForDatum_.bind(this)); 87 var domain = d3.extent(this.data_, this.getXForDatum_.bind(this));
67 this.xCushion_ = xDifferences / (this.data_.length - 1); 88 if (this.data_.length > 1)
89 this.xCushion_ = xDifferences / (this.data_.length - 1);
68 this.xScale_.domain([domain[0], domain[1] + this.xCushion_]); 90 this.xScale_.domain([domain[0], domain[1] + this.xCushion_]);
69 91
70 // Y. 92 // Y.
71 this.yScale_.range([this.chartAreaSize.height, 0]); 93 this.yScale_.range([this.chartAreaSize.height, 0]);
72 this.yScale_.domain(this.getYScaleDomain_(yRange.min, yRange.max)); 94 this.yScale_.domain(this.getYScaleDomain_(yRange.min, yRange.max));
73 }, 95 },
74 96
97 getYScaleDomain_: function(minValue, maxValue) {
98 if (!this.isStacked) {
99 return ChartBase2DBrushX.prototype.getYScaleDomain_.call(
100 this, minValue, maxValue);
101 }
102
103 var range = new tr.b.Range();
104 range.addValue(0);
105 this.data_.forEach(function(datum, index) {
106 var sum = 0;
107 for (var [key, series] of this.seriesByKey_) {
108 if (datum[key] === undefined)
109 continue;
110 sum += datum[key];
111 }
112 range.addValue(sum);
113 }, this);
114 return [range.min, range.max];
115 },
116
117 getStackedRectsForDatum_: function(datum, index) {
118 var stacks = [];
119 var bottom = this.yScale_.range()[0];
120 var sum = 0;
121 for (var [key, series] of this.seriesByKey_) {
122 if (datum[key] === undefined || !this.isSeriesEnabled(key))
123 continue;
124 sum += datum[key];
125 var heightPx = bottom - this.yScale_(sum);
126 bottom -= heightPx;
127 stacks.push({
128 key: key,
129 value: datum[key],
130 color: getColorOfKey(key),
131 heightPx: heightPx,
132 topPx: bottom
133 });
134 }
135 return stacks;
136 },
137
138 getRectsForDatum_: function(datum, index) {
139 if (this.isStacked)
140 return this.getStackedRectsForDatum_(datum, index);
141
142 var stacks = [];
143 for (var [key, series] of this.seriesByKey_) {
144 if (datum[key] === undefined || !this.isSeriesEnabled(key))
145 continue;
146 var topPx = this.yScale_(Math.max(datum[key], this.getYScaleMin_()));
147 stacks.push({
148 key: key,
149 value: datum[key],
150 topPx: topPx,
151 heightPx: this.yScale_.range()[0] - topPx,
152 color: getColorOfKey(key)
153 });
154 }
155 stacks.sort(function(a, b) {
156 return b.topPx - a.topPx;
157 });
158 return stacks;
159 },
160
75 updateDataContents_: function(dataSel) { 161 updateDataContents_: function(dataSel) {
76 dataSel.selectAll('*').remove(); 162 dataSel.selectAll('*').remove();
77 var rectsSel = dataSel.selectAll('path').data(this.seriesKeys_); 163 var chartAreaSel = d3.select(this.chartAreaElement);
164 var rectsSel = dataSel.selectAll('path').data(
165 [...this.seriesByKey_.keys()]);
78 this.data_.forEach(function(datum, index) { 166 this.data_.forEach(function(datum, index) {
79 var currentX = this.getXForDatum_(datum, index); 167 var currentX = this.getXForDatum_(datum, index);
80 var width = undefined; 168 var width = undefined;
81 if (index < (this.data_.length - 1)) { 169 if (index < (this.data_.length - 1)) {
82 var nextX = this.getXForDatum_(this.data_[index + 1], index + 1); 170 var nextX = this.getXForDatum_(this.data_[index + 1], index + 1);
83 width = nextX - currentX; 171 width = nextX - currentX;
84 } else { 172 } else {
85 width = this.xCushion_; 173 width = this.xCushion_;
86 } 174 }
87 175 this.getRectsForDatum_(datum, index).forEach(function(rect) {
88 var stacks = []; 176 var leftPx = this.xScale_(currentX);
89 this.seriesKeys_.forEach(function(key) { 177 var rightPx = this.xScale_(currentX + width);
90 if (datum[key] !== undefined) 178 var widthPx = rightPx - leftPx;
91 stacks.push({y: datum[key], color: getColorOfKey(key)});
92 });
93 stacks.sort(function(a, b) {
94 return b.y - a.y;
95 });
96
97 stacks.forEach(function(stack) {
98 var left = this.xScale_(currentX);
99 var right = this.xScale_(currentX + width);
100 var widthPx = right - left;
101 var top = this.yScale_(Math.max(stack.y, this.getYScaleMin_()));
102 rectsSel.enter() 179 rectsSel.enter()
103 .append('rect') 180 .append('rect')
104 .attr('fill', stack.color) 181 .attr('fill', rect.color)
105 .attr('x', left) 182 .attr('x', leftPx)
106 .attr('y', top) 183 .attr('y', rect.topPx)
107 .attr('width', widthPx) 184 .attr('width', widthPx)
108 .attr('height', this.yScale_.range()[0] - top); 185 .attr('height', rect.heightPx)
186 .on('mouseenter', function() {
187 chartAreaSel.selectAll('.hover').remove();
188 chartAreaSel
189 .append('rect')
190 .attr('class', 'hover')
191 .attr('fill', 'white')
192 .attr('x', leftPx + widthPx)
193 .attr('y', rect.topPx)
194 .attr('width', this.margin.right)
195 .attr('height', 30);
196 chartAreaSel
197 .append('text')
198 .attr('class', 'hover')
199 .attr('fill', rect.color)
200 .attr('x', leftPx + widthPx + 2)
201 .attr('y', rect.topPx + 10)
202 .text(rect.key);
203 chartAreaSel
204 .append('text')
205 .attr('class', 'hover')
206 .attr('fill', rect.color)
207 .attr('x', leftPx + widthPx + 2)
208 .attr('y', rect.topPx + 25)
209 .text(rect.value);
210 }.bind(this))
211 .on('mouseleave', function() {
212 chartAreaSel.selectAll('.hover').remove();
213 }.bind(this));
109 }, this); 214 }, this);
110 }, this); 215 }, this);
111 rectsSel.exit().remove(); 216 rectsSel.exit().remove();
112 } 217 }
113 }; 218 };
114 219
115 return { 220 return {
116 BarChart: BarChart 221 BarChart: BarChart
117 }; 222 };
118 }); 223 });
119 </script> 224 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698