diff options
Diffstat (limited to 'tensorflow/tensorboard/components/tf-graph-info')
3 files changed, 501 insertions, 0 deletions
diff --git a/tensorflow/tensorboard/components/tf-graph-info/tf-graph-info.html b/tensorflow/tensorboard/components/tf-graph-info/tf-graph-info.html new file mode 100644 index 0000000000..b7900f86de --- /dev/null +++ b/tensorflow/tensorboard/components/tf-graph-info/tf-graph-info.html @@ -0,0 +1,65 @@ +<link rel="import" href="../../bower_components/polymer/polymer.html"> +<link rel="import" href="tf-node-info.html"> +<dom-module id="tf-graph-info"> +<template> +<style> +:host { + font-size: 12px; + margin: 0; + padding: 0; + display: block; +} + +h2 { + padding: 0; + text-align: center; + margin: 0; +} +</style> +<template is="dom-if" if="{{selectedNode}}"> + <paper-material elevation="1" class="card"> + <tf-node-info graph-hierarchy='[[graphHierarchy]]' + flat-graph="[[graph]]" + node-name='[[selectedNode]]' + highlighted-node='{{highlightedNode}}'> + </tf-node-info> + </paper-material> +</template> +</template> +<script> +(function() { + Polymer({ + is: 'tf-graph-info', + + properties: { + title: String, + graphHierarchy: Object, + graph: Object, + // Two-ways + selectedNode: { + type: String, + notify: true + }, + highlightedNode: { + type: String, + notify: true + } + }, + listeners: { + 'node-list-item-click': '_nodeListItemClicked', + 'node-list-item-mouseover': '_nodeListItemMouseover', + 'node-list-item-mouseout': '_nodeListItemMouseout' + }, + _nodeListItemClicked: function(event) { + this.selectedNode = event.detail.nodeName; + }, + _nodeListItemMouseover: function(event) { + this.highlightedNode = event.detail.nodeName; + }, + _nodeListItemMouseout: function() { + this.highlightedNode = null; + } + }); +})(); +</script> +</dom-module> diff --git a/tensorflow/tensorboard/components/tf-graph-info/tf-node-info.html b/tensorflow/tensorboard/components/tf-graph-info/tf-node-info.html new file mode 100644 index 0000000000..5044bf2bb1 --- /dev/null +++ b/tensorflow/tensorboard/components/tf-graph-info/tf-node-info.html @@ -0,0 +1,345 @@ +<link rel="import" href="../../bower_components/iron-collapse/iron-collapse.html"> +<link rel="import" href="../../bower_components/iron-list/iron-list.html"> +<link rel="import" href="../../bower_components/polymer/polymer.html"> +<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html"> +<link rel="import" href="../../bower_components/paper-item/all-imports.html"> +<link rel="import" href="../tf-graph-common/tf-graph-common.html"> +<link rel="import" href="../tf-graph/tf-graph-icon.html"> +<link rel="import" href="tf-node-list-item.html"> + +<dom-module id="tf-node-info"> + <style> + .sub-list-group { + padding: 8px 12px 0px; + font-weight: 500; + font-size: 12pt; + } + + .sub-list { + max-height: 300px; + overflow-y: scroll; + } + + .attr-left { + float: left; + width: 30%; + word-wrap: break-word; + color: #565656; + font-size: 11pt; + font-weight: 400; + } + + .attr-right { + margin-left: 30%; + word-wrap: break-word; + color: #565656; + font-weight: 400; + } + + paper-item { + padding: 0; + background: #e9e9e9; + } + + paper-item-body[two-line] { + min-height: 0; + padding: 8px 12px 4px; + } + + .expandedInfo { + padding: 0 0 8px; + } + + .controlDeps { + padding: 0 0 0 8px; + } + + .node-name { + white-space: normal; + word-wrap: break-word; + font-size: 14pt; + font-weight: 500; + } + + .node-icon { + float: right; + } + + .subtitle { + font-size: 12pt; + color: #5e5e5e; + } + + .controlLine { + font-size: 11pt; + font-weight: 400; + } + + .toggle-button { + float: right; + max-height: 20px; + max-width: 20px; + padding: 0; + } + + .control-toggle-button { + float: left; + max-height: 20px; + max-width: 20px; + padding: 0; + } + </style> + <template> + <paper-item> + <paper-item-body two-line> + <div> + <paper-icon-button + icon="{{_getToggleIcon(_expanded)}}" + on-click="_toggleExpanded" + class="toggle-button"> + </paper-icon-button> + <div class="node-name">[[_getNodeName(nodeName)]]</div> + </div> + <div secondary> + <tf-graph-icon class="node-icon" node="[[_node]]"></tf-graph-icon> + <template is="dom-if" if="{{_node.op}}"> + <div class="subtitle"> + Operation: + <span>[[_node.op]]</span> + </div> + </template> + <template is="dom-if" if="{{_node.metagraph}}"> + <div class="subtitle"> + Subgraph: + <span>[[_node.cardinality]]</span> nodes + </div> + </template> + </div> + </paper-item-body> + </paper-item> + <iron-collapse opened="{{_expanded}}"> + <template is="dom-if" if="{{_expanded}}" restamp="true"> + <div class="expandedInfo"> + <div class="sub-list-group attributes"> + Attributes + (<span>[[_attributes.length]]</span>) + <iron-list class="sub-list" id ="attributesList" + items="[[_attributes]]"> + <template> + <div> + <div class="attr-left">[[item.key]]</div> + <div class="attr-right">[[item.value]]</div> + </div> + </template> + </iron-list> + </div> + + <template is="dom-if" if="{{_device}}"> + <div class="sub-list-group device"> + <div class="attr-left">Device</div> + <div class="attr-right">[[_device]]</div> + </div> + </template> + + <div class="sub-list-group predecessors"> + Inputs + (<span>[[_totalPredecessors]]</span>) + <iron-list class="sub-list" id ="inputsList" + items="[[_predecessors.regular]]"> + <template> + <tf-node-list-item card-node="[[_node]]" + item-node="[[_getNode(item, graphHierarchy)]]" + name="[[item]]" + item-type="predecessors"> + </tf-node-list-item> + </template> + </iron-list> + <template is="dom-if" if="[[_predecessors.control.length]]"> + <div class="controlDeps"> + <div class="controlLine"> + <paper-icon-button + icon="{{_getToggleIcon(_openedControlPred)}}" + on-click="_toggleControlPred" + class="control-toggle-button"> + </paper-icon-button> + Control dependencies + </div> + <iron-collapse opened="{{_openedControlPred}}"> + <template is="dom-if" if="{{_openedControlPred}}" restamp="true"> + <iron-list class="sub-list" items="[[_predecessors.control]]"> + <template> + <tf-node-list-item card-node="[[_node]]" + item-node="[[_getNode(item, graphHierarchy)]]" + name="[[item]]" + item-type="predecessors"> + </tf-node-list-item> + </template> + </iron-list> + </template> + </iron-collapse> + </div> + </template> + </div> + + <div class="sub-list-group successors"> + Outputs + (<span>[[_totalSuccessors]]</span>) + <iron-list class="sub-list" id ="outputsList" + items="[[_successors.regular]]"> + <template> + <tf-node-list-item card-node="[[_node]]" + item-node="[[_getNode(item, graphHierarchy)]]" + name="[[item]]" + item-type="successor"> + </tf-node-list-item> + </template> + </iron-list> + <template is="dom-if" if="[[_successors.control.length]]"> + <div class="controlDeps"> + <div class="controlLine"> + <paper-icon-button + icon="{{_getToggleIcon(_openedControlSucc)}}" + on-click="_toggleControlSucc" + class="control-toggle-button"> + </paper-icon-button> + Control dependencies + </div> + <iron-collapse opened="{{_openedControlSucc}}"> + <template is="dom-if" if="{{_openedControlSucc}}" restamp="true"> + <iron-list class="sub-list" items="[[_successors.control]]"> + <template> + <tf-node-list-item card-node="[[_node]]" + item-node="[[_getNode(item, graphHierarchy)]]" + name="[[item]]" + item-type="successors"> + </tf-node-list-item> + </template> + </iron-list> + </template> + </iron-collapse> + </div> + </template> + </div> + </div> + </template> + </iron-collapse> + </template> + + <script> + (function() { + Polymer({ + is: 'tf-node-info', + + properties: { + nodeName: String, + graphHierarchy: Object, + _node: { + type: Object, + computed: '_getNode(nodeName, graphHierarchy)', + observer: '_resetState' + }, + _attributes: { + type: Array, + computed: '_getAttributes(_node)' + }, + _device: { + type: String, + computed: '_getDevice(_node)' + }, + _successors: { + type: Object, + computed: '_getSuccessors(_node, graphHierarchy)' + }, + _predecessors: { + type: Object, + computed: '_getPredecessors(_node, graphHierarchy)' + }, + _subnodes: { + type: Array, + computed: '_getSubnodes(_node)' + }, + _expanded: { + type: Boolean, + value: true + }, + _totalPredecessors: { + type: Number, + computed: '_getTotalPred(_predecessors)' + }, + _totalSuccessors: { + type: Number, + computed: '_getTotalSucc(_successors)' + }, + _openedControlPred: { + type: Boolean, + value: false + }, + _openedControlSucc: { + type: Boolean, + value: false + }, + }, + expandNode: function() { + this.fire('_node.expand', this.node); + }, + _getNode: function(n, graphHierarchy) { + return graphHierarchy.node(n); + }, + _getNodeName: function(nodeName) { + // Insert a zero-width whitespace character before each slash so that + // long node names wrap cleanly at path boundaries. + return (nodeName || '').replace(/\//g, '\u200B/'); + }, + _getAttributes: function(node) { + this.async(this._resizeList.bind(this, "#attributesList")); + return node && node.attr ? node.attr.map(function(entry) { + return {key: entry.key, value: JSON.stringify(entry.value)}; + }) : []; + + }, + _getDevice: function(node) { + return node ? node.device : null; + }, + _getSuccessors: function(node, hierarchy) { + this.async(this._resizeList.bind(this, "#inputsList")); + return node ? hierarchy.getSuccessors(node.name) : [[], []]; + }, + _getPredecessors: function(node, hierarchy) { + this.async(this._resizeList.bind(this, "#outputsList")); + return node ? hierarchy.getPredecessors(node.name) : [[], []]; + }, + _getSubnodes: function(node) { + return node && node.metagraph ? node.metagraph.nodes() : null; + }, + _getTotalPred: function(predecessors) { + return predecessors.regular.length + predecessors.control.length; + }, + _getTotalSucc: function(successors) { + return successors.regular.length + successors.control.length; + }, + _toggleControlPred: function() { + this._openedControlPred = !this._openedControlPred; + }, + _toggleControlSucc: function() { + this._openedControlSucc = !this._openedControlSucc; + }, + _toggleExpanded: function() { + this._expanded = !this._expanded; + }, + _getToggleIcon: function(expanded) { + return expanded ? "expand-less" : "expand-more"; + }, + _resetState: function() { + this._openedControlPred = false; + this._openedControlSucc = false; + }, + _resizeList: function(selector) { + var list = document.querySelector(selector); + if (list) { + list.fire('iron-resize'); + } + } + }); + })(); + </script> +</dom-module> diff --git a/tensorflow/tensorboard/components/tf-graph-info/tf-node-list-item.html b/tensorflow/tensorboard/components/tf-graph-info/tf-node-list-item.html new file mode 100644 index 0000000000..f16e9e4511 --- /dev/null +++ b/tensorflow/tensorboard/components/tf-graph-info/tf-node-list-item.html @@ -0,0 +1,91 @@ +<link rel="import" href="../../bower_components/polymer/polymer.html"> +<link rel="import" href="../tf-graph/tf-graph-icon.html"> + +<dom-module id="tf-node-list-item"> + <style> + #list-item { + width: 100%; + color: #565656; + font-size: 11pt; + font-weight: 400; + position: relative; + } + + #list-item:hover { + background-color: var(--google-yellow-100); + } + + .clickable { + cursor: pointer; + } + + #list-item span { + display: block; + margin-left: 40px; + } + + #list-item.excluded span { + color: #999; + } + + .node-icon { + position: absolute; + top: 1px; + left: 2px; + } + </style> + <template> + <div id="list-item" + on-mouseover="_nodeListener" + on-mouseout="_nodeListener" + on-click="_nodeListener"> + <tf-graph-icon class="node-icon" + node="[[itemNode]]" height="12"></tf-graph-icon> + <span title$="[[name]]">[[name]]</span> + </div> + </template> + + <script> + (function() { + Polymer({ + is: 'tf-node-list-item', + + properties: { + /** + * The Node for the card itself, on which this item is being drawn. + * @type {tf.graph.Node} + */ + cardNode: Object, + /** + * The Node for the item within the card, somehow related to cardNode. + * @type {tf.graph.Node} + */ + itemNode: Object, + name: String, + itemType: { + type: String, + observer: '_itemTypeChanged' + } + }, + + _itemTypeChanged: function() { + if (this.itemType !== 'subnode') { + this.$['list-item'].classList.add('clickable'); + } else { + this.$['list-item'].classList.remove('clickable'); + } + }, + + _nodeListener: function(event) { + // fire node.click/mouseover/mouseout + this.fire('node-list-item-' + event.type, { + cardNode: this.cardNode.name, + nodeName: this.name, + type: this.itemType + }); + } + + }); + })(); + </script> +</dom-module> |