OLD | NEW |
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 <link rel="import" href="/tracing/base/range.html"> | 8 <link rel="import" href="/tracing/base/range.html"> |
8 <link rel="import" href="/tracing/ui/base/chart_base.html"> | 9 <link rel="import" href="/tracing/ui/base/chart_base.html"> |
9 <link rel="import" href="/tracing/ui/base/d3.html"> | 10 <link rel="import" href="/tracing/ui/base/d3.html"> |
10 <link rel="import" href="/tracing/ui/base/dom_helpers.html"> | 11 <link rel="import" href="/tracing/ui/base/dom_helpers.html"> |
11 <link rel="stylesheet" href="/tracing/ui/base/pie_chart.css"> | 12 <link rel="stylesheet" href="/tracing/ui/base/pie_chart.css"> |
12 | 13 |
13 <script> | 14 <script> |
14 'use strict'; | 15 'use strict'; |
15 | 16 |
16 tr.exportTo('tr.ui.b', function() { | 17 tr.exportTo('tr.ui.b', function() { |
17 var ChartBase = tr.ui.b.ChartBase; | 18 var ChartBase = tr.ui.b.ChartBase; |
18 var getColorOfKey = tr.ui.b.getColorOfKey; | 19 var getColorOfKey = tr.ui.b.getColorOfKey; |
19 | 20 |
20 var MIN_RADIUS = 100; | 21 var MIN_RADIUS = 100; |
21 | 22 |
22 /** | 23 /** |
23 * @constructor | 24 * @constructor |
24 */ | 25 */ |
25 var PieChart = tr.ui.b.define('pie-chart', ChartBase); | 26 var PieChart = tr.ui.b.define('pie-chart', ChartBase); |
26 | 27 |
27 PieChart.prototype = { | 28 PieChart.prototype = { |
28 __proto__: ChartBase.prototype, | 29 __proto__: ChartBase.prototype, |
29 | 30 |
30 decorate: function() { | 31 decorate: function() { |
31 ChartBase.prototype.decorate.call(this); | 32 ChartBase.prototype.decorate.call(this); |
32 Polymer.dom(this).classList.add('pie-chart'); | 33 Polymer.dom(this).classList.add('pie-chart'); |
33 | 34 |
34 this.data_ = undefined; | 35 this.data_ = undefined; |
35 this.seriesKeys_ = undefined; | |
36 | 36 |
37 var chartAreaSel = d3.select(this.chartAreaElement); | 37 var chartAreaSel = d3.select(this.chartAreaElement); |
38 var pieGroupSel = chartAreaSel.append('g') | 38 var pieGroupSel = chartAreaSel.append('g') |
39 .attr('class', 'pie-group'); | 39 .attr('class', 'pie-group'); |
40 this.pieGroup_ = pieGroupSel.node(); | 40 this.pieGroup_ = pieGroupSel.node(); |
41 | 41 |
42 this.pathsGroup_ = pieGroupSel.append('g') | 42 this.pathsGroup_ = pieGroupSel.append('g') |
43 .attr('class', 'paths') | 43 .attr('class', 'paths') |
44 .node(); | 44 .node(); |
45 this.labelsGroup_ = pieGroupSel.append('g') | 45 this.labelsGroup_ = pieGroupSel.append('g') |
46 .attr('class', 'labels') | 46 .attr('class', 'labels') |
47 .node(); | 47 .node(); |
48 this.linesGroup_ = pieGroupSel.append('g') | 48 this.linesGroup_ = pieGroupSel.append('g') |
49 .attr('class', 'lines') | 49 .attr('class', 'lines') |
50 .node(); | 50 .node(); |
51 }, | 51 }, |
52 | 52 |
53 get data() { | 53 get data() { |
54 return this.data_; | 54 return this.data_; |
55 }, | 55 }, |
56 | 56 |
| 57 get titleMarginPx() { |
| 58 return 40; |
| 59 }, |
57 | 60 |
58 /** | 61 /** |
59 * @param {Array} data Data for the chart, where each element in the array | 62 * @param {Array} data Data for the chart, where each element in the array |
60 * must be of the form {label: str, value: number}. | 63 * must be of the form {label: str, value: number}. |
61 */ | 64 */ |
62 set data(data) { | 65 set data(data) { |
63 if (data !== undefined) { | 66 if (data !== undefined) { |
64 // Figure out the label values in the data set. E.g. from | 67 // Figure out the label values in the data set. E.g. from |
65 // [{label: 'a', ...}, {label: 'b', ...}] | 68 // [{label: 'a', ...}, {label: 'b', ...}] |
66 // we would commpute ['a', 'y']. These become the series keys. | 69 // we would commpute ['a', 'y']. These become the series keys. |
67 var seriesKeys = []; | 70 // Don't clear seriesByKey_; the caller might have put state in it using |
| 71 // customizeLegendTargets, customizeOptionalSeries, or |
| 72 // customizeEnabledSeries before setting data. |
68 var seenSeriesKeys = {}; | 73 var seenSeriesKeys = {}; |
69 data.forEach(function(d) { | 74 data.forEach(function(d) { |
70 var k = d.label; | 75 var k = d.label; |
71 if (seenSeriesKeys[k]) | 76 if (seenSeriesKeys[k]) |
72 throw new Error('Label ' + k + ' has been used already'); | 77 throw new Error('Label ' + k + ' has been used already'); |
73 seriesKeys.push(k); | 78 this.getDataSeries(k); |
74 seenSeriesKeys[k] = true; | 79 seenSeriesKeys[k] = true; |
75 }, this); | 80 }, this); |
76 this.seriesKeys_ = seriesKeys; | |
77 } else { | |
78 this.seriesKeys_ = undefined; | |
79 } | 81 } |
80 this.data_ = data; | 82 this.data_ = data; |
81 this.updateContents_(); | 83 this.updateContents_(); |
82 }, | 84 }, |
83 | 85 |
84 get margin() { | |
85 var margin = {top: 0, right: 0, bottom: 0, left: 0}; | |
86 if (this.chartTitle_) | |
87 margin.top += 40; | |
88 return margin; | |
89 }, | |
90 | |
91 getMinSize: function() { | 86 getMinSize: function() { |
92 this.updateContents_(); | 87 this.updateContents_(); |
93 | 88 |
94 var labelSel = d3.select(this.labelsGroup_).selectAll('.label'); | 89 var labelSel = d3.select(this.labelsGroup_).selectAll('.label'); |
95 var maxLabelWidth = -Number.MAX_VALUE; | 90 var maxLabelWidth = -Number.MAX_VALUE; |
96 var leftTextHeightSum = 0; | 91 var leftTextHeightSum = 0; |
97 var rightTextHeightSum = 0; | 92 var rightTextHeightSum = 0; |
98 labelSel.each(function(l) { | 93 labelSel.each(function(l) { |
99 var r = this.getBoundingClientRect(); | 94 var r = this.getBoundingClientRect(); |
100 maxLabelWidth = Math.max(maxLabelWidth, r.width + 32); | 95 maxLabelWidth = Math.max(maxLabelWidth, r.width + 32); |
(...skipping 11 matching lines...) Expand all Loading... |
112 var marginHeight = margin.top + margin.bottom; | 107 var marginHeight = margin.top + margin.bottom; |
113 return { | 108 return { |
114 width: Math.max(2 * MIN_RADIUS + 2 * maxLabelWidth, | 109 width: Math.max(2 * MIN_RADIUS + 2 * maxLabelWidth, |
115 titleWidth * 1.1) + marginWidth, | 110 titleWidth * 1.1) + marginWidth, |
116 height: marginHeight + Math.max(2 * MIN_RADIUS, | 111 height: marginHeight + Math.max(2 * MIN_RADIUS, |
117 leftTextHeightSum, | 112 leftTextHeightSum, |
118 rightTextHeightSum) * 1.25 | 113 rightTextHeightSum) * 1.25 |
119 }; | 114 }; |
120 }, | 115 }, |
121 | 116 |
122 | |
123 getLegendKeys_: function() { | |
124 // This class creates its own legend, instead of using ChartBase. | |
125 return undefined; | |
126 }, | |
127 | |
128 updateScales_: function(width, height) { | 117 updateScales_: function(width, height) { |
129 if (this.data_ === undefined) | 118 if (this.data_ === undefined) |
130 return; | 119 return; |
131 }, | 120 }, |
132 | 121 |
133 updateContents_: function() { | 122 updateContents_: function() { |
134 ChartBase.prototype.updateContents_.call(this); | 123 ChartBase.prototype.updateContents_.call(this); |
135 if (!this.data_) | 124 if (!this.data_) |
136 return; | 125 return; |
137 | 126 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 }.bind(this)); | 190 }.bind(this)); |
202 | 191 |
203 // Value labels. | 192 // Value labels. |
204 piePathsSel.enter().append('text') | 193 piePathsSel.enter().append('text') |
205 .attr('class', 'arc-text') | 194 .attr('class', 'arc-text') |
206 .attr('transform', function(d) { | 195 .attr('transform', function(d) { |
207 return 'translate(' + valueLabelArc.centroid(d) + ')'; | 196 return 'translate(' + valueLabelArc.centroid(d) + ')'; |
208 }) | 197 }) |
209 .attr('dy', '.35em') | 198 .attr('dy', '.35em') |
210 .style('text-anchor', 'middle') | 199 .style('text-anchor', 'middle') |
| 200 .on('mouseenter', function(d, i) { |
| 201 var origData = this.data_[i]; |
| 202 this.pushTempHighlightedLegendKey(origData.label); |
| 203 }.bind(this)) |
| 204 .on('mouseleave', function(d, i) { |
| 205 var origData = this.data_[i]; |
| 206 this.popTempHighlightedLegendKey(origData.label); |
| 207 }.bind(this)) |
211 .text(function(d, i) { | 208 .text(function(d, i) { |
212 var origData = this.data_[i]; | 209 var origData = this.data_[i]; |
213 if (origData.valueText === undefined) | 210 if (origData.valueText === undefined) |
214 return ''; | 211 return ''; |
215 | 212 |
216 if (d.endAngle - d.startAngle < 0.4) | 213 if (d.endAngle - d.startAngle < 0.4) |
217 return ''; | 214 return ''; |
218 return origData.valueText; | 215 return origData.valueText; |
219 }.bind(this)); | 216 }.bind(this)); |
220 | 217 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 this.style.fill = color; | 265 this.style.fill = color; |
269 }); | 266 }); |
270 } | 267 } |
271 }; | 268 }; |
272 | 269 |
273 return { | 270 return { |
274 PieChart: PieChart | 271 PieChart: PieChart |
275 }; | 272 }; |
276 }); | 273 }); |
277 </script> | 274 </script> |
OLD | NEW |