aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/tensorboard/components/tf-graph/tf-graph.html
diff options
context:
space:
mode:
Diffstat (limited to 'tensorflow/tensorboard/components/tf-graph/tf-graph.html')
-rw-r--r--tensorflow/tensorboard/components/tf-graph/tf-graph.html221
1 files changed, 221 insertions, 0 deletions
diff --git a/tensorflow/tensorboard/components/tf-graph/tf-graph.html b/tensorflow/tensorboard/components/tf-graph/tf-graph.html
new file mode 100644
index 0000000000..905d96e237
--- /dev/null
+++ b/tensorflow/tensorboard/components/tf-graph/tf-graph.html
@@ -0,0 +1,221 @@
+<link rel="import" href="../../bower_components/polymer/polymer.html">
+<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
+<link rel="import" href="../../bower_components/paper-button/paper-button.html">
+<link rel="import" href="../../bower_components/paper-input/paper-input.html">
+<link rel="import" href="../../bower_components/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="../tf-graph-common/tf-graph-common.html">
+<link rel="import" href="tf-graph-scene.html">
+<link rel="import" href="tf-graph-params.html">
+<dom-module id="tf-graph">
+<template>
+<style>
+.container {
+ width: 100%;
+ height: 100%;
+}
+
+.vertical {
+ width:100%;
+ height:100%;
+ @apply(--layout-vertical);
+}
+
+.auto {
+ @apply(--layout-flex-auto);
+ @apply(--layout-vertical);
+}
+
+h2 {
+ text-align: center;
+}
+
+paper-button {
+ text-transform: none;
+}
+</style>
+<div class="container">
+ <tf-graph-params id="graphParams"></tf-graph-params>
+ <div class="vertical">
+ <h2>[[title]]</h2>
+ <tf-graph-scene id="scene" class="auto"
+ graph-hierarchy="[[_renderHierarchy]]"
+ highlighted-node="[[_getVisible(highlightedNode)]]"
+ selected-node="[[selectedNode]]"
+ color-by="[[colorBy]]"
+ name="[[graphName]]"
+ progress="[[progress]]"
+ ></tf-graph-scene>
+ </div>
+</div>
+</template>
+</dom-module>
+
+<script>
+Polymer({
+
+ is: 'tf-graph',
+
+ properties: {
+ graphHierarchy: {
+ type: Object,
+ notify: true,
+ observer: '_graphChanged'
+ },
+ title: String,
+ selectedNode: {
+ type: String,
+ notify: true,
+ },
+ highlightedNode: {
+ type: String,
+ notify: true
+ },
+ /** What to color the nodes by (compute time, memory, device etc.) */
+ colorBy: String,
+ colorByParams: {
+ type: Object,
+ notify: true,
+ readOnly: true, // Produces and doesn't consume.
+ },
+ // internal properties
+ _graphParams: {
+ type: Object,
+ value: function() {
+ return this.$.graphParams;
+ }
+ },
+ _renderDepth: {
+ type: Number,
+ value: 1
+ },
+ _renderHierarchy: {
+ type: Object,
+ readOnly: true,
+ notify: true,
+ computed: '_buildRenderHierarchy(graphHierarchy, _graphParams)'
+ },
+ _allowGraphSelect: {
+ type: Boolean,
+ value: true
+ }
+ },
+ _buildRenderHierarchy: function(graphHierarchy, params) {
+ return tf.time('new tf.graph.render.Hierarchy', function() {
+ if (graphHierarchy.root.type !== tf.graph.NodeType.META) {
+ // root must be metanode but sometimes Polymer's dom-if has not
+ // remove tf-graph element yet in <tf-node-info>
+ // and thus mistakenly pass non-metanode to this module.
+ return;
+ }
+ var renderGraph = new tf.graph.render.RenderGraphInformation(
+ graphHierarchy, params);
+ // Producing the 'color by' parameters to be consumed
+ // by the tf-graph-controls panel. It contains information about the
+ // min and max values and their respective colors, as well as list
+ // of devices with their respective colors.
+
+ function getColorParamsFromScale(scale) {
+ return {
+ minValue: scale.domain()[0],
+ maxValue: scale.domain()[1],
+ startColor: scale.range()[0],
+ endColor: scale.range()[1]
+ };
+ }
+
+ this._setColorByParams({
+ compute_time: getColorParamsFromScale(renderGraph.computeTimeScale),
+ memory: getColorParamsFromScale(renderGraph.memoryUsageScale),
+ device: _.map(renderGraph.deviceColorMap.domain(),
+ function(deviceName) {
+ return {
+ device: deviceName,
+ color: renderGraph.deviceColorMap(deviceName)
+ };
+ })
+ });
+ return renderGraph;
+ }.bind(this));
+ },
+ _getVisible: function(name) {
+ if (!name) {
+ return name;
+ }
+ return this._renderHierarchy.getNearestVisibleAncestor(name);
+ },
+ listeners: {
+ 'graph-select': '_graphSelected',
+ 'disable-click': '_disableClick',
+ 'enable-click': '_enableClick',
+ // Nodes
+ 'node-toggle-expand': '_nodeToggleExpand',
+ 'node-select': '_nodeSelected',
+ 'node-highlight': '_nodeHighlighted',
+ 'node-unhighlight': '_nodeUnhighlighted',
+
+ // Annotations
+
+ /* Note: currently highlighting/selecting annotation node has the same
+ * behavior as highlighting/selecting actual node so we point to the same
+ * set of event listeners. However, we might redesign this to be a bit
+ * different.
+ */
+ 'annotation-select': '_nodeSelected',
+ 'annotation-highlight': '_nodeHighlighted',
+ 'annotation-unhighlight': '_nodeUnhighlighted',
+ },
+ _graphChanged: function() {
+ // When a new graph is loaded, fire this event so that there is no
+ // info-card being displayed for the previously-loaded graph.
+ this.fire('graph-select');
+ },
+ _graphSelected: function(event) {
+ // Graph selection is not allowed during an active zoom event, as the
+ // click seen during a zoom/pan is part of the zooming and does not
+ // indicate a user desire to click on a specific section of the graph.
+ if (this._allowGraphSelect) {
+ this.set('selectedNode', null);
+ }
+ // Reset this variable as a bug in d3 zoom behavior can cause zoomend
+ // callback not to be called if a right-click happens during a zoom event.
+ this._allowGraphSelect = true;
+ },
+ _disableClick: function(event) {
+ this._allowGraphSelect = false;
+ },
+ _enableClick: function(event) {
+ this._allowGraphSelect = true;
+ },
+ _nodeSelected: function(event) {
+ if (this._allowGraphSelect) {
+ this.set('selectedNode', event.detail.name);
+ }
+ // Reset this variable as a bug in d3 zoom behavior can cause zoomend
+ // callback not to be called if a right-click happens during a zoom event.
+ this._allowGraphSelect = true;
+ },
+ _nodeHighlighted: function(event) {
+ this.set('highlightedNode', event.detail.name);
+ },
+ _nodeUnhighlighted: function(event) {
+ this.set('highlightedNode', null);
+ },
+ _nodeToggleExpand: function(event) {
+ var nodeName = event.detail.name;
+ var renderNode = this._renderHierarchy.getRenderNodeByName(nodeName);
+ // Op nodes are not expandable.
+ if (renderNode.node.type === tf.graph.NodeType.OP) {
+ return;
+ }
+ this._renderHierarchy.buildSubhierarchy(nodeName);
+ renderNode.expanded = !renderNode.expanded;
+ this.querySelector('#scene').setNodeExpanded(renderNode);
+ // Also select the expanded node.
+ this._nodeSelected(event);
+ },
+ not: function(x) {
+ return !x;
+ }
+});
+</script>