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

Unified Diff: tracing/tracing/value/ui/value_set_table.html

Issue 2162963002: [polymer] Merge of master into polymer10-migration (Closed) Base URL: git@github.com:catapult-project/catapult.git@polymer10-migration
Patch Set: Merge polymer10-migration int polymer10-merge 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tracing/tracing/value/ui/scalar_span_test.html ('k') | tracing/tracing/value/ui/value_set_table_test.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tracing/tracing/value/ui/value_set_table.html
diff --git a/tracing/tracing/value/ui/value_set_table.html b/tracing/tracing/value/ui/value_set_table.html
index 76fc197afce591037985a390aaa31283247d38cb..4eb50e885fa2fbd4b6402bb4dbbf3b495affb564 100644
--- a/tracing/tracing/value/ui/value_set_table.html
+++ b/tracing/tracing/value/ui/value_set_table.html
@@ -28,8 +28,21 @@ found in the LICENSE file.
div#error {
color: red;
}
+ #histogram {
+ display: none;
+ }
+ #search {
+ max-width: 20em;
+ margin-top: 5px;
+ margin-bottom: 5px;
+ }
</style>
+ <input id="search" placeholder="Find Value name">
+ <div>
+ <input type="checkbox" id="show_all">
+ <label for="show_all">Show all</label>
+ </div>
<div id="error"></div>
<table-container>
<tr-ui-b-table id="table"></tr-ui-b-table>
@@ -41,6 +54,79 @@ found in the LICENSE file.
<script>
'use strict';
tr.exportTo('tr.ui', function() {
+
+ /**
+ * @param {!tr.v.Value} value
+ * @param {string} fieldName
+ * @param {*} defaultValue
+ * @return {*}
+ */
+ function getIterationInfoField(value, fieldName, defaultValue) {
+ var iteration = tr.v.d.IterationInfo.getFromValue(value);
+ if (!(iteration instanceof tr.v.d.IterationInfo))
+ return defaultValue;
+ return iteration[fieldName];
+ }
+
+ /**
+ * @param {!tr.v.Value} value
+ * @param {string} fieldName
+ * @return {string}
+ */
+ function getStoryGroupingKeyLabel(value, storyGroupingKey) {
+ var iteration = tr.v.d.IterationInfo.getFromValue(value);
+ if (!(iteration instanceof tr.v.d.IterationInfo))
+ return storyGroupingKey + ': undefined';
+ return storyGroupingKey + ': ' +
+ iteration.storyGroupingKeys[storyGroupingKey];
+ }
+
+ /**
+ * @param {!tr.v.Value} value
+ * @return {string}
+ */
+ var getDisplayLabel = v => getIterationInfoField(v, 'displayLabel', 'Value');
+
+ var SELECTED_VALUE_SETTINGS_KEY = 'tr-v-ui-value-set-table-value';
+ var SHOW_ALL_SETTINGS_KEY = 'tr-v-ui-value-set-table-show-all';
+
+ /**
+ * Recursively groups |values|.
+ * TODO(benjhayden): Use ES6 Maps instead of dictionaries?
+ *
+ * @param {!Array.<!tr.v.Value>} values
+ * @param {!Array.<!function(!tr.v.Value):(string|number)>} groupingCallbacks
+ * @return {!(Object|tr.v.Value)}
+ */
+ function organizeValues(values, groupingCallbacks, level) {
+ if (groupingCallbacks.length === level) {
+ // Recursion base case: there should only be a single value when we've
+ // grouped by every possible grouping.
+ if (values.length > 1) {
+ console.warn('Multiple Values with same name, benchmarkName, ' +
+ 'storyGroupingKeys, storyName, start, storysetRepeatCounter, ' +
+ 'storyRepeatCounter, and displayLabel', values);
+ }
+ return values[0];
+ }
+
+ // Group the values by the current grouping.
+ var groupedValues = tr.b.group(values, groupingCallbacks[level]);
+
+ // Skip this grouping level if it contains only a single group,
+ // but never skip the zeroth grouping level (value name) nor the last
+ // (displayLabel).
+ if (level > 0 && level < (groupingCallbacks.length - 1) &&
+ tr.b.dictionaryLength(groupedValues) === 1) {
+ return organizeValues(values, groupingCallbacks, level + 1);
+ }
+
+ // Recursively group groupedValues.
+ return tr.b.mapItems(groupedValues, function(key, groupValues) {
+ return organizeValues(groupValues, groupingCallbacks, level + 1);
+ });
+ }
+
Polymer({
is: 'tr-v-ui-value-set-table',
@@ -64,111 +150,583 @@ tr.exportTo('tr.ui', function() {
return 'Table';
},
+ created: function() {
+ // TODO(benjhayden): Should these all be ValueSets?
+ /** @type {undefined|!tr.v.ValueSet} */
+ this.values_ = undefined;
+ /** @type {!Array.<!tr.v.Value>} */
+ this.sourceValues_ = [];
+ /** @type {!Object} */
+ this.summaryValuesByGuid_ = {};
+
+ this.rows_ = undefined;
+ this.columns_ = undefined;
+ },
+
ready: function() {
- this.$.table.sortDescending = true;
- this.$.table.selectionMode = tr.ui.b.TableFormat.SelectionMode.ROW;
- this.$.table.tableColumns = [
- {
- title: 'Name',
- value: function(value) {
- var nameEl = document.createElement('span');
- Polymer.dom(nameEl).textContent = value.name;
- if (value.description)
- nameEl.title = value.description;
- nameEl.style.textOverflow = 'ellipsis';
- return nameEl;
- },
- cmp: function(a, b) {
- return a.name.localeCompare(b.name);
- }
- },
- {
- title: 'Value',
- align: tr.ui.b.TableFormat.ColumnAlignment.RIGHT,
- value: function(value) {
- if (value.diagnostic instanceof tr.v.d.Diagnostic)
- return tr.v.ui.createDiagnosticSpan(value.diagnostic);
- if (value.unit)
- return tr.v.ui.createScalarSpan(value.value, {unit: value.unit});
- return value.value;
- },
- cmp: function(a, b) {
- return a.value - b.value;
+ this.$.table.selectionMode = tr.ui.b.TableFormat.SelectionMode.CELL;
+ this.$.table.addEventListener('selection-changed',
+ this.onSelectionChanged_.bind(this));
+ this.$.table.addEventListener('selected-column-changed',
+ this.onSelectedColumnChanged_.bind(this));
+ this.addEventListener('requestSelectionChange',
+ this.onRelatedValueSelected_.bind(this));
+ this.$.search.addEventListener('keyup', this.onSearch_.bind(this));
+ this.$.show_all.checked = tr.b.Settings.get(SHOW_ALL_SETTINGS_KEY, false);
+ this.$.show_all.addEventListener('change',
+ this.onShowAllChange_.bind(this));
+ },
+
+ onShowAllChange_: function() {
+ tr.b.Settings.set(SHOW_ALL_SETTINGS_KEY, this.$.show_all.checked);
+ this.updateContents_();
+ },
+
+ onSelectedColumnChanged_: function() {
+ // Force the table to rebuild the cell values without forgetting which
+ // rows were expanded.
+ var expansionStates = this.getExpansionStates_(this.rows_);
+ this.$.table.tableRows = this.rows_;
+ this.setExpansionStates_(expansionStates, this.rows_);
+ },
+
+ getExpansionStates_: function(rows) {
+ var states = {};
+ for (var i = 0; i < rows.length; ++i) {
+ var row = rows[i];
+ if (row.subRows && row.subRows.length &&
+ this.$.table.getExpandedForTableRow(row)) {
+ states[i] = this.getExpansionStates_(row.subRows);
+ }
+ }
+ return states;
+ },
+
+ setExpansionStates_: function(states, rows) {
+ for (var i = 0; i < rows.length; ++i) {
+ if (states[i]) {
+ this.$.table.setExpandedForTableRow(rows[i], true);
+ this.setExpansionStates_(states[i], rows[i].subRows);
+ }
+ }
+ },
+
+ onSearch_: function() {
+ this.updateContents_();
+ },
+
+ rowMatchesSearch_: function(row) {
+ return row.name.indexOf(this.$.search.value) >= 0;
+ },
+
+ onRelatedValueSelected_: function(event) {
+ var value = event.selection;
+ if (!(value instanceof tr.v.Value))
+ return;
+
+ event.stopPropagation();
+
+ var displayLabel = getDisplayLabel(value);
+ var columnIndex = -1;
+ for (var i = 0; i < this.columns_.length; ++i) {
+ if (this.columns_[i].title === displayLabel) {
+ columnIndex = i;
+ break;
+ }
+ }
+ if (columnIndex < 0)
+ return;
+
+ var hierarchy = [];
+ var found = false;
+ function search(row) {
+ if (row.columns[displayLabel] === value) {
+ for (var hirow in hierarchy) {
+ this.$.table.setExpandedForTableRow(hirow, true);
}
+ found = true;
+ this.$.table.selectedTableRow = row;
+ this.$.table.selectedColumnIndex = columnIndex;
+ return;
}
- ];
- this.$.table.sortColumnIndex = 1;
- this.$.table.addEventListener('selection-changed',
- this.onRowSelected_.bind(this));
+ if (!row.subRows)
+ return;
+ hierarchy.push(row);
+ row.subRows.forEach(search, this);
+ hierarchy.pop(row);
+ }
+ this.rows_.forEach(search, this);
+
+ if (found || this.$.show_all.checked)
+ return;
+
+ // Search hidden values for |value|.
+ for (var test of this.values) {
+ // Skip values that are already displayed -- we would have found them
+ // in search() above.
+ if (this.sourceValues_.indexOf(test) >= 0)
+ continue;
+
+ if (test === value) {
+ this.$.show_all.checked = true;
+ this.onShowAllChange_();
+ this.onRelatedValueSelected_(event);
+ break;
+ }
+ }
},
- onRowSelected_: function() {
+ onSelectionChanged_: function() {
var row = this.$.table.selectedTableRow;
- if (row && row.numeric) {
- this.$.histogram.style.display = '';
- this.$.histogram.histogram = row.numeric;
+ var col = this.$.table.selectedColumnIndex;
+ var cell = undefined;
+ if (row && col && this.columns_)
+ cell = row.columns[this.columns_[col].title];
+
+ if ((cell instanceof tr.v.NumericValue) &&
+ (cell.numeric instanceof tr.v.Numeric)) {
+ this.$.histogram.style.display = 'block';
+ this.$.histogram.histogram = cell.numeric;
+
+ tr.b.Settings.set(SELECTED_VALUE_SETTINGS_KEY, JSON.stringify({
+ row: row.name,
+ column: this.columns_[col].title
+ }));
} else {
this.$.histogram.style.display = 'none';
}
},
+ handleFailureValues_: function() {
+ this.values.map(function(value) {
+ if (value instanceof tr.v.FailureValue) {
+ Polymer.dom(this.$.error).textContent = value.description;
+ this.$.table.style.display = 'none';
+ this.style.width = '10em';
+ }
+ }, this);
+ },
+
+ addDiagnosticSubRows_: function(value, row, column) {
+ value.diagnostics.forEach(function(name, diagnostic) {
+ if (name === tr.v.SUMMARY_VALUE_MAP_DIAGNOSTIC_NAME)
+ return;
+
+ // If a previous |value| had a diagnostic with the same name, then
+ // there is already a subRow that should contain this diagnostic.
+ for (var subRow of row.subRows) {
+ if (subRow.name === name) {
+ subRow.columns[column] = diagnostic;
+ return;
+ }
+ }
+
+ // This is the first time that a diagnostic with this name has been
+ // seen for Values whose name is |value.name|, so create a new subRow.
+ var subRow = {name: name, columns: {}};
+ subRow.columns[column] = diagnostic;
+ row.subRows.push(subRow);
+ });
+ },
+
+ get values() {
+ return this.values_;
+ },
+
+ findSummaryValues_: function() {
+ this.summaryValuesByGuid_ = {};
+ this.values.map(function(value) {
+ var summaryValueMap = value.diagnostics.get(
+ tr.v.SUMMARY_VALUE_MAP_DIAGNOSTIC_NAME);
+ if (!(summaryValueMap instanceof tr.v.d.RelatedValueMap))
+ return;
+
+ summaryValueMap.values.forEach(function(summaryValue) {
+ this.summaryValuesByGuid_[summaryValue.guid] = summaryValue;
+ }, this);
+ }, this);
+ },
+
/**
* @param {!tr.v.ValueSet} values
*/
set values(values) {
+ this.values_ = values;
+ this.sourceValues_ = values.sourceValues;
+ this.findSummaryValues_();
+ this.updateContents_();
+ },
+
+ updateContents_: function() {
+ if (!this.values_)
+ return;
this.style.width = '';
this.$.table.style.display = '';
Polymer.dom(this.$.error).textContent = '';
+ this.$.histogram.style.display = 'none';
- values.map(function(value) {
- if (value instanceof tr.v.FailureValue) {
- Polymer.dom(this.$.error).textContent = value.description;
- this.$.table.style.display = 'none';
- this.style.width = '10em';
- }
- }, this);
+ this.handleFailureValues_();
if (Polymer.dom(this.$.error).textContent)
return;
- this.$.table.tableRows = values.map(function(value) {
- var row = {
- name: value.name,
- value: '',
- unit: undefined,
- description: value.description,
- subRows: []
- };
-
- if (value.numeric) {
- row.unit = value.numeric.unit;
- if (value.numeric.value !== undefined) {
- row.value = value.numeric.value;
- } else if (value.numeric.average !== undefined) {
- row.numeric = value.numeric;
- row.value = value.numeric.average;
- }
- }
+ this.buildRows_();
- value.diagnostics.forEach(function(name, diagnostic) {
- row.subRows.push({
- name: name,
- diagnostic: diagnostic
- });
- });
+ if (this.rows_.length === 0) {
+ Polymer.dom(this.$.error).textContent = 'zero values';
+ this.$.table.style.display = 'none';
+ this.style.width = '10em';
+ return;
+ }
- return row;
- });
+ this.buildColumns_();
+ this.$.table.tableColumns = this.columns_;
+ this.$.table.tableRows = this.rows_;
+ this.$.table.sortColumnIndex = 0;
this.$.table.rebuild();
- this.onRowSelected_();
+ this.selectValue_();
tr.b.requestAnimationFrame(function() {
this.style.width = this.$.table.getBoundingClientRect().width;
}, this);
+ },
+
+ selectValue_: function() {
+ var selectedValue = tr.b.Settings.get(
+ SELECTED_VALUE_SETTINGS_KEY, undefined);
+ if (selectedValue) {
+ selectedValue = JSON.parse(selectedValue);
+ for (var row of this.rows_) {
+ if (row.name === selectedValue.row) {
+ for (var coli = 1; coli < this.columns_.length; ++coli) {
+ var column = this.columns_[coli];
+ if (column.title === selectedValue.column) {
+ this.$.table.selectedTableRow = row;
+ this.$.table.selectedColumnIndex = coli;
+ return;
+ }
+ }
+ }
+ }
+ }
+ this.$.table.selectedTableRow = this.rows_[0];
+ this.$.table.selectedColumnIndex = 1;
+ },
+
+ /**
+ * Build table rows recursively from organized Values. The recursion stack
+ * of subRows is maintained in |hierarchy|.
+ *
+ * @param {!Object} organizedValues
+ * @param {!Array.<!Object>} hierarchy
+ */
+ buildRow_: function(organizedValues, hierarchy) {
+ tr.b.iterItems(organizedValues, function(name, value) {
+ if (value instanceof tr.v.Value) {
+ // This recursion base case corresponds to the recursion base case of
+ // organizeValues(). The last groupingCallback is getDisplayLabel,
+ // which defines the columns of the table.
+
+ // Merge Values up the grouping hierarchy.
+ for (var row of hierarchy) {
+ if (row.description === undefined)
+ row.description = value.description;
+
+ if (row.columns[name])
+ row.columns[name] = row.columns[name].merge(value);
+ else
+ row.columns[name] = value;
+ }
+
+ var row = hierarchy[hierarchy.length - 1];
+ this.addDiagnosticSubRows_(value, row, name);
+ } else {
+ // |value| is actually a nested organizedValues.
+ var row = {name: name, subRows: [], columns: {}};
+ hierarchy.push(row);
+ this.buildRow_(value, hierarchy);
+ hierarchy.pop();
+
+ if (hierarchy.length === 0)
+ this.rows_.push(row);
+ else
+ hierarchy[hierarchy.length - 1].subRows.push(row);
+ }
+ }, this);
+ },
+
+ get storyGroupingKeys() {
+ var keys = new Set();
+ for (var value of this.values) {
+ var iteration = tr.v.d.IterationInfo.getFromValue(value);
+ if (!(iteration instanceof tr.v.d.IterationInfo) ||
+ !iteration.storyGroupingKeys)
+ continue;
+
+ for (var key in iteration.storyGroupingKeys)
+ keys.add(key);
+ }
+ return [...keys.values()].sort();
+ },
+
+ /**
+ * A ValueSet is a flat set of Values. Value-set-table must present a
+ * hierarchical view. This method recursively groups this.values as an
+ * intermediate step towards building tableRows in buildRow_().
+ * {
+ * valueA: {
+ * benchmarkA: {
+ * storyA: {
+ * startA: {
+ * storysetRepeatCounterA: {
+ * storyRepeatCounterA: {
+ * displayLabelA: Value,
+ * displayLabelB: Value
+ * }
+ * }
+ * }
+ * }
+ * }
+ * }
+ * }
+ * @return {!Object}
+ */
+ get organizedValues_() {
+ var showingValues = this.$.show_all.checked ?
+ this.values : this.sourceValues_;
+ var values = [];
+ for (var value of showingValues)
+ if (this.summaryValuesByGuid_[value.guid] === undefined)
+ values.push(value);
+
+ var groupingCallbacks = [];
+ groupingCallbacks.push(v => v.name);
+ groupingCallbacks.push(
+ v => getIterationInfoField(v, 'benchmarkName', ''));
+ for (var storyGroupingKey of this.storyGroupingKeys) {
+ // Javascript closures are dumb.
+ groupingCallbacks.push((sgk => (
+ v => getStoryGroupingKeyLabel(v, sgk)))(storyGroupingKey));
+ }
+ groupingCallbacks.push(
+ v => getIterationInfoField(v, 'storyDisplayName', ''));
+ groupingCallbacks.push(
+ v => getIterationInfoField(v, 'benchmarkStartString', ''));
+ groupingCallbacks.push(
+ v => getIterationInfoField(v, 'storysetRepeatCounterLabel', 0));
+ groupingCallbacks.push(
+ v => getIterationInfoField(v, 'storyRepeatCounterLabel', 0));
+ groupingCallbacks.push(getDisplayLabel);
+
+ return organizeValues(values, groupingCallbacks, 0);
+ },
+
+ /* this.rows_ will look something like
+ * [
+ * {
+ * name: 'value name',
+ * columns: {
+ * displayLabelA: Value,
+ * displayLabelB: Value,
+ * },
+ * subRows: [
+ * {
+ * name: 'benchmark name if multiple',
+ * columns: {
+ * displayLabelA: Value,
+ * displayLabelB: Value,
+ * },
+ * subRows: [
+ * {
+ * name: 'story name if multiple',
+ * columns: {
+ * displayLabelA: Value,
+ * displayLabelB: Value,
+ * },
+ * subRows: [
+ * {
+ * name: 'benchmark start if multiple',
+ * columns: {
+ * displayLabelA: Value,
+ * displayLabelB: Value,
+ * },
+ * subRows: [
+ * {
+ * name: 'storyset repeat counter if multiple',
+ * columns: {
+ * displayLabelA: Value,
+ * displayLabelB: Value,
+ * },
+ * subRows: [
+ * {
+ * name: 'story repeat counter if multiple',
+ * columns: {
+ * displayLabelA: Value,
+ * displayLabelB: Value,
+ * },
+ * subRows: [
+ * {
+ * name: 'diagnostic map key',
+ * columns: {
+ * displayLabelA: Diagnostic,
+ * displayLabelB: Diagnostic,
+ * },
+ * }
+ * ]
+ * }
+ * ]
+ * }
+ * ]
+ * }
+ * ]
+ * }
+ * ]
+ * }
+ * ]
+ * }
+ * ]
+ *
+ * Any of those layers may be missing except 'value name'.
+ */
+ buildRows_: function() {
+ this.rows_ = [];
+ var hierarchy = [];
+ this.buildRow_(this.organizedValues_, hierarchy);
+ this.rows_ = this.rows_.filter(this.rowMatchesSearch_.bind(this));
+ },
+
+ get startTimesForDisplayLabels() {
+ var startTimesForDisplayLabels = {};
+ for (var value of this.values) {
+ if (this.summaryValuesByGuid_[value.guid])
+ continue;
+
+ var displayLabel = getDisplayLabel(value);
+ startTimesForDisplayLabels[displayLabel] = Math.min(
+ startTimesForDisplayLabels[displayLabel] || 0,
+ getIterationInfoField(
+ value, 'benchmarkStart', new Date(0)).getTime());
+ }
+ return startTimesForDisplayLabels;
+ },
+
+ get displayLabels() {
+ var startTimesForDisplayLabels = this.startTimesForDisplayLabels;
+ var displayLabels = Object.keys(startTimesForDisplayLabels);
+ displayLabels.sort(function(a, b) {
+ return startTimesForDisplayLabels[a] - startTimesForDisplayLabels[b];
+ });
+ return displayLabels;
+ },
+
+ buildColumn_: function(displayLabel) {
+ function getValueForValue(value) {
+ return value.numeric instanceof tr.v.Numeric ? value.numeric.average :
+ value.numeric.value;
+ }
+
+ return {
+ title: displayLabel,
+ align: tr.ui.b.TableFormat.ColumnAlignment.RIGHT,
+ supportsCellSelection: true,
+ selectable: true,
+
+ value: function(row) {
+ var cell = row.columns[displayLabel];
+ if (cell === undefined)
+ return '';
+
+ if (cell instanceof tr.v.NumericValue) {
+ if (this.$.table.selectedTableColumn &&
+ this.$.table.selectedTableColumn.title !== displayLabel) {
+ var referenceCell = row.columns[
+ this.$.table.selectedTableColumn.title];
+
+ if (referenceCell instanceof tr.v.NumericValue &&
+ cell.numeric.unit === referenceCell.numeric.unit) {
+ var significance = tr.v.Significance.DONT_CARE;
+
+ if (cell.numeric instanceof tr.v.Numeric &&
+ referenceCell.numeric instanceof tr.v.Numeric) {
+ significance = cell.numeric.getDifferenceSignificance(
+ referenceCell.numeric);
+ }
+
+ return tr.v.ui.createScalarSpan(
+ getValueForValue(cell) - getValueForValue(referenceCell),
+ {unit: cell.numeric.unit.correspondingDeltaUnit,
+ significance: significance});
+ }
+ }
+
+ return tr.v.ui.createScalarSpan(cell);
+ }
+ if (cell instanceof tr.v.d.Diagnostic) {
+ var span = tr.v.ui.createDiagnosticSpan(cell);
+ span.style.textAlign = 'left';
+ return span;
+ }
+ throw new Error('Invalid cell', cell);
+ }.bind(this),
+
+ cmp: function(rowA, rowB) {
+ var cellA = rowA.columns[displayLabel];
+ var cellB = rowB.columns[displayLabel];
+ if (!(cellA instanceof tr.v.NumericValue) ||
+ !(cellB instanceof tr.v.NumericValue)) {
+ return undefined;
+ }
+
+ var valueA = getValueForValue(cellA);
+ var valueB = getValueForValue(cellB);
+
+ // If a reference column is selected, compare the *differences*
+ // between the two cells and their references.
+ if (this.$.table.selectedTableColumn &&
+ this.$.table.selectedTableColumn.title !== displayLabel) {
+ var referenceColumn = this.$.table.selectedTableColumn.title;
+ var referenceCellA = rowA.columns[referenceColumn];
+ var referenceCellB = rowB.columns[referenceColumn];
+ if (referenceCellA instanceof tr.v.NumericValue &&
+ referenceCellB instanceof tr.v.NumericValue &&
+ cellA.numeric.unit === referenceCellA.numeric.unit &&
+ cellB.numeric.unit === referenceCellB.numeric.unit) {
+ valueA -= getValueForValue(referenceCellA);
+ valueB -= getValueForValue(referenceCellB);
+ }
+ }
+
+ return valueA - valueB;
+ }.bind(this)
+ };
+ },
+
+ buildColumns_: function() {
+ this.columns_ = [
+ {
+ title: 'Name',
+ align: tr.ui.b.TableFormat.ColumnAlignment.LEFT,
+ supportsCellSelection: false,
+
+ value: function(row) {
+ var nameEl = document.createElement('span');
+ Polymer.dom(nameEl).textContent = row.name;
+ if (row.description)
+ nameEl.title = row.description;
+ nameEl.style.textOverflow = 'ellipsis';
+ return nameEl;
+ },
+
+ cmp: (a, b) => a.name.localeCompare(b.name)
+ }
+ ];
+
+ for (var displayLabel of this.displayLabels)
+ this.columns_.push(this.buildColumn_(displayLabel));
}
});
- tr.ui.registerValueSetView('tr-v-ui-value-set-table');
+ tr.v.ui.registerValueSetView('tr-v-ui-value-set-table');
return {};
});
« no previous file with comments | « tracing/tracing/value/ui/scalar_span_test.html ('k') | tracing/tracing/value/ui/value_set_table_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698