| 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 |