OLD | NEW |
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/timing.html"> | 8 <link rel="import" href="/tracing/base/timing.html"> |
9 <link rel="import" href="/tracing/ui/base/table.html"> | 9 <link rel="import" href="/tracing/ui/base/table.html"> |
10 <link rel="import" href="/tracing/value/histogram_set.html"> | 10 <link rel="import" href="/tracing/value/histogram_set.html"> |
(...skipping 30 matching lines...) Expand all Loading... |
41 Polymer({ | 41 Polymer({ |
42 is: 'tr-v-ui-histogram-set-table', | 42 is: 'tr-v-ui-histogram-set-table', |
43 | 43 |
44 created() { | 44 created() { |
45 this.viewState_ = undefined; | 45 this.viewState_ = undefined; |
46 this.progress_ = () => Promise.resolve(); | 46 this.progress_ = () => Promise.resolve(); |
47 this.nameColumnTitle_ = undefined; | 47 this.nameColumnTitle_ = undefined; |
48 this.displayLabels_ = []; | 48 this.displayLabels_ = []; |
49 this.histograms_ = undefined; | 49 this.histograms_ = undefined; |
50 this.sourceHistograms_ = undefined; | 50 this.sourceHistograms_ = undefined; |
| 51 this.sourceHistogramNames_ = undefined; |
51 this.groupedHistograms_ = undefined; | 52 this.groupedHistograms_ = undefined; |
52 this.hierarchies_ = undefined; | 53 this.hierarchies_ = undefined; |
53 this.tableRows_ = undefined; | 54 this.tableRows_ = undefined; |
54 }, | 55 }, |
55 | 56 |
56 ready() { | 57 ready() { |
57 this.$.table.zebra = true; | 58 this.$.table.zebra = true; |
58 this.addEventListener('sort-column-changed', | 59 this.addEventListener('sort-column-changed', |
59 this.onSortColumnChanged_.bind(this)); | 60 this.onSortColumnChanged_.bind(this)); |
60 this.addEventListener('requestSelectionChange', | 61 this.addEventListener('requestSelectionChange', |
(...skipping 26 matching lines...) Expand all Loading... |
87 * @param {!tr.v.HistogramSet} sourceHistograms | 88 * @param {!tr.v.HistogramSet} sourceHistograms |
88 * @param {!Array.<string>} displayLabels | 89 * @param {!Array.<string>} displayLabels |
89 * @param {function(string, function())=} opt_progress | 90 * @param {function(string, function())=} opt_progress |
90 */ | 91 */ |
91 async build(histograms, sourceHistograms, displayLabels, opt_progress) { | 92 async build(histograms, sourceHistograms, displayLabels, opt_progress) { |
92 this.histograms_ = histograms; | 93 this.histograms_ = histograms; |
93 this.sourceHistograms_ = sourceHistograms; | 94 this.sourceHistograms_ = sourceHistograms; |
94 this.groupedHistograms_ = undefined; | 95 this.groupedHistograms_ = undefined; |
95 this.displayLabels_ = displayLabels; | 96 this.displayLabels_ = displayLabels; |
96 | 97 |
| 98 this.sourceHistogramNames_ = new Set(); |
| 99 if (this.histograms_.length !== this.sourceHistograms_.length) { |
| 100 for (const hist of this.sourceHistograms_) { |
| 101 this.sourceHistogramNames_.add(hist.name); |
| 102 } |
| 103 } |
| 104 |
97 if (opt_progress !== undefined) this.progress_ = opt_progress; | 105 if (opt_progress !== undefined) this.progress_ = opt_progress; |
98 | 106 |
99 if (histograms.length === 0) { | 107 if (histograms.length === 0) { |
100 throw new Error('histogram-set-table requires non-empty HistogramSet.'); | 108 throw new Error('histogram-set-table requires non-empty HistogramSet.'); |
101 } | 109 } |
102 | 110 |
103 await this.progress_('Building columns...'); | 111 await this.progress_('Building columns...'); |
104 this.$.table.tableColumns = [ | 112 this.$.table.tableColumns = [ |
105 { | 113 { |
106 title: this.buildNameColumnTitle_(), | 114 title: this.buildNameColumnTitle_(), |
107 value: row => row.nameCell, | 115 value: row => row.nameCell, |
108 cmp: (a, b) => a.compareNames(b), | 116 cmp: (a, b) => a.compareNames(b), |
109 } | 117 } |
110 ].concat(displayLabels.map(l => this.buildColumn_(l))); | 118 ].concat(displayLabels.map(l => this.buildColumn_(l))); |
111 | 119 |
112 tr.b.Timing.instant('histogram-set-table', 'columnCount', | 120 tr.b.Timing.instant('histogram-set-table', 'columnCount', |
113 this.$.table.tableColumns.length); | 121 this.$.table.tableColumns.length); |
114 | 122 |
115 // updateContents_() displays its own progress. | 123 // updateContents_() displays its own progress. |
116 await this.updateContents_(); | 124 await this.updateContents_(); |
117 | 125 |
118 // Building some elements requires being able to measure them, which is | 126 // Building some elements requires being able to measure them, which is |
119 // impossible until they are displayed. If clients hide this table while | 127 // impossible until they are displayed. If clients hide this table while |
120 // it is being built, then they must display it when this event fires. | 128 // it is being built, then they must display it when this event fires. |
121 this.fire('display-ready'); | 129 this.fire('display-ready'); |
122 | 130 |
123 this.progress_ = () => Promise.resolve(); | 131 this.progress_ = () => Promise.resolve(); |
124 | 132 |
125 this.checkNameColumnOverflow_( | 133 for (const row of |
126 tr.v.ui.HistogramSetTableRow.walkAll(this.$.table.tableRows)); | 134 tr.v.ui.HistogramSetTableRow.walkAll(this.$.table.tableRows)) { |
| 135 row.nameCell.isSource = this.sourceHistogramNames_.has(row.name); |
| 136 this.checkNameColumnOverflow_(row); |
| 137 } |
127 }, | 138 }, |
128 | 139 |
129 buildNameColumnTitle_() { | 140 buildNameColumnTitle_() { |
130 this.nameColumnTitle_ = document.createElement('span'); | 141 this.nameColumnTitle_ = document.createElement('span'); |
131 this.nameColumnTitle_.style.display = 'inline-flex'; | 142 this.nameColumnTitle_.style.display = 'inline-flex'; |
132 | 143 |
133 // Wrap the string in a span instead of using createTextNode() so that the | 144 // Wrap the string in a span instead of using createTextNode() so that the |
134 // span can be styled later. | 145 // span can be styled later. |
135 const nameEl = document.createElement('span'); | 146 const nameEl = document.createElement('span'); |
136 nameEl.textContent = 'Name'; | 147 nameEl.textContent = 'Name'; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 | 256 |
246 // Each name-cell listens to this.viewState for updates to | 257 // Each name-cell listens to this.viewState for updates to |
247 // constrainNameColumn. | 258 // constrainNameColumn. |
248 // Each table-cell listens to this.viewState for updates to | 259 // Each table-cell listens to this.viewState for updates to |
249 // displayStatisticName and referenceDisplayLabel. | 260 // displayStatisticName and referenceDisplayLabel. |
250 | 261 |
251 if (tableRowsDirty) { | 262 if (tableRowsDirty) { |
252 await this.progress_('Building DOM...'); | 263 await this.progress_('Building DOM...'); |
253 this.$.table.tableRows = this.tableRows_; | 264 this.$.table.tableRows = this.tableRows_; |
254 | 265 |
| 266 for (const row of |
| 267 tr.v.ui.HistogramSetTableRow.walkAll(this.$.table.tableRows)) { |
| 268 row.nameCell.isSource = this.sourceHistogramNames_.has(row.name); |
| 269 } |
| 270 |
255 // Try to restore previous row state. | 271 // Try to restore previous row state. |
256 // Wait to do this until after the base table has the new rows so that | 272 // Wait to do this until after the base table has the new rows so that |
257 // setExpandedForTableRow doesn't get confused. | 273 // setExpandedForTableRow doesn't get confused. |
258 for (const row of this.tableRows_) { | 274 for (const row of this.tableRows_) { |
259 const previousState = previousRowStates.get(row.name); | 275 const previousState = previousRowStates.get(row.name); |
260 if (!previousState) continue; | 276 if (!previousState) continue; |
261 await row.restoreState(previousState); | 277 await row.restoreState(previousState); |
262 } | 278 } |
263 } | 279 } |
264 | 280 |
(...skipping 10 matching lines...) Expand all Loading... |
275 'row' + (event.row.viewState.isExpanded ? 'Expanded' : 'Collapsed')); | 291 'row' + (event.row.viewState.isExpanded ? 'Expanded' : 'Collapsed')); |
276 | 292 |
277 // When the user expands a row, the table builds subRows' name-cells. | 293 // When the user expands a row, the table builds subRows' name-cells. |
278 // If a subRow's name isOverflowing even though none of the top-level rows | 294 // If a subRow's name isOverflowing even though none of the top-level rows |
279 // are constrained, show the dots to allow the user to unconstrain the | 295 // are constrained, show the dots to allow the user to unconstrain the |
280 // name column. | 296 // name column. |
281 // Each name-cell.isOverflowing would force layout if we don't await | 297 // Each name-cell.isOverflowing would force layout if we don't await |
282 // animationFrame here, which would be inefficient. | 298 // animationFrame here, which would be inefficient. |
283 if (this.nameColumnTitle_.children[1].style.display === 'block') return; | 299 if (this.nameColumnTitle_.children[1].style.display === 'block') return; |
284 await tr.b.animationFrame(); | 300 await tr.b.animationFrame(); |
285 this.checkNameColumnOverflow_(event.row.subRows); | 301 for (const row of event.row.subRows) { |
286 }, | 302 this.checkNameColumnOverflow_(row); |
287 | |
288 checkNameColumnOverflow_(rows) { | |
289 for (const row of rows) { | |
290 if (!row.nameCell.isOverflowing) continue; | |
291 | |
292 const [nameSpan, dots] = this.nameColumnTitle_.children; | |
293 dots.style.display = 'block'; | |
294 | |
295 // Size the span containing 'Name' so that the dots align with the | |
296 // ellipses in the name-cells. | |
297 const labelWidthPx = tr.v.ui.NAME_COLUMN_WIDTH_PX - | |
298 dots.getBoundingClientRect().width; | |
299 nameSpan.style.width = labelWidthPx + 'px'; | |
300 // TODO(benjhayden): Manage this using polymer. | |
301 | |
302 return; | |
303 } | 303 } |
304 }, | 304 }, |
305 | 305 |
| 306 checkNameColumnOverflow_(row) { |
| 307 if (!row.nameCell.isOverflowing) return; |
| 308 |
| 309 const [nameSpan, dots] = this.nameColumnTitle_.children; |
| 310 dots.style.display = 'block'; |
| 311 |
| 312 // Size the span containing 'Name' so that the dots align with the |
| 313 // ellipses in the name-cells. |
| 314 const labelWidthPx = tr.v.ui.NAME_COLUMN_WIDTH_PX - |
| 315 dots.getBoundingClientRect().width; |
| 316 nameSpan.style.width = labelWidthPx + 'px'; |
| 317 }, |
| 318 |
306 groupHistograms_() { | 319 groupHistograms_() { |
307 const groupings = this.viewState.groupings.slice(); | 320 const groupings = this.viewState.groupings.slice(); |
308 groupings.push(tr.v.HistogramGrouping.DISPLAY_LABEL); | 321 groupings.push(tr.v.HistogramGrouping.DISPLAY_LABEL); |
309 | 322 |
310 function canSkipGrouping(grouping, groupedHistograms) { | 323 function canSkipGrouping(grouping, groupedHistograms) { |
311 // Never skip meaningful groupings. | 324 // Never skip meaningful groupings. |
312 if (groupedHistograms.size > 1) return false; | 325 if (groupedHistograms.size > 1) return false; |
313 | 326 |
314 // Never skip the zero-th grouping. | 327 // Never skip the zero-th grouping. |
315 if (grouping.key === groupings[0].key) return false; | 328 if (grouping.key === groupings[0].key) return false; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 } | 444 } |
432 return histograms; | 445 return histograms; |
433 } | 446 } |
434 }); | 447 }); |
435 | 448 |
436 return { | 449 return { |
437 MIDLINE_HORIZONTAL_ELLIPSIS, | 450 MIDLINE_HORIZONTAL_ELLIPSIS, |
438 }; | 451 }; |
439 }); | 452 }); |
440 </script> | 453 </script> |
OLD | NEW |