aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--WORKSPACE2
-rw-r--r--tensorflow/tensorboard/TAG2
-rw-r--r--tensorflow/tensorboard/dist/tf-tensorboard.html464
3 files changed, 454 insertions, 14 deletions
diff --git a/WORKSPACE b/WORKSPACE
index 36d382095b..a0aaefa6f5 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -70,7 +70,7 @@ new_git_repository(
name = "iron_a11y_keys_behavior",
build_file = "bower.BUILD",
remote = "https://github.com/polymerelements/iron-a11y-keys-behavior.git",
- tag = "v1.1.5",
+ tag = "v1.1.6",
)
new_git_repository(
diff --git a/tensorflow/tensorboard/TAG b/tensorflow/tensorboard/TAG
index aabe6ec390..2bd5a0a98a 100644
--- a/tensorflow/tensorboard/TAG
+++ b/tensorflow/tensorboard/TAG
@@ -1 +1 @@
-21
+22
diff --git a/tensorflow/tensorboard/dist/tf-tensorboard.html b/tensorflow/tensorboard/dist/tf-tensorboard.html
index 77e224dd20..1c0297dbdb 100644
--- a/tensorflow/tensorboard/dist/tf-tensorboard.html
+++ b/tensorflow/tensorboard/dist/tf-tensorboard.html
@@ -3963,6 +3963,7 @@ var tf;
}
return OpNodeImpl;
}());
+ graph_1.OpNodeImpl = OpNodeImpl;
;
function createMetanode(name, opt) {
if (opt === void 0) { opt = {}; }
@@ -4171,6 +4172,7 @@ var tf;
};
return MetanodeImpl;
}());
+ graph_1.MetanodeImpl = MetanodeImpl;
;
function createMetaedge(v, w) {
return new MetaedgeImpl(v, w);
@@ -4527,6 +4529,7 @@ var tf;
var parts = name.split(graph_1.NAMESPACE_DELIM);
return name + graph_1.NAMESPACE_DELIM + '(' + parts[parts.length - 1] + ')';
}
+ graph_1.getStrictName = getStrictName;
/**
* For each op node (embedding or non-embedding), rename it if there is a
* non-embedding node under its namespace. For example, assume node name 'A'.
@@ -6494,6 +6497,7 @@ var tf;
this.index[hierarchy.root.name] = this.root;
this.buildSubhierarchy(hierarchy.root.name);
this.root.expanded = true;
+ this.traceInputs = false;
}
RenderGraphInfo.prototype.computeScales = function () {
this.deviceColorMap = d3.scale.ordinal()
@@ -8788,10 +8792,333 @@ var tf;
d3.rgb(fill).darker().toString();
}
node_1.getStrokeForFill = getStrokeForFill;
+ /**
+ * Finds selected node and highlights all nodes which are providing direct
+ * or indirect input to the node and all edges connecting these nodes
+ * together and to the selected node.
+ *
+ * @param renderGraphInfo Information on the rendered state of the graph.
+ */
+ function traceInputs(renderGraphInfo) {
+ // Reset all styling.
+ d3.selectAll('.input-highlight').classed('input-highlight', false);
+ d3.selectAll('.non-input').classed('non-input', false);
+ d3.selectAll('.input-parent').classed('input-parent', false);
+ d3.selectAll('.input-child').classed('input-child', false);
+ d3.selectAll('.input-edge-highlight').classed('input-edge-highlight', false);
+ d3.selectAll('.non-input-edge-highlight')
+ .classed('non-input-edge-highlight', false);
+ d3.selectAll('.input-highlight-selected')
+ .classed('input-highlight-selected', false);
+ // Extract currently selected node. Return if input tracing disabled or no
+ // node is selected.
+ var selectedNodeSelectorString = 'g.node.selected,g.op.selected';
+ var node = d3.select(selectedNodeSelectorString);
+ var currentNode = undefined;
+ if (renderGraphInfo && renderGraphInfo.traceInputs && node && node[0] &&
+ node[0][0]) {
+ currentNode = node[0][0];
+ }
+ else {
+ return;
+ }
+ var nodeName = currentNode.getAttribute('data-name');
+ var opNodes = _getAllContainedOpNodes(nodeName, renderGraphInfo);
+ var allTracedNodes = {};
+ _.each(opNodes, function (nodeInstance) {
+ allTracedNodes =
+ traceAllInputsOfOpNode(renderGraphInfo, nodeInstance, allTracedNodes);
+ });
+ d3.selectAll(selectedNodeSelectorString).classed({
+ // Remove the input-highlight from the selected node.
+ 'input-highlight': false,
+ // Add input-highlight-selected class to selected node, which allows
+ // treating the selected not as a special case of an input node.
+ 'input-highlight-selected': true
+ });
+ // Highlight all parent nodes of each OpNode as input parent to allow
+ // specific highlighting.
+ var highlightedNodes = Object.keys(allTracedNodes);
+ var visibleNodes = _findVisibleParentsFromOpNodes(renderGraphInfo, highlightedNodes);
+ _markParentsOfNodes(visibleNodes);
+ // Attach class to all non-input nodes and edges for styling.
+ d3.selectAll('g.node:not(.selected):not(.input-highlight)' +
+ ':not(.input-parent):not(.input-children)')
+ .classed('non-input', true)
+ .each(function (d) {
+ // Mark all nodes with the specified name as non-inputs. This
+ // results in Annotation nodes which are attached to inputs to be
+ // tagged as well.
+ var nodeName = d.node.name;
+ d3.selectAll("[data-name=\"" + nodeName + "\"]").classed('non-input', true);
+ });
+ d3.selectAll('g.edge:not(.input-edge-highlight)')
+ .classed('non-input-edge-highlight', true);
+ }
+ node_1.traceInputs = traceInputs;
+ /**
+ * Recursively find all op nodes contained by the node identified by the
+ * provided name.
+ * @param nodeName The meta or op node of which the OpNode instances are
+ * required.
+ * @param renderGraphInfo The rendered graph information object.
+ * @returns {Array} An array of OpNodeImpl instances.
+ */
+ function _getAllContainedOpNodes(nodeName, renderGraphInfo) {
+ var opNodes = [];
+ // Get current node.
+ var node = renderGraphInfo.getNodeByName(nodeName);
+ // If node is already OpNode then return the node plus its input embeddings.
+ if (node instanceof tf.graph.OpNodeImpl) {
+ return [node].concat(node.inEmbeddings);
+ }
+ // Otherwise, make recursive call for each node contained by the GroupNode.
+ var childNodeNames = node.metagraph.nodes();
+ _.each(childNodeNames, function (childNodeName) {
+ opNodes =
+ opNodes.concat(_getAllContainedOpNodes(childNodeName, renderGraphInfo));
+ });
+ return opNodes;
+ }
+ node_1._getAllContainedOpNodes = _getAllContainedOpNodes;
+ function traceAllInputsOfOpNode(renderGraphInfo, startNode, allTracedNodes) {
+ // To prevent infinite loops due to cyclical relationships and improving
+ // performance by tracing OpNode which is input to 2+ nodes only once.
+ if (allTracedNodes[startNode.name]) {
+ return allTracedNodes;
+ }
+ else {
+ allTracedNodes[startNode.name] = true;
+ }
+ // Extract the inputs.
+ var inputs = startNode.inputs;
+ // Get visible parent.
+ var currentVisibleParent = getVisibleParent(renderGraphInfo, startNode);
+ // Mark as input node.
+ d3.select(".node[data-name=\"" + currentVisibleParent.name + "\"]")
+ .classed('input-highlight', true);
+ // Find the visible parent of each input.
+ var visibleInputs = {};
+ _.each(inputs, function (nodeInstance) {
+ var resolvedNode = renderGraphInfo.getNodeByName(nodeInstance.name);
+ if (resolvedNode === undefined) {
+ // Node could not be found in rendered Hierarchy, which happens when
+ // tracing inputs of a SummaryNode.
+ return;
+ }
+ // Ensure node is resolved to OpNode if name collision with Metanode exists.
+ if (resolvedNode instanceof graph.MetanodeImpl) {
+ var resolvedNodeName = tf.graph.getStrictName(resolvedNode.name);
+ resolvedNode = renderGraphInfo.getNodeByName(resolvedNodeName);
+ }
+ var visibleParent = getVisibleParent(renderGraphInfo, resolvedNode);
+ // Append OpNode to visible parent entry.
+ var visibleInputsEntry = visibleInputs[visibleParent.name];
+ if (visibleInputsEntry) {
+ visibleInputsEntry.opNodes.push(resolvedNode);
+ }
+ else {
+ visibleInputs[visibleParent.name] = {
+ visibleParent: visibleParent,
+ opNodes: [resolvedNode]
+ };
+ }
+ });
+ // Find all parents of the start node.
+ var startNodeParents = {};
+ var indexedStartNodeParents = [currentVisibleParent];
+ startNodeParents[currentVisibleParent.name] = {
+ traced: false,
+ index: 0,
+ connectionEndpoints: []
+ };
+ var currentNode = currentVisibleParent;
+ for (var index = 1; currentNode.name !== tf.graph.ROOT_NAME; index++) {
+ currentNode = currentNode.parentNode;
+ startNodeParents[currentNode.name] = {
+ traced: false,
+ index: index,
+ connectionEndpoints: []
+ };
+ indexedStartNodeParents[index] = currentNode;
+ }
+ // Find first mutual parent of each input node and highlight connection.
+ _.forOwn(visibleInputs, function (visibleParentInfo, key) {
+ var nodeInstance = visibleParentInfo.visibleParent;
+ // Make recursive call for each input-OpNode contained by the visible
+ // parent.
+ _.each(visibleParentInfo.opNodes, function (opNode) {
+ allTracedNodes =
+ traceAllInputsOfOpNode(renderGraphInfo, opNode, allTracedNodes);
+ });
+ if (nodeInstance.name !== currentVisibleParent.name) {
+ _createVisibleTrace(nodeInstance, startNodeParents, indexedStartNodeParents);
+ }
+ });
+ return allTracedNodes;
+ }
+ node_1.traceAllInputsOfOpNode = traceAllInputsOfOpNode;
+ /**
+ * Colors the edges to connect the passed node to the start node. This is
+ * done by:
+ *
+ * a) Finding the first (visible) common parent in the rendered
+ * hierarchy.
+ * NB: There are 2 types of connections:
+ * 1) Direct connections between node A
+ * and B, marked below as II,
+ * 2) Connections from any node A to its parent, A'. Marked below as I and III.
+ * For type 2 connection you need to know the inner-nested node, the
+ * direct parent, and the ultimate destination of the connection.
+ *
+ * A_parent B_parent
+ * +--------+ +---------+
+ * | | | |
+ * | +--+ I| II |III+--+ |
+ * | |A +----------\x3e+B | |
+ * | +--+ | | +--+ |
+ * | | | |
+ * +--------+ +---------+
+ *
+ *
+ * b) Highlighting the direct connection between the parents of A and B,
+ * called A_parent and B_parent, s.t. A_parent and B_parent are children of the
+ * mutual parent of A and B found in a), marked above as II.
+ *
+ * c) Highlighting the connection from A to A_parent and B to B_parent
+ * (through all layers of parents between A and A_parent and B and B_parent,
+ * respectively). Marked above as I and III.
+ *
+ * @param nodeInstance The instance of the node to use as destination node, B.
+ * @param startNodeParents Map of startNodeParent names to information objects
+ * about the parent.
+ * @param indexedStartNodeParents An array of all parents of the start node.
+ * This is required to find the child of the mutual parent which is a parent
+ * of the start node.
+ * @private
+ */
+ function _createVisibleTrace(nodeInstance, startNodeParents, indexedStartNodeParents) {
+ var currentNode = nodeInstance;
+ var previousNode = nodeInstance;
+ // Ascend through parents until a mutual parent is found with the start
+ // node.
+ var destinationParentPairs = [];
+ while (!startNodeParents[currentNode.name]) {
+ if (previousNode.name !== currentNode.name) {
+ destinationParentPairs.push([previousNode, currentNode]);
+ }
+ previousNode = currentNode;
+ currentNode = currentNode.parentNode;
+ }
+ // Connection between nodes is drawn between the parents of each
+ // respective node, both of which share the mutual parent.
+ var startNodeIndex = startNodeParents[currentNode.name].index;
+ var startNodeName = indexedStartNodeParents[Math.max(startNodeIndex - 1, 0)].name;
+ var startNodeTopParentName = startNodeName;
+ var targetNodeTopParentName = previousNode.name;
+ var endNodeName = previousNode.name;
+ d3.selectAll("[data-edge=\"" + endNodeName + "--" + startNodeName + "\"]")
+ .classed('input-edge-highlight', true);
+ // Trace up the parents of the input.
+ _.each(destinationParentPairs, function (value) {
+ var inner = value[0];
+ var outer = value[1];
+ var edgeSelector = ("[data-edge=\"" + inner.name + "--" + startNodeTopParentName) +
+ ("~~" + outer.name + "~~OUT\"]");
+ d3.selectAll(edgeSelector).classed('input-edge-highlight', true);
+ });
+ // Trace up the parents of the start node.
+ for (var index = 1; index < startNodeIndex; index++) {
+ var inner = indexedStartNodeParents[index - 1];
+ var outer = indexedStartNodeParents[index];
+ var edgeSelector = ("[data-edge=\"" + targetNodeTopParentName + "~~" + outer.name) +
+ ("~~IN--" + inner.name + "\"]");
+ d3.selectAll(edgeSelector).classed('input-edge-highlight', true);
+ }
+ }
+ /**
+ * Creates map { [name: string] -> Node } of all visible / rendered parents
+ * of the nodes identified by the node names passed in.
+ *
+ * @param renderGraphInfo The information on the rendered graph.
+ * @param nodeNames String array of node names.
+ * @returns {[nodeName: string]: Node}
+ * @private
+ */
+ function _findVisibleParentsFromOpNodes(renderGraphInfo, nodeNames) {
+ var visibleParents = {};
+ _.each(nodeNames, function (nodeName) {
+ var currentNode = renderGraphInfo.getNodeByName(nodeName);
+ var visibleParent = getVisibleParent(renderGraphInfo, currentNode);
+ visibleParents[visibleParent.name] = visibleParent;
+ });
+ return visibleParents;
+ }
+ /**
+ * Traverse through the parents of all nodes in the list and mark each
+ * encountered node as input-parent.
+ * @param visibleNodes Map of input nodes, have to be visible/rendered when
+ * called.
+ * @private
+ */
+ function _markParentsOfNodes(visibleNodes) {
+ _.forOwn(visibleNodes, function (nodeInstance) {
+ // Mark all parents of the node as input-parents.
+ var currentNode = nodeInstance;
+ while (currentNode.name !== tf.graph.ROOT_NAME) {
+ var renderedElement = d3.select(".node[data-name=\"" + currentNode.name + "\"]");
+ // Only mark the element as a parent node to an input if it is not
+ // marked as input node itself.
+ if (renderedElement[0][0] &&
+ !renderedElement.classed('input-highlight') &&
+ !renderedElement.classed('selected') &&
+ // OpNode only parent if start node is embedded node, in which case
+ // the OpNode should be faded as well.
+ !renderedElement.classed('op')) {
+ renderedElement.classed('input-parent', true);
+ }
+ currentNode = currentNode.parentNode;
+ }
+ });
+ }
+ /**
+ * Find the parent of the passed in op node which is expanded. This is done
+ * by going through all parents until the parent's parent is expanded, thus
+ * finding the the first unexpanded parent which is rendered on the screen.
+ * @param renderGraphInfo The graph info object used to gain access to the
+ * render info of the parents.
+ * @param currentNode The node whose parent is to be found.
+ * @returns Node
+ */
+ function getVisibleParent(renderGraphInfo, currentNode) {
+ var found = false;
+ var currentParent = currentNode;
+ while (!found) {
+ // Get parent element, to extract name.
+ currentNode = currentParent;
+ currentParent = currentNode.parentNode;
+ if (currentParent === undefined) {
+ found = true;
+ }
+ else {
+ var renderNode = renderGraphInfo.getRenderNodeByName(currentParent.name);
+ // Found if node is rendered on the screen (renderNode truthy), and
+ // the parent is either expanded (i.e. it is a metanode or seriesnode)
+ // or the parent is an OpNode in which case currentNode is an embedded
+ // node which has another OpNode as parent.
+ if (renderNode &&
+ (renderNode.expanded || currentParent instanceof graph.OpNodeImpl)) {
+ found = true;
+ }
+ }
+ } // Close while loop.
+ return currentNode;
+ }
+ node_1.getVisibleParent = getVisibleParent;
})(node = scene.node || (scene.node = {}));
})(scene = graph.scene || (graph.scene = {}));
})(graph = tf.graph || (tf.graph = {}));
-})(tf || (tf = {})); // close module
+})(tf || (tf = {})); // Close module.
</script>
<script>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
@@ -10137,6 +10464,7 @@ Polymer({
::content .faded rect,
::content .faded ellipse,
::content .faded path,
+::content .faded use,
::content #rectHatch line,
::content #ellipseHatch line {
color: #e0d4b3 !important;
@@ -10153,7 +10481,8 @@ Polymer({
fill: url("#rectHatch") !important;
}
-::content .faded ellipse {
+::content .faded ellipse,
+::content .faded use {
fill: url("#ellipseHatch") !important;
}
@@ -10161,6 +10490,81 @@ Polymer({
opacity: 0;
}
+/* Rules used for input-tracing. */
+::content .input-highlight > * > rect,
+::content .input-highlight > * > ellipse,
+::content .input-highlight > * > use
+{
+ fill: white;
+ stroke: #ff9800 !important;
+}
+
+/* - Faded non-input styling */
+::content .non-input > * > rect,
+::content .non-input > * > ellipse,
+::content .non-input > * > use,
+/* For Const nodes. */
+::content .non-input > * > .constant:not([class*="input-highlight"]) >
+ .annotation-node > ellipse,
+/* For styling of annotation nodes of non-input nodes. */
+::content .non-input > g > .annotation > .annotation-node > rect {
+ stroke: #e0d4b3 !important;
+ stroke-width: inherit;
+ stroke-dasharray: inherit;
+}
+
+
+::content .non-input path {
+ visibility: hidden;
+}
+
+::content .non-input > .nodeshape > rect,
+::content .non-input > .annotation-node > rect,
+/* For styling of annotation nodes of non-input nodes. */
+::content .non-input > g > .annotation > .annotation-node > rect
+{
+ fill: url("#rectHatch") !important;
+}
+
+::content .non-input ellipse,
+::content .non-input use {
+ fill: url("#ellipseHatch") !important;
+}
+
+::content .non-input > text {
+ opacity: 0;
+}
+
+::content .non-input .annotation > .annotation-edge {
+ marker-end: url("#annotation-arrowhead-faded");
+}
+
+::content .non-input .annotation > .annotation-edge.refline {
+ marker-start: url("#ref-annotation-arrowhead-faded");
+}
+
+/* Input edges. */
+::content .input-edge-highlight > text {
+ fill: black !important;
+}
+::content .input-edge-highlight > path,
+::content .input-highlight > .in-annotations > .annotation > .annotation-edge,
+::content .input-highlight-selected > .in-annotations > .annotation >
+.annotation-edge {
+ stroke: #999 !important;
+}
+
+/* Non-input edges. */
+::content .non-input-edge-highlight,
+::content .non-input > g > .annotation > path,
+/* Annotation styles (label and edges respectively). */
+::content .non-input > g >
+.annotation:not(.input-highlight):not(.input-highlight-selected) >
+.annotation-label
+/*.annotation-edge*/
+{
+ visibility: hidden;
+}
/* --- Op Node --- */
@@ -10689,6 +11093,7 @@ Polymer({
tf.graph.util.time('tf-graph-scene (build scene):', function() {
tf.graph.scene.buildGroup(d3.select(this.$.root), renderHierarchy.root, this);
tf.graph.scene.addGraphClickListener(this.$.svg, this);
+ tf.graph.scene.node.traceInputs(renderHierarchy);
}.bind(this));
// Update the minimap again when the graph is done animating.
setTimeout(function() {
@@ -10853,6 +11258,13 @@ Polymer({
}, this);
},
+ /**
+ * Handles new node selection. 1) Updates the selected-state of each node,
+ * 2) triggers input tracing.
+ * @param selectedNode {string} The name of the newly selected node.
+ * @param oldSelectedNode {string} The name of the previously selected node.
+ * @private
+ */
_selectedNodeChanged: function(selectedNode, oldSelectedNode) {
if (selectedNode === oldSelectedNode) {
return;
@@ -10865,9 +11277,13 @@ Polymer({
this._updateNodeState(oldSelectedNode);
}
+ tf.graph.scene.node.traceInputs(this.renderHierarchy);
+
if (!selectedNode) {
return;
}
+
+
// Update the minimap to reflect the highlighted (selected) node.
this.minimap.update();
var node = this.renderHierarchy.hierarchy.node(selectedNode);
@@ -12296,10 +12712,10 @@ paper-progress {
</template>
<div class$="[[_getContainerClass(progress)]]">
<div id="main">
- <tf-graph id="graph" graph-hierarchy="{{graphHierarchy}}" basic-graph="[[graph]]" hierarchy-params="[[hierarchyParams]]" render-hierarchy="{{_renderHierarchy}}" devices-for-stats="[[devicesForStats]]" stats="[[stats]]" selected-node="{{_selectedNode}}" highlighted-node="{{_highlightedNode}}" color-by="[[colorBy]]" color-by-params="{{colorByParams}}" progress="{{progress}}"></tf-graph>
+ <tf-graph id="graph" graph-hierarchy="{{graphHierarchy}}" basic-graph="[[graph]]" hierarchy-params="[[hierarchyParams]]" render-hierarchy="{{renderHierarchy}}" devices-for-stats="[[devicesForStats]]" stats="[[stats]]" selected-node="{{_selectedNode}}" highlighted-node="{{_highlightedNode}}" color-by="[[colorBy]]" color-by-params="{{colorByParams}}" progress="{{progress}}"></tf-graph>
</div>
<div id="info">
- <tf-graph-info id="graph-info" title="selected" graph-hierarchy="[[graphHierarchy]]" render-hierarchy="[[_renderHierarchy]]" graph="[[graph]]" selected-node="{{_selectedNode}}" selected-node-include="{{_selectedNodeInclude}}" highlighted-node="{{_highlightedNode}}" color-by="[[colorBy]]" color-by-params="[[colorByParams]]"></tf-graph-info>
+ <tf-graph-info id="graph-info" title="selected" graph-hierarchy="[[graphHierarchy]]" render-hierarchy="[[renderHierarchy]]" graph="[[graph]]" selected-node="{{_selectedNode}}" selected-node-include="{{_selectedNodeInclude}}" highlighted-node="{{_highlightedNode}}" color-by="[[colorBy]]" color-by-params="[[colorByParams]]"></tf-graph-info>
</div>
<div class="context-menu"></div>
</div>
@@ -12324,14 +12740,17 @@ Polymer({
colorBy: String,
colorByParams: {
type: Object,
- notify: true,
+ notify: true
+ },
+ renderHierarchy: {
+ type: Object,
+ notify: true
},
// Private API: Data routing between child components.
_selectedNode: String,
// The enum value of the include property of the selected node.
_selectedNodeInclude: Number,
- _highlightedNode: String,
- _renderHierarchy: Object,
+ _highlightedNode: String
},
listeners: {
'node-toggle-extract': '_nodeToggleExtract'
@@ -12618,6 +13037,14 @@ span.counter {
</div>
</div>
<div class="control-holder">
+ <div class="title">
+ Trace inputs
+ </div>
+ <paper-toggle-button id="trace-inputs">
+
+ </paper-toggle-button>
+ </div>
+ <div class="control-holder">
<div class="title">Color</div>
<paper-radio-group selected="{{colorBy}}">
<paper-radio-button name="structure">Structure</paper-radio-button>
@@ -12846,6 +13273,10 @@ Polymer({
type: Array,
observer: '_datasetsChanged'
},
+ renderHierarchy: {
+ type: Object,
+ notify: true,
+ },
metadataTags: {
type: Array,
computed: '_getMetadataTags(selectedDataset, datasets)'
@@ -12870,6 +13301,14 @@ Polymer({
computed: '_getCurrentGradientParams(colorByParams, colorBy)'
}
},
+ listeners: {
+ 'trace-inputs.change': '_traceInputToggleChanged'
+ },
+ _traceInputToggleChanged: function(event) {
+ // Flip the state of the trace inputs flag.
+ this.renderHierarchy.traceInputs = event.target.active;
+ tf.graph.scene.node.traceInputs(this.renderHierarchy);
+ },
_statsNotNull: function(stats) {
return stats != null;
},
@@ -12988,6 +13427,7 @@ Polymer({
if (this.datasets) {
this.set('selectedMetadataTag', -1);
this.set('colorBy', 'structure');
+ this.$['trace-inputs'].active = false; // Set trace input to off-state.
this._setDownloadFilename(this.datasets[newDataset].path);
}
},
@@ -13019,12 +13459,11 @@ Polymer({
<template is="dom-if" if="[[!_datasetsEmpty(_datasets)]]">
<tf-dashboard-layout>
<div class="sidebar">
- <tf-graph-controls id="controls" devices-for-stats="{{_devicesForStats}}" color-by-params="[[_colorByParams]]" stats="[[_stats]]" color-by="{{_colorBy}}" ,="" datasets="[[_datasets]]" selected-dataset="{{_selectedDataset}}" selected-file="{{_selectedFile}}" selected-metadata-tag="{{_selectedMetadataTag}}"></tf-graph-controls>
- <tf-graph-loader id="loader" datasets="[[_datasets]]" ,="" selected-dataset="[[_selectedDataset]]" selected-metadata-tag="[[_selectedMetadataTag]]" selected-file="[[_selectedFile]]" out-graph-hierarchy="{{_graphHierarchy}}" out-graph="{{_graph}}" out-stats="{{_stats}}" progress="{{_progress}}" out-hierarchy-params="{{_hierarchyParams}}"></tf-graph-loader>
+ <tf-graph-controls id="controls" devices-for-stats="{{_devicesForStats}}" color-by-params="[[_colorByParams]]" stats="[[_stats]]" color-by="{{_colorBy}}" datasets="[[_datasets]]" render-hierarchy="[[_renderHierarchy]]" selected-dataset="{{_selectedDataset}}" selected-file="{{_selectedFile}}" selected-metadata-tag="{{_selectedMetadataTag}}"></tf-graph-controls>
+ <tf-graph-loader id="loader" datasets="[[_datasets]]" selected-dataset="[[_selectedDataset]]" selected-metadata-tag="[[_selectedMetadataTag]]" selected-file="[[_selectedFile]]" out-graph-hierarchy="{{_graphHierarchy}}" out-graph="{{_graph}}" out-stats="{{_stats}}" progress="{{_progress}}" out-hierarchy-params="{{_hierarchyParams}}"></tf-graph-loader>
</div>
<div class="center">
- <tf-graph-board id="graphboard" devices-for-stats="[[_devicesForStats]]" graph-hierarchy="[[_graphHierarchy]]" graph="[[_graph]]" stats="[[_stats]]" progress="[[_progress]]" color-by="[[_colorBy]]" color-by-params="{{_colorByParams}}" hierarchy-params="[[_hierarchyParams]]">
- </tf-graph-board>
+ <tf-graph-board id="graphboard" devices-for-stats="[[_devicesForStats]]" color-by="[[_colorBy]]" color-by-params="{{_colorByParams}}" graph-hierarchy="[[_graphHierarchy]]" graph="[[_graph]]" hierarchy-params="[[_hierarchyParams]]" progress="[[_progress]]" render-hierarchy="{{_renderHierarchy}}" stats="[[_stats]]"></tf-graph-board>
</div>
</tf-dashboard-layout>
</template>
@@ -13049,8 +13488,9 @@ Polymer({
is: 'tf-graph-dashboard',
properties: {
_datasets: Object,
+ _renderHierarchy: Object,
backend: {type: Object, observer: 'reload'},
- runs: Array,
+ runs: Array
},
reload: function() {
Promise.all([this.backend.graphRuns(), this.backend.runMetadataRuns()])