| 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
|
| deleted file mode 100644
|
| index aa5e25a84e66e9874c14b7a9a46b16ae5dfe46dc..0000000000000000000000000000000000000000
|
| --- a/tracing/tracing/value/ui/value_set_table.html
|
| +++ /dev/null
|
| @@ -1,962 +0,0 @@
|
| -<!DOCTYPE html>
|
| -<!--
|
| -Copyright 2016 The Chromium Authors. All rights reserved.
|
| -Use of this source code is governed by a BSD-style license that can be
|
| -found in the LICENSE file.
|
| --->
|
| -
|
| -<link rel="import" href="/tracing/base/raf.html">
|
| -<link rel="import" href="/tracing/base/unit.html">
|
| -<link rel="import" href="/tracing/ui/base/grouping_table_groupby_picker.html">
|
| -<link rel="import" href="/tracing/ui/base/table.html">
|
| -<link rel="import" href="/tracing/value/ui/diagnostic_span.html">
|
| -<link rel="import" href="/tracing/value/ui/histogram_span.html">
|
| -<link rel="import" href="/tracing/value/ui/scalar_span.html">
|
| -<link rel="import" href="/tracing/value/value_set.html">
|
| -
|
| -<dom-module id="tr-v-ui-value-set-table-cell">
|
| - <template>
|
| - <style>
|
| - :host {
|
| - display: flex;
|
| - flex-direction: row;
|
| - }
|
| -
|
| - #missing, #empty, #unmergeable, #scalar {
|
| - flex-grow: 1;
|
| - }
|
| -
|
| - svg {
|
| - height: 1em;
|
| - }
|
| -
|
| - #open_histogram {
|
| - margin-left: 4px;
|
| - stroke-width: 0;
|
| - stroke: blue;
|
| - fill: blue;
|
| - }
|
| - :host(:hover) #open_histogram {
|
| - background: blue;
|
| - stroke: white;
|
| - fill: white;
|
| - }
|
| -
|
| - #scalar {
|
| - flex-grow: 1;
|
| - white-space: nowrap;
|
| - }
|
| -
|
| - #histogram {
|
| - flex-grow: 1;
|
| - }
|
| -
|
| - #close_histogram line {
|
| - stroke-width: 18;
|
| - stroke: black;
|
| - }
|
| - #close_histogram:hover {
|
| - background: black;
|
| - }
|
| - #close_histogram:hover line {
|
| - stroke: white;
|
| - }
|
| - </style>
|
| -
|
| - <span id="missing">(missing)</span>
|
| - <span id="empty">(empty)</span>
|
| - <span id="unmergeable">(unmergeable)</span>
|
| -
|
| - <tr-v-ui-scalar-span id="scalar" on-click="openHistogram_"></tr-v-ui-scalar-span>
|
| -
|
| - <svg viewbox="0 0 128 128" id="open_histogram" on-click="openHistogram_">
|
| - <rect x="16" y="24" width="32" height="16"/>
|
| - <rect x="16" y="56" width="96" height="16"/>
|
| - <rect x="16" y="88" width="64" height="16"/>
|
| - </svg>
|
| -
|
| - <span id="histogram"></span>
|
| -
|
| - <svg viewbox="0 0 128 128" id="close_histogram" on-click="closeHistogram_">
|
| - <line x1="28" y1="28" x2="100" y2="100"/>
|
| - <line x1="28" y1="100" x2="100" y2="28"/>
|
| - </svg>
|
| - </template>
|
| -</dom-module>
|
| -
|
| -<dom-module id="tr-v-ui-value-set-table">
|
| - <template>
|
| - <style>
|
| - :host {
|
| - display: block;
|
| - }
|
| -
|
| - #container {
|
| - flex-direction: column;
|
| - display: none;
|
| - }
|
| -
|
| - table-container {
|
| - margin-top: 5px;
|
| - display: flex;
|
| - min-height: 0px;
|
| - overflow-y: auto;
|
| - }
|
| -
|
| - #histogram {
|
| - display: none;
|
| - }
|
| -
|
| - #zero {
|
| - color: red;
|
| - /* value-set-table is used by both metrics-side-panel and results2.html.
|
| - * This font-size rule has no effect in results2.html, but improves
|
| - * legibility in the metrics-side-panel, which sets font-size in order to
|
| - * make this table denser.
|
| - */
|
| - font-size: initial;
|
| - }
|
| -
|
| - #search {
|
| - max-width: 20em;
|
| - margin-right: 20px;
|
| - }
|
| -
|
| - #controls {
|
| - white-space: nowrap;
|
| - }
|
| -
|
| - #reference_column_container * {
|
| - margin-right: 20px;
|
| - }
|
| - </style>
|
| -
|
| - <div id="zero">zero values</div>
|
| -
|
| - <div id="container">
|
| - <div id="controls">
|
| - <input id="search" placeholder="Find Histogram name" on-keyup="onSearch_">
|
| -
|
| - <span id="reference_column_container"></span>
|
| -
|
| - <input type="checkbox" id="show_all" on-change="onShowAllChange_" title="When unchecked, less important histograms are hidden.">
|
| - <label for="show_all" title="When unchecked, less important histograms are hidden.">Show all</label>
|
| - </div>
|
| -
|
| - <tr-ui-b-grouping-table-groupby-picker id="picker">
|
| - </tr-ui-b-grouping-table-groupby-picker>
|
| -
|
| - <table-container>
|
| - <tr-ui-b-table id="table"/>
|
| - </table-container>
|
| - </div>
|
| - </template>
|
| -</dom-module>
|
| -
|
| -<script>
|
| -'use strict';
|
| -tr.exportTo('tr.ui', function() {
|
| - /**
|
| - * Returns a closure that gets a story grouping key label from a Histogram.
|
| - *
|
| - * @param {string} storyGroupingKey
|
| - * @return {!function(tr.v.Histogram):string}
|
| - */
|
| - function makeStoryGroupingKeyLabelGetter(storyGroupingKey) {
|
| - return v => tr.v.d.IterationInfo.getStoryGroupingKeyLabel(
|
| - v, storyGroupingKey);
|
| - }
|
| -
|
| - var getDisplayLabel = tr.v.ValueSet.GROUPINGS.DISPLAY_LABEL.callback;
|
| -
|
| - var DEFAULT_POSSIBLE_GROUPS = [];
|
| - DEFAULT_POSSIBLE_GROUPS.push(new tr.v.HistogramGrouping(
|
| - tr.v.ValueSet.GROUPINGS.HISTOGRAM_NAME.key,
|
| - h => h.shortName || h.name));
|
| -
|
| - tr.b.iterItems(tr.v.ValueSet.GROUPINGS, function(name, group) {
|
| - // DISPLAY_LABEL is used to define the columns, so don't allow grouping
|
| - // rows by it.
|
| - // Override HISTOGRAM_NAME so that we can display shortName.
|
| - if (group !== tr.v.ValueSet.GROUPINGS.DISPLAY_LABEL &&
|
| - group !== tr.v.ValueSet.GROUPINGS.HISTOGRAM_NAME)
|
| - DEFAULT_POSSIBLE_GROUPS.push(group);
|
| - });
|
| -
|
| - var SHOW_ALL_SETTINGS_KEY = 'tr-v-ui-value-set-table-show-all';
|
| -
|
| - var UNMERGEABLE = '(unmergeable)';
|
| -
|
| - Polymer({
|
| - is: 'tr-v-ui-value-set-table-cell',
|
| -
|
| - created: function() {
|
| - this.histogram_ = undefined;
|
| - this.referenceHistogram_ = undefined;
|
| - this.histogramSpan_ = undefined;
|
| - },
|
| -
|
| - ready: function() {
|
| - this.addEventListener('click', this.onClick_.bind(this));
|
| - },
|
| -
|
| - onClick_: function(event) {
|
| - // Since the value-set-table's table doesn't support any kind of
|
| - // selection, clicking anywhere within a row that has subRows will
|
| - // expand/collapse that row, which can relayout the table and move things
|
| - // around. Prevent table relayout by preventing the tr-ui-b-table from
|
| - // receiving the click event.
|
| - event.stopPropagation();
|
| - },
|
| -
|
| - get histogram() {
|
| - return this.histogram_;
|
| - },
|
| -
|
| - /**
|
| - * @param {undefined|string|!tr.v.Histogram} h
|
| - */
|
| - set histogram(h) {
|
| - this.histogram_ = h;
|
| - this.updateContents_();
|
| - },
|
| -
|
| - /**
|
| - * @param {undefined|string|!tr.v.Histogram} rh
|
| - */
|
| - set referenceHistogram(rh) {
|
| - this.referenceHistogram_ = rh;
|
| - this.updateContents_();
|
| - },
|
| -
|
| - get referenceHistogram() {
|
| - return this.referenceHistogram_;
|
| - },
|
| -
|
| - get isHistogramOpen() {
|
| - return this.histogramSpan_ &&
|
| - (this.$.histogram.style.display === 'block');
|
| - },
|
| -
|
| - set isHistogramOpen(open) {
|
| - if (!this.histogram ||
|
| - this.histogram === UNMERGEABLE ||
|
| - !(this.histogram instanceof tr.v.Histogram) ||
|
| - (this.histogram.numValues === 0)) {
|
| - return;
|
| - }
|
| -
|
| - // Unfortunately, we can't use a css attribute for this since this stuff
|
| - // is tied up in all the possible states of this.histogram. See
|
| - // updateContents_().
|
| -
|
| - this.$.scalar.style.display = open ? 'none' : 'block';
|
| - this.$.open_histogram.style.display = open ? 'none' : 'block';
|
| -
|
| - this.$.close_histogram.style.display = open ? 'block' : 'none';
|
| - this.$.histogram.style.display = open ? 'block' : 'none';
|
| -
|
| - // Wait to create the histogram-span until the user wants to display it
|
| - // in order to speed up creating lots of value-set-table-cells when
|
| - // building the table.
|
| - // Wait to pass the Histogram to the histogram-span until it's displayed
|
| - // so that it can size its BarChart appropriately.
|
| - if (open && this.histogramSpan_ === undefined) {
|
| - this.histogramSpan_ = document.createElement('tr-v-ui-histogram-span');
|
| - this.$.histogram.appendChild(this.histogramSpan_);
|
| - this.histogramSpan_.referenceHistogram = this.referenceHistogram;
|
| - this.histogramSpan_.histogram = this.histogram;
|
| - }
|
| - },
|
| -
|
| - openHistogram_: function() {
|
| - this.isHistogramOpen = true;
|
| - },
|
| -
|
| - closeHistogram_: function() {
|
| - this.isHistogramOpen = false;
|
| - },
|
| -
|
| - updateContents_: function() {
|
| - this.$.empty.style.display = 'none';
|
| - this.$.unmergeable.style.display = 'none';
|
| - this.$.scalar.style.display = 'none';
|
| - this.$.histogram.style.display = 'none';
|
| - this.$.close_histogram.style.display = 'none';
|
| - this.$.open_histogram.style.visibility = 'hidden';
|
| -
|
| - if (!this.histogram) {
|
| - this.$.missing.style.display = 'block';
|
| - return;
|
| - }
|
| -
|
| - this.$.missing.style.display = 'none';
|
| -
|
| - if (this.histogram === UNMERGEABLE) {
|
| - this.$.unmergeable.style.display = 'block';
|
| - return;
|
| - }
|
| -
|
| - if (!(this.histogram instanceof tr.v.Histogram)) {
|
| - throw new Error('Invalid Histogram: ' + this.histogram);
|
| - }
|
| -
|
| - if (this.histogram.numValues === 0) {
|
| - this.$.empty.style.display = 'block';
|
| - return;
|
| - }
|
| -
|
| - this.$.open_histogram.style.display = 'block';
|
| - this.$.open_histogram.style.visibility = 'visible';
|
| - this.$.scalar.style.display = 'block';
|
| -
|
| - if ((this.referenceHistogram instanceof tr.v.Histogram) &&
|
| - (this.histogram.unit === this.referenceHistogram.unit) &&
|
| - (this.referenceHistogram.numValues > 0)) {
|
| - this.$.scalar.setValueAndUnit(
|
| - this.histogram.average - this.referenceHistogram.average,
|
| - this.histogram.unit.correspondingDeltaUnit);
|
| - this.$.scalar.significance = this.histogram.getDifferenceSignificance(
|
| - this.referenceHistogram);
|
| - } else {
|
| - this.$.scalar.setValueAndUnit(
|
| - this.histogram.average, this.histogram.unit);
|
| - }
|
| - }
|
| - });
|
| -
|
| - Polymer({
|
| - is: 'tr-v-ui-value-set-table',
|
| -
|
| - /**
|
| - * This can optionally depend on the ValueSet.
|
| - *
|
| - * @return {string}
|
| - */
|
| - get tabLabel() {
|
| - return 'Table';
|
| - },
|
| -
|
| - created: function() {
|
| - /** @type {undefined|!tr.v.ValueSet} */
|
| - this.values_ = undefined;
|
| -
|
| - /** @type {undefined|!tr.v.ValueSet} */
|
| - this.sourceValues_ = undefined;
|
| -
|
| - this.rows_ = undefined;
|
| - this.columns_ = undefined;
|
| -
|
| - this.updatingContents_ = false;
|
| - this.displayLabels_ = undefined;
|
| - this.referenceDisplayLabel_ = undefined;
|
| - },
|
| -
|
| - ready: function() {
|
| - this.$.table.zebra = true;
|
| - this.addEventListener('requestSelectionChange',
|
| - this.onRelatedValueSelected_.bind(this));
|
| - this.$.show_all.checked = tr.b.Settings.get(SHOW_ALL_SETTINGS_KEY, false);
|
| - this.$.picker.settingsKey = 'tr-v-ui-value-set-table-groupby-picker';
|
| -
|
| - this.$.picker.possibleGroups = DEFAULT_POSSIBLE_GROUPS.slice();
|
| - this.$.picker.defaultGroupKeys = [
|
| - tr.v.ValueSet.GROUPINGS.HISTOGRAM_NAME.key,
|
| - tr.v.ValueSet.GROUPINGS.STORY_NAME.key];
|
| - this.$.picker.addEventListener('current-groups-changed',
|
| - this.currentGroupsChanged_.bind(this));
|
| - },
|
| -
|
| - set groupingKeys(keys) {
|
| - this.$.picker.currentGroupKeys = keys;
|
| - },
|
| -
|
| - get groupingKeys() {
|
| - return this.$.picker.currentGroupKeys;
|
| - },
|
| -
|
| - get possibleGroupingKeys() {
|
| - return this.$.picker.possibleGroups.map(g => g.key);
|
| - },
|
| -
|
| - currentGroupsChanged_: function() {
|
| - if (this.updatingContents_)
|
| - return;
|
| -
|
| - if (this.$.picker.currentGroups.length === 0 &&
|
| - this.possibleGroupingKeys.length > 0) {
|
| - this.$.picker.currentGroupKeys = [this.$.picker.possibleGroups[0].key];
|
| - }
|
| - var expansionStates = undefined;
|
| - if (this.rows_)
|
| - expansionStates = this.getExpansionStates_();
|
| - this.updateContents_();
|
| - if (expansionStates)
|
| - this.setExpansionStates_(expansionStates);
|
| - },
|
| -
|
| - onShowAllChange_: function() {
|
| - if (this.updatingContents_)
|
| - return;
|
| -
|
| - tr.b.Settings.set(SHOW_ALL_SETTINGS_KEY, this.$.show_all.checked);
|
| - var expansionStates = this.getExpansionStates_();
|
| - this.updateContents_();
|
| - this.setExpansionStates_(expansionStates);
|
| - },
|
| -
|
| - getExpansionStates_: function() {
|
| - var table = this.$.table;
|
| - function recurse(row) {
|
| - var rowStates = {
|
| - expanded: table.getExpandedForTableRow(row),
|
| - cells: new Map(),
|
| - subRows: new Map()
|
| - };
|
| -
|
| - tr.b.iterItems(row.cells, function(displayLabel, cell) {
|
| - if (cell.isHistogramOpen) {
|
| - rowStates.cells.set(displayLabel, true);
|
| - }
|
| - });
|
| -
|
| - if (rowStates.expanded) {
|
| - for (var i = 0; i < row.subRows.length; ++i) {
|
| - rowStates.subRows.set(i, recurse(row.subRows[i]));
|
| - }
|
| - }
|
| - return rowStates;
|
| - }
|
| -
|
| - var states = new Map();
|
| - for (var i = 0; i < this.rows_.length; ++i) {
|
| - states.set(i, recurse(this.rows_[i]));
|
| - }
|
| - return states;
|
| - },
|
| -
|
| - setExpansionStates_: function(states) {
|
| - var table = this.$.table;
|
| - function recurse(row, rowStates) {
|
| - if (rowStates.expanded) {
|
| - table.setExpandedForTableRow(row, true);
|
| - }
|
| -
|
| - for (var [displayLabel, value] of rowStates.cells) {
|
| - var cell = row.cells[displayLabel];
|
| - if (cell) {
|
| - cell.isHistogramOpen = value;
|
| - }
|
| - }
|
| - for (var [key, value] of rowStates.subRows) {
|
| - var subRow = row.subRows[key];
|
| - recurse(subRow, value);
|
| - }
|
| - }
|
| -
|
| - for (var i = 0; i < this.rows_.length; ++i) {
|
| - var rowStates = states.get(i);
|
| - if (rowStates === undefined) {
|
| - continue;
|
| - }
|
| - var row = this.rows_[i];
|
| - recurse(row, rowStates);
|
| - }
|
| - },
|
| -
|
| - 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.Histogram))
|
| - 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;
|
| - row.cells[displayLabel].isHistogramOpen = true;
|
| - return;
|
| - }
|
| - 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) {
|
| - if (test === value) {
|
| - found = true;
|
| - this.$.show_all.checked = true;
|
| - this.onShowAllChange_();
|
| - this.onRelatedValueSelected_(event);
|
| - break;
|
| - }
|
| - }
|
| - },
|
| -
|
| - get values() {
|
| - return this.values_;
|
| - },
|
| -
|
| - /**
|
| - * @param {!tr.v.ValueSet} values
|
| - */
|
| - set values(values) {
|
| - this.values_ = values;
|
| - this.sourceValues_ = values ? values.sourceValues : new tr.v.ValueSet();
|
| - this.displayLabels_ = undefined;
|
| - this.referenceDisplayLabel_ = undefined;
|
| - this.maybeDisableShowAll_();
|
| - this.updateContents_();
|
| - },
|
| -
|
| - get referenceDisplayLabel() {
|
| - return this.referenceDisplayLabel_;
|
| - },
|
| -
|
| - set referenceDisplayLabel(reference) {
|
| - this.referenceDisplayLabel_ = reference;
|
| -
|
| - if (this.updatingContents_)
|
| - return;
|
| -
|
| - this.$.table.selectedTableColumnIndex = this.referenceDisplayLabel ?
|
| - 1 + this.displayLabels.indexOf(this.referenceDisplayLabel) : undefined;
|
| -
|
| - // Force the table to rebuild the cell values without forgetting which
|
| - // rows were expanded.
|
| - var expansionStates = this.getExpansionStates_();
|
| - this.$.table.tableRows = this.rows_;
|
| - this.setExpansionStates_(expansionStates);
|
| - },
|
| -
|
| - updateReferenceColumnSelector_: function() {
|
| - Polymer.dom(this.$.reference_column_container).textContent = '';
|
| -
|
| - if (this.displayLabels.length < 2)
|
| - return;
|
| -
|
| - var options = [{value: '', label: 'Select a reference column'}];
|
| - for (var displayLabel of this.displayLabels)
|
| - options.push({value: displayLabel, label: displayLabel});
|
| -
|
| - var settingsKey =
|
| - 'tr-v-ui-value-set-table-reference-display-label';
|
| - Polymer.dom(this.$.reference_column_container).appendChild(
|
| - tr.ui.b.createSelector(
|
| - this, 'referenceDisplayLabel', settingsKey, '', options));
|
| - },
|
| -
|
| - updateGroups_: function() {
|
| - var groups = DEFAULT_POSSIBLE_GROUPS.filter(function(group) {
|
| - // Remove groups for which there is only one value, except
|
| - // HISTOGRAM_NAME.
|
| - if (group.key === tr.v.ValueSet.GROUPINGS.HISTOGRAM_NAME.key)
|
| - return true;
|
| -
|
| - var values = new Set();
|
| - for (var value of this.values_) {
|
| - value = group.callback(value);
|
| - if (!value)
|
| - continue;
|
| -
|
| - values.add(value);
|
| - if (values.size > 1)
|
| - return true;
|
| - }
|
| - return false; // Prune this grouping.
|
| - }, this);
|
| -
|
| - // Add all storyGroupingKey groups for the current values.
|
| - for (var storyGroupingKey of this.storyGroupingKeys) {
|
| - groups.push(new tr.v.HistogramGrouping(
|
| - 'storyGroupingKey_' + storyGroupingKey,
|
| - makeStoryGroupingKeyLabelGetter(storyGroupingKey),
|
| - storyGroupingKey));
|
| - }
|
| -
|
| - // Save and restore current grouping keys in order to let
|
| - // |set groupingKeys| filter out the keys that are no longer in
|
| - // possibleGroups.
|
| - var groupingKeys = this.groupingKeys;
|
| - if (groupingKeys.length === 0 &&
|
| - groups.length > 0) {
|
| - // This can happen if the settings key contains an empty Array,
|
| - // which *should* never happen, but somehow sometimes does.
|
| - // When |groupingKeys| is empty, then the entire table will be
|
| - // mysteriously empty, so recover by ensuring that |groupingKeys| is
|
| - // never empty.
|
| - groupingKeys = [groups[0].key];
|
| - }
|
| - this.$.picker.possibleGroups = groups;
|
| - this.$.picker.currentGroupKeys = groupingKeys;
|
| -
|
| - this.$.picker.style.display = (groups.length === 1) ? 'none' : '';
|
| - },
|
| -
|
| - updateContents_: function() {
|
| - if (this.updatingContents_)
|
| - return;
|
| -
|
| - if (!this.values_ || (this.values_.length === 0)) {
|
| - this.$.container.style.display = '';
|
| - this.$.zero.style.display = '';
|
| - return;
|
| - }
|
| -
|
| - this.updatingContents_ = true;
|
| -
|
| - this.$.zero.style.display = 'none';
|
| - this.$.container.style.display = 'block';
|
| - this.$.table.style.display = '';
|
| -
|
| - this.updateReferenceColumnSelector_();
|
| - this.updateGroups_();
|
| - this.buildRows_();
|
| - this.buildColumns_();
|
| - this.$.table.tableColumns = this.columns_;
|
| - this.$.table.tableRows = this.rows_;
|
| - this.$.table.sortColumnIndex = 0;
|
| - this.$.table.rebuild();
|
| -
|
| - this.$.table.selectedTableColumnIndex = this.referenceDisplayLabel ?
|
| - 1 + this.displayLabels.indexOf(this.referenceDisplayLabel) : undefined;
|
| -
|
| - this.updatingContents_ = false;
|
| - },
|
| -
|
| - maybeDisableShowAll_: function() {
|
| - var allValuesAreSource = !this.values ||
|
| - (this.values.length === this.sourceValues_.length);
|
| -
|
| - // Disable show_all if all values are sourceValues.
|
| - // Re-enable show_all if this changes.
|
| - this.$.show_all.disabled = allValuesAreSource;
|
| -
|
| - // Check show_all if it is disabled.
|
| - // Do not automatically uncheck show_all.
|
| - if (this.$.show_all.disabled) {
|
| - this.$.show_all.checked = true;
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * 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) {
|
| - for (var [name, values] of organizedValues) {
|
| - if (values instanceof Array) {
|
| - // This recursion base case corresponds to the recursion base case of
|
| - // groupHistogramsRecursively(). The last groupingCallback is always
|
| - // getDisplayLabel, which defines the columns of the table and is
|
| - // unskippable.
|
| - for (var value of values) {
|
| - // Merge Values up the grouping hierarchy.
|
| - for (var row of hierarchy) {
|
| - if (!row.description) {
|
| - row.description = value.description;
|
| - }
|
| -
|
| - if (row.columns[name] === undefined) {
|
| - row.columns[name] = value;
|
| - continue;
|
| - }
|
| - if (row.columns[name] === UNMERGEABLE) {
|
| - continue;
|
| - }
|
| - if (!row.columns[name].canAddHistogram(value)) {
|
| - row.columns[name] = UNMERGEABLE;
|
| - continue;
|
| - }
|
| -
|
| - // Create a new Histogram with a new uuid instead of cloning
|
| - // either |value| or |row.columns[name]| so that we don't clone
|
| - // either Histogram's diagnostics.
|
| - // |value.name| might not necessarily equal |row.columns[name]|,
|
| - // but that shouldn't matter for this dom-module.
|
| - var merged = row.columns[name];
|
| - if (!merged.diagnostics.has(tr.v.MERGED_FROM_DIAGNOSTIC_KEY)) {
|
| - merged = merged.cloneEmpty();
|
| - merged.addHistogram(row.columns[name]);
|
| - }
|
| - merged.addHistogram(value);
|
| - row.columns[name] = merged;
|
| - }
|
| - }
|
| - } else if (values instanceof Map) {
|
| - // |values| is actually a nested organizedValues.
|
| - var row = {name: name, subRows: [], columns: {}, cells: {}};
|
| - hierarchy.push(row);
|
| - this.buildRow_(values, hierarchy);
|
| - hierarchy.pop();
|
| -
|
| - if (hierarchy.length === 0)
|
| - this.rows_.push(row);
|
| - else
|
| - hierarchy[hierarchy.length - 1].subRows.push(row);
|
| - }
|
| - }
|
| - },
|
| -
|
| - 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 showingValueSet = this.$.show_all.checked ?
|
| - this.values : this.sourceValues_;
|
| -
|
| - var groupings = this.$.picker.currentGroups.slice();
|
| - groupings.push(tr.v.ValueSet.GROUPINGS.DISPLAY_LABEL);
|
| -
|
| - function canSkipGrouping(grouping, groupedHistograms) {
|
| - // Never skip meaningful groupings.
|
| - if (groupedHistograms.size > 1)
|
| - return false;
|
| -
|
| - // Never skip the zero-th grouping.
|
| - if (grouping.key === groupings[0].key)
|
| - return false;
|
| -
|
| - // Never skip the grouping that defines the table columns.
|
| - if (grouping.key === tr.v.ValueSet.GROUPINGS.DISPLAY_LABEL.key)
|
| - return false;
|
| -
|
| - // Skip meaningless groupings.
|
| - return true;
|
| - }
|
| -
|
| - return showingValueSet.groupHistogramsRecursively(
|
| - groupings, canSkipGrouping);
|
| - },
|
| -
|
| - /* 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,
|
| - * }
|
| - * }
|
| - * ]
|
| - * }
|
| - * ]
|
| - * }
|
| - * ]
|
| - * }
|
| - * ]
|
| - * }
|
| - * ]
|
| - * }
|
| - * ]
|
| - *
|
| - * Any of those layers may be missing except 'value name'.
|
| - */
|
| - buildRows_: function() {
|
| - this.rows_ = [];
|
| - var hierarchy = [];
|
| - var organizedValues = this.organizedValues_;
|
| - this.buildRow_(organizedValues, hierarchy);
|
| - this.rows_ = this.rows_.filter(this.rowMatchesSearch_.bind(this));
|
| - },
|
| -
|
| - get startTimesForDisplayLabels() {
|
| - var startTimesForDisplayLabels = {};
|
| - for (var value of this.values) {
|
| - var displayLabel = getDisplayLabel(value);
|
| - startTimesForDisplayLabels[displayLabel] = Math.min(
|
| - startTimesForDisplayLabels[displayLabel] || 0,
|
| - tr.v.d.IterationInfo.getField(
|
| - value, 'benchmarkStart', new Date(0)).getTime());
|
| - }
|
| - return startTimesForDisplayLabels;
|
| - },
|
| -
|
| - get displayLabels() {
|
| - if (this.displayLabels_ === undefined) {
|
| - var startTimesForDisplayLabels = this.startTimesForDisplayLabels;
|
| - this.displayLabels_ = Object.keys(startTimesForDisplayLabels);
|
| - this.displayLabels_.sort(function(a, b) {
|
| - return startTimesForDisplayLabels[a] - startTimesForDisplayLabels[b];
|
| - });
|
| - }
|
| - return this.displayLabels_;
|
| - },
|
| -
|
| - buildColumn_: function(displayLabel) {
|
| - return {
|
| - title: displayLabel,
|
| - align: tr.ui.b.TableFormat.ColumnAlignment.RIGHT,
|
| -
|
| - value: row => {
|
| - var cell = document.createElement('tr-v-ui-value-set-table-cell');
|
| - cell.histogram = row.columns[displayLabel];
|
| - if (this.referenceDisplayLabel &&
|
| - this.referenceDisplayLabel !== displayLabel) {
|
| - cell.referenceHistogram = row.columns[this.referenceDisplayLabel];
|
| - }
|
| - row.cells[displayLabel] = cell;
|
| - return cell;
|
| - },
|
| -
|
| - cmp: (rowA, rowB) => {
|
| - var cellA = rowA.columns[displayLabel];
|
| - var cellB = rowB.columns[displayLabel];
|
| - if (!(cellA instanceof tr.v.Histogram) ||
|
| - !(cellB instanceof tr.v.Histogram)) {
|
| - return undefined;
|
| - }
|
| -
|
| - var valueA = cellA.average;
|
| - var valueB = cellB.average;
|
| -
|
| - // If a reference column is selected, compare the absolute deltas
|
| - // between the two cells and their references.
|
| - if (this.referenceDisplayLabel &&
|
| - this.referenceDisplayLabel !== displayLabel) {
|
| - var referenceCellA = rowA.columns[this.referenceDisplayLabel];
|
| - var referenceCellB = rowB.columns[this.referenceDisplayLabel];
|
| - if (referenceCellA instanceof tr.v.Histogram &&
|
| - referenceCellB instanceof tr.v.Histogram &&
|
| - cellA.unit === referenceCellA.unit &&
|
| - cellB.unit === referenceCellB.unit) {
|
| - valueA -= referenceCellA.average;
|
| - valueB -= referenceCellB.average;
|
| - }
|
| - }
|
| -
|
| - return valueA - valueB;
|
| - }
|
| - };
|
| - },
|
| -
|
| - buildColumns_: function() {
|
| - this.columns_ = [
|
| - {
|
| - title: 'Name',
|
| -
|
| - value: function(row) {
|
| - var nameEl = document.createElement('span');
|
| - Polymer.dom(nameEl).textContent = row.name;
|
| - if (row.description) {
|
| - nameEl.title = row.description;
|
| - }
|
| - nameEl.style.whiteSpace = 'nowrap';
|
| - return nameEl;
|
| - },
|
| -
|
| - cmp: (a, b) => a.name.localeCompare(b.name)
|
| - }
|
| - ];
|
| -
|
| - for (var displayLabel of this.displayLabels) {
|
| - this.columns_.push(this.buildColumn_(displayLabel));
|
| - }
|
| - }
|
| - });
|
| -
|
| - return {};
|
| -});
|
| -</script>
|
|
|