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

Side by Side Diff: tracing/tracing/value/ui/breakdown_span.html

Issue 3009553002: Refactor Histogram relationship diagnostics. (Closed)
Patch Set: Created 3 years, 3 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 2016 The Chromium Authors. All rights reserved. 3 Copyright 2016 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/base/fixed_color_scheme.html"> 8 <link rel="import" href="/tracing/base/fixed_color_scheme.html">
9 <link rel="import" href="/tracing/extras/chrome/chrome_user_friendly_category_dr iver.html"> 9 <link rel="import" href="/tracing/extras/chrome/chrome_user_friendly_category_dr iver.html">
10 <link rel="import" href="/tracing/metrics/all_fixed_color_schemes.html"> 10 <link rel="import" href="/tracing/metrics/all_fixed_color_schemes.html">
(...skipping 24 matching lines...) Expand all
35 <div id="container"></div> 35 <div id="container"></div>
36 <span> 36 <span>
37 <tr-ui-b-table id="table"></tr-ui-b-table> 37 <tr-ui-b-table id="table"></tr-ui-b-table>
38 </span> 38 </span>
39 </div> 39 </div>
40 </template> 40 </template>
41 </dom-module> 41 </dom-module>
42 42
43 <script> 43 <script>
44 'use strict'; 44 'use strict';
45
46 tr.exportTo('tr.v.ui', function() { 45 tr.exportTo('tr.v.ui', function() {
47 const DEFAULT_COLOR_SCHEME = new tr.b.SinebowColorGenerator(); 46 const DEFAULT_COLOR_SCHEME = new tr.b.SinebowColorGenerator();
48 47
48 function getHistogramName(histogram, diagnosticName, key) {
49 const nameMap = histogram.diagnostics.get(diagnosticName);
50 if (nameMap === undefined) return undefined;
51 return nameMap.get(key);
52 }
53
54 function getColorScheme(colorSchemeName) {
55 if (colorSchemeName ===
56 tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER) {
57 return name => {
58 let cat = name.split(' ');
59 cat = cat[cat.length - 1];
60 return tr.e.chrome.ChromeUserFriendlyCategoryDriver.getColor(cat);
61 };
62 }
63
64 if (colorSchemeName !== undefined) {
65 return name => tr.b.FixedColorSchemeRegistry.lookUp(
66 colorSchemeName).getColor(name);
67 }
68
69 return name => DEFAULT_COLOR_SCHEME.colorForKey(name);
70 }
71
72 function getUnit(name, histograms) {
73 const candidates = histograms.getHistogramsNamed(name);
74 if (candidates.length === 0) return undefined;
75 return candidates[0].unit;
76 }
77
49 class BreakdownTableSummaryRow { 78 class BreakdownTableSummaryRow {
50 constructor(displayElement, histogramNames) { 79 constructor(valueSpan, histogramNames) {
51 this.displayElement_ = displayElement; 80 this.valueSpan_ = valueSpan;
52 this.histogramNames_ = histogramNames; 81 this.histogramNames_ = histogramNames;
53 this.keySpan_ = undefined; 82 this.keySpan_ = undefined;
54 } 83 }
55 84
56 get numberValue() { 85 get sanitizedValue() {
57 // Prevent this row from appearing in the ColumnChart. 86 // Prevent this row from appearing in the ColumnChart.
58 return undefined; 87 return undefined;
59 } 88 }
60 89
61 get keySpan() { 90 get keySpan() {
62 if (this.keySpan_ === undefined) { 91 if (this.keySpan_ === undefined) {
63 if (this.histogramNames_.length) { 92 if (this.histogramNames_.length) {
64 this.keySpan_ = document.createElement('tr-ui-a-analysis-link'); 93 this.keySpan_ = document.createElement('tr-ui-a-analysis-link');
65 this.keySpan_.setSelectionAndContent( 94 this.keySpan_.setSelectionAndContent(
66 this.histogramNames_, 'Select All'); 95 this.histogramNames_, 'Select All');
67 } else { 96 } else {
68 this.keySpan_ = 'Sum'; 97 this.keySpan_ = 'Sum';
69 } 98 }
70 } 99 }
71 return this.keySpan_; 100 return this.keySpan_;
72 } 101 }
73 102
74 get name() { 103 get name() {
75 return 'Sum'; 104 return 'Sum';
76 } 105 }
77 106
78 get displayElement() { 107 get valueSpan() {
79 return this.displayElement_; 108 return this.valueSpan_;
80 } 109 }
81 110
82 get stringPercent() { 111 get percentString() {
83 return '100%'; 112 return '100%';
84 } 113 }
85 } 114 }
86 115
87 class BreakdownTableRow { 116 class BreakdownTableRow {
88 constructor(name, value, unit, color) { 117 constructor(name, value, histogramName, unit, color) {
89 this.name_ = name; 118 this.name_ = name;
90 this.value = value; 119 this.value_ = value;
91 this.unit = unit; 120 this.histogramName_ = histogramName;
121 this.unit_ = unit;
92 122
93 if (!this.isHistogram && typeof value !== 'number') { 123 if (typeof value !== 'number') {
94 throw new Error('unsupported value ' + value); 124 throw new Error('unsupported value ' + value);
95 } 125 }
96 126
97 this.tableSum_ = undefined; 127 this.tableSum_ = undefined;
98 this.keySpan_ = undefined; 128 this.keySpan_ = undefined;
99 129
100 this.color_ = color; 130 this.color_ = color;
101 const hsl = this.color.toHSL(); 131 const hsl = this.color.toHSL();
102 hsl.l *= 0.85; 132 hsl.l *= 0.85;
103 this.highlightedColor_ = tr.b.Color.fromHSL(hsl); 133 this.highlightedColor_ = tr.b.Color.fromHSL(hsl);
104 134
105 if (this.isHistogram) { 135 if (this.sanitizedValue !== undefined && this.unit_) {
106 this.displayElement_ = tr.v.ui.createScalarSpan(this.numberValue, { 136 this.valueSpan_ = tr.v.ui.createScalarSpan(this.sanitizedValue, {
107 unit: this.value.unit, 137 unit: this.unit_,
108 }); 138 });
109 } else { 139 } else {
110 this.displayElement_ = tr.ui.b.createSpan({ 140 this.valueSpan_ = tr.ui.b.createSpan({
111 textContent: this.stringValue, 141 textContent: this.stringValue,
112 }); 142 });
113 } 143 }
114 } 144 }
115 145
116 get isHistogram() {
117 return this.value instanceof tr.v.Histogram;
118 }
119
120 get name() { 146 get name() {
121 return this.name_; 147 return this.name_;
122 } 148 }
123 149
150 /**
151 * @return {number|undefined}
152 */
153 get sanitizedValue() {
154 if (isNaN(this.value_) ||
155 this.value_ === Infinity ||
156 this.value_ === -Infinity ||
157 this.value_ < 0) {
158 return undefined;
159 }
160 return this.value_;
161 }
162
124 get color() { 163 get color() {
125 return this.color_; 164 return this.color_;
126 } 165 }
127 166
128 get highlightedColor() { 167 get highlightedColor() {
129 return this.highlightedColor_; 168 return this.highlightedColor_;
130 } 169 }
131 170
132 get keySpan() { 171 get keySpan() {
133 if (this.keySpan_ === undefined) { 172 if (this.keySpan_ === undefined) {
134 if (this.isHistogram) { 173 if (this.histogramName_) {
135 this.keySpan_ = document.createElement('tr-ui-a-analysis-link'); 174 this.keySpan_ = document.createElement('tr-ui-a-analysis-link');
136 this.keySpan_.setSelectionAndContent([this.value.name], this.name); 175 this.keySpan_.setSelectionAndContent(
176 [this.histogramName_], this.name);
137 this.keySpan_.color = this.color; 177 this.keySpan_.color = this.color;
138 this.keySpan_.title = this.value.name; 178 this.keySpan_.title = this.histogramName_;
139 } else { 179 } else {
140 this.keySpan_ = document.createElement('span'); 180 this.keySpan_ = tr.ui.b.createSpan({
141 this.keySpan_.innerText = this.name; 181 textContent: this.name,
142 this.keySpan_.style.color = this.color; 182 color: this.color,
183 });
143 } 184 }
144 } 185 }
145 return this.keySpan_; 186 return this.keySpan_;
146 } 187 }
147 188
148 /**
149 * @return {number|undefined}
150 */
151 get numberValue() {
152 if (this.isHistogram) return this.value.sum;
153 if (!isNaN(this.value) &&
154 (this.value !== Infinity) &&
155 (this.value !== -Infinity) &&
156 (this.value > 0)) return this.value;
157 // Prevent this row from appearing in the ColumnChart.
158 return undefined;
159 }
160
161 get stringValue() { 189 get stringValue() {
162 if (!this.isHistogram && 190 if (this.unit !== undefined) return this.unit.format(this.value_);
163 (isNaN(this.value) || 191 return this.value_.toString();
164 this.value === Infinity ||
165 this.value === -Infinity)) {
166 return this.value.toString();
167 }
168 if (this.unit !== undefined) return this.unit.format(this.value);
169 if (this.isHistogram) return this.value.sum.toString();
170 return this.value.toString();
171 } 192 }
172 193
173 set tableSum(s) { 194 set tableSum(s) {
174 this.tableSum_ = s; 195 this.tableSum_ = s;
175 } 196 }
176 197
177 get stringPercent() { 198 get percentString() {
178 if (this.tableSum_ === undefined) return ''; 199 if (this.tableSum_ === undefined) return '';
179 const num = this.numberValue; 200 const num = this.sanitizedValue;
180 if (num === undefined) return ''; 201 if (num === undefined) return '';
181 return Math.floor(num * 100.0 / this.tableSum_) + '%'; 202 return Math.floor(num * 100.0 / this.tableSum_) + '%';
182 } 203 }
183 204
184 get displayElement() { 205 get valueSpan() {
185 return this.displayElement_; 206 return this.valueSpan_;
186 } 207 }
187 208
188 compare(other) { 209 compare(other) {
189 if (this.numberValue === undefined) { 210 if (this.sanitizedValue === undefined) {
190 if (other.numberValue === undefined) { 211 if (other.sanitizedValue === undefined) {
191 return this.name.localeCompare(other.name); 212 return this.name.localeCompare(other.name);
192 } 213 }
193 return 1; 214 return 1;
194 } 215 }
195 if (other.numberValue === undefined) { 216 if (other.sanitizedValue === undefined) {
196 return -1; 217 return -1;
197 } 218 }
198 if (this.numberValue === other.numberValue) { 219 if (this.sanitizedValue === other.sanitizedValue) {
199 return this.name.localeCompare(other.name); 220 return this.name.localeCompare(other.name);
200 } 221 }
201 return other.numberValue - this.numberValue; 222 return other.sanitizedValue - this.sanitizedValue;
202 } 223 }
203 } 224 }
204 225
205 Polymer({ 226 Polymer({
206 is: 'tr-v-ui-breakdown-span', 227 is: 'tr-v-ui-breakdown-span',
207 behaviors: [tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR], 228 behaviors: [tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],
208 229
209 created() { 230 created() {
210 this.chart_ = new tr.ui.b.ColumnChart(); 231 this.chart_ = new tr.ui.b.ColumnChart();
211 this.chart_.graphHeight = 130; 232 this.chart_.graphHeight = 130;
212 this.chart_.isStacked = true; 233 this.chart_.isStacked = true;
213 this.chart_.hideXAxis = true; 234 this.chart_.hideXAxis = true;
214 this.chart_.hideLegend = true; 235 this.chart_.hideLegend = true;
215 this.chart_.enableHoverBox = false; 236 this.chart_.enableHoverBox = false;
216 this.chart_.addEventListener('rect-mouseenter', 237 this.chart_.addEventListener('rect-mouseenter',
217 event => this.onRectMouseEnter_(event)); 238 event => this.onRectMouseEnter_(event));
218 this.chart_.addEventListener('rect-mouseleave', 239 this.chart_.addEventListener('rect-mouseleave',
219 event => this.onRectMouseLeave_(event)); 240 event => this.onRectMouseLeave_(event));
220 }, 241 },
221 242
222 onRectMouseEnter_(event) { 243 onRectMouseEnter_(event) {
223 for (const row of this.$.table.tableRows) { 244 for (const row of this.$.table.tableRows) {
224 if (row.name === event.rect.key) { 245 if (row.name === event.rect.key) {
225 row.displayElement.style.background = event.rect.color; 246 row.valueSpan.style.background = event.rect.color;
226 row.keySpan.scrollIntoViewIfNeeded(); 247 row.keySpan.scrollIntoViewIfNeeded();
227 } else { 248 } else {
228 row.displayElement.style.background = ''; 249 row.valueSpan.style.background = '';
229 } 250 }
230 } 251 }
231 }, 252 },
232 253
233 onRectMouseLeave_(event) { 254 onRectMouseLeave_(event) {
234 for (const row of this.$.table.tableRows) { 255 for (const row of this.$.table.tableRows) {
235 row.displayElement.style.background = ''; 256 row.valueSpan.style.background = '';
236 } 257 }
237 }, 258 },
238 259
239 ready() { 260 ready() {
240 Polymer.dom(this.$.container).appendChild(this.chart_); 261 Polymer.dom(this.$.container).appendChild(this.chart_);
241 262
242 this.$.table.zebra = true; 263 this.$.table.zebra = true;
243 this.$.table.showHeader = false; 264 this.$.table.showHeader = false;
244 this.$.table.tableColumns = [ 265 this.$.table.tableColumns = [
245 { 266 {
246 value: row => row.keySpan, 267 value: row => row.keySpan,
247 }, 268 },
248 { 269 {
249 value: row => row.displayElement, 270 value: row => row.valueSpan,
250 align: tr.ui.b.TableFormat.ColumnAlignment.RIGHT, 271 align: tr.ui.b.TableFormat.ColumnAlignment.RIGHT,
251 }, 272 },
252 { 273 {
253 value: row => row.stringPercent, 274 value: row => row.percentString,
254 align: tr.ui.b.TableFormat.ColumnAlignment.RIGHT, 275 align: tr.ui.b.TableFormat.ColumnAlignment.RIGHT,
255 }, 276 },
256 ]; 277 ];
257 }, 278 },
258 279
259 updateContents_() { 280 updateContents_() {
260 this.$.container.style.display = 'none'; 281 this.$.container.style.display = 'none';
261 this.$.table.style.display = 'none'; 282 this.$.table.style.display = 'none';
262 this.$.empty.style.display = 'block'; 283 this.$.empty.style.display = 'block';
263 284
264 if (!this.diagnostic_) { 285 if (!this.diagnostic_ || this.diagnostic_.size === 0) {
265 this.chart_.data = []; 286 this.chart_.data = [];
266 return; 287 return;
267 } 288 }
268 289
269 if (this.histogram_) this.chart_.unit = this.histogram_.unit; 290 const colorScheme = getColorScheme(this.diagnostic.colorScheme);
291 const tableRows = [];
292 const histogramNames = new Set();
293 let tableSum = 0;
294 let conflictingUnits = false;
295 for (const [key, value] of this.diagnostic) {
296 const histogramName = getHistogramName(this.histogram_, this.name_,
297 key);
298 let unit = this.histogram_.unit;
299 if (histogramName) {
300 histogramNames.add(histogramName);
270 301
271 let colorScheme = undefined; 302 unit = getUnit(histogramName, this.histograms_);
272 // https://github.com/catapult-project/catapult/issues/2970 303 if (unit !== undefined) {
273 if (this.diagnostic.colorScheme === 304 if (this.chart_.unit === undefined &&
274 tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER) { 305 !conflictingUnits) {
275 colorScheme = (name) => { 306 this.chart_.unit = unit;
276 let cat = name.split(' '); 307 } else if (unit !== this.chart_.unit) {
277 cat = cat[cat.length - 1]; 308 conflictingUnits = true;
278 return tr.e.chrome.ChromeUserFriendlyCategoryDriver.getColor(cat); 309 this.chart_.unit = undefined;
279 }; 310 }
280 } else if (this.diagnostic.colorScheme !== undefined) { 311 }
281 colorScheme = (name) => tr.b.FixedColorSchemeRegistry.lookUp( 312 } else {
282 this.diagnostic.colorScheme).getColor(name); 313 this.chart_.unit = unit;
283 } else { 314 }
284 colorScheme = (name) => DEFAULT_COLOR_SCHEME.colorForKey(name);
285 }
286 315
287 const tableRows = [];
288 let tableSum = 0;
289 const histogramNames = [];
290 for (const [name, value] of this.diagnostic) {
291 const row = new BreakdownTableRow( 316 const row = new BreakdownTableRow(
292 name, value, this.chart_.unit, colorScheme(name)); 317 key, value, histogramName, unit, colorScheme(key));
293 tableRows.push(row); 318 tableRows.push(row);
294 if (row.numberValue !== undefined) tableSum += row.numberValue; 319 if (row.sanitizedValue !== undefined) tableSum += row.sanitizedValue;
295 if (row.isHistogram) {
296 histogramNames.push(value.name);
297 }
298 } 320 }
299 tableRows.sort((x, y) => x.compare(y)); 321 tableRows.sort((x, y) => x.compare(y));
300 322
301 if (tableSum > 0) { 323 if (tableRows.length > 1) {
302 let summaryDisplayElement = tableSum; 324 let summaryDisplayElement = tableSum;
303 if (this.chart_.unit !== undefined) { 325 if (this.chart_.unit !== undefined) {
304 summaryDisplayElement = this.chart_.unit.format(tableSum); 326 summaryDisplayElement = this.chart_.unit.format(tableSum);
305 } 327 }
306 summaryDisplayElement = tr.ui.b.createSpan({ 328 summaryDisplayElement = tr.ui.b.createSpan({
307 textContent: summaryDisplayElement, 329 textContent: summaryDisplayElement,
308 }); 330 });
309 tableRows.unshift(new BreakdownTableSummaryRow( 331 tableRows.unshift(new BreakdownTableSummaryRow(
310 summaryDisplayElement, histogramNames)); 332 summaryDisplayElement, histogramNames));
311 } 333 }
312 334
313 const chartData = {x: 0}; 335 const chartData = {x: 0};
314 for (const row of tableRows) { 336 for (const row of tableRows) {
315 if (row.numberValue === undefined) continue; 337 if (row.sanitizedValue === undefined) continue;
316 338
317 // Let the row compute its percentage. 339 if (tableRows.length > 1) {
318 row.tableSum = tableSum; 340 // Let the row compute its percentage.
341 row.tableSum = tableSum;
342 }
319 343
320 // Add it to the chart. 344 // Add it to the chart.
321 chartData[row.name] = row.numberValue; 345 chartData[row.name] = row.sanitizedValue;
322 346
323 // Configure the colors. 347 // Configure the colors.
324 const dataSeries = this.chart_.getDataSeries(row.name); 348 const dataSeries = this.chart_.getDataSeries(row.name);
325 dataSeries.color = row.color; 349 dataSeries.color = row.color;
326 dataSeries.highlightedColor = row.highlightedColor; 350 dataSeries.highlightedColor = row.highlightedColor;
327 } 351 }
328 352
329 if (tableRows.length > 0) { 353 if (tableRows.length > 0) {
330 this.$.table.style.display = 'block'; 354 this.$.table.style.display = 'block';
331 this.$.empty.style.display = 'none'; 355 this.$.empty.style.display = 'none';
332 this.$.table.tableRows = tableRows; 356 this.$.table.tableRows = tableRows;
333 this.$.table.rebuild(); 357 this.$.table.rebuild();
334 } 358 }
335 359
336 if (Object.keys(chartData).length > 1) { 360 if (Object.keys(chartData).length > 2) {
337 this.$.container.style.display = 'block'; 361 this.$.container.style.display = 'block';
338 this.$.empty.style.display = 'none'; 362 this.$.empty.style.display = 'none';
339 this.chart_.data = [chartData]; 363 this.chart_.data = [chartData];
340 } 364 }
341 } 365 }
342 }); 366 });
343 367
344 return {}; 368 return {};
345 }); 369 });
346 </script> 370 </script>
OLDNEW
« no previous file with comments | « tracing/tracing/value/merge_histograms_cmdline.html ('k') | tracing/tracing/value/ui/breakdown_span_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698