Autogenerated Change: Release TensorBoard at TAG: 21
Change: 126371321
diff --git a/WORKSPACE b/WORKSPACE
index 36d3820..a0aaefa 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -70,7 +70,7 @@
   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 aabe6ec..2bd5a0a 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 77e224d..1c0297d 100644
--- a/tensorflow/tensorboard/dist/tf-tensorboard.html
+++ b/tensorflow/tensorboard/dist/tf-tensorboard.html
@@ -3963,6 +3963,7 @@
             }
             return OpNodeImpl;
         }());
+        graph_1.OpNodeImpl = OpNodeImpl;
         ;
         function createMetanode(name, opt) {
             if (opt === void 0) { opt = {}; }
@@ -4171,6 +4172,7 @@
             };
             return MetanodeImpl;
         }());
+        graph_1.MetanodeImpl = MetanodeImpl;
         ;
         function createMetaedge(v, w) {
             return new MetaedgeImpl(v, w);
@@ -4527,6 +4529,7 @@
             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 @@
                     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 @@
                         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 @@
 ::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 @@
   fill: url("#rectHatch") !important;
 }
 
-::content .faded ellipse {
+::content .faded ellipse,
+::content .faded use {
   fill: url("#ellipseHatch") !important;
 }
 
@@ -10161,6 +10490,81 @@
   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 @@
     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 @@
     }, 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 @@
       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 @@
 </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 @@
     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 @@
     </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 @@
       type: Array,
       observer: '_datasetsChanged'
     },
+    renderHierarchy: {
+      type: Object,
+      notify: true,
+    },
     metadataTags: {
       type: Array,
       computed: '_getMetadataTags(selectedDataset, datasets)'
@@ -12870,6 +13301,14 @@
       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 @@
     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 @@
 <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 @@
   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()])