aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Dan Mané <danmane@google.com>2016-06-23 12:52:01 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2016-06-23 14:06:12 -0700
commit7fe1c1ce84cd6ce3d782ece58ffdef5f2ea44816 (patch)
tree8c8c2c8b05496db994f902397fbdb9d2c655975b
parentc12c59b22cc386fc2ad166aa7609b7fce32e3ccf (diff)
Autogenerated Change: Update TensorBoard source and deps.
Change: 125714059
-rw-r--r--WORKSPACE18
-rw-r--r--tensorflow/tensorboard/bower.json20
-rw-r--r--tensorflow/tensorboard/dist/tf-tensorboard.html554
3 files changed, 346 insertions, 246 deletions
diff --git a/WORKSPACE b/WORKSPACE
index bd6146c6c4..a7ee39ed5e 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -70,14 +70,14 @@ 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.3",
+ tag = "v1.1.4",
)
new_git_repository(
name = "iron_ajax",
build_file = "bower.BUILD",
remote = "https://github.com/polymerelements/iron-ajax.git",
- tag = "v1.1.1",
+ tag = "v1.2.0",
)
new_git_repository(
@@ -119,7 +119,7 @@ new_git_repository(
name = "iron_fit_behavior",
build_file = "bower.BUILD",
remote = "https://github.com/polymerelements/iron-fit-behavior.git",
- tag = "v1.2.2",
+ tag = "v1.2.3",
)
new_git_repository(
@@ -189,7 +189,7 @@ new_git_repository(
name = "iron_overlay_behavior",
build_file = "bower.BUILD",
remote = "https://github.com/polymerelements/iron-overlay-behavior.git",
- tag = "v1.8.0",
+ tag = "v1.8.1",
)
new_git_repository(
@@ -322,7 +322,7 @@ new_git_repository(
name = "paper_menu_button",
build_file = "bower.BUILD",
remote = "https://github.com/polymerelements/paper-menu-button.git",
- tag = "v1.1.0",
+ tag = "v1.1.1",
)
new_git_repository(
@@ -350,7 +350,7 @@ new_git_repository(
name = "paper_ripple",
build_file = "bower.BUILD",
remote = "https://github.com/polymerelements/paper-ripple.git",
- tag = "v1.0.5",
+ tag = "v1.0.7",
)
new_git_repository(
@@ -371,7 +371,7 @@ new_git_repository(
name = "paper_tabs",
build_file = "bower.BUILD",
remote = "https://github.com/polymerelements/paper-tabs.git",
- tag = "v1.5.0",
+ tag = "v1.6.2",
)
new_git_repository(
@@ -385,7 +385,7 @@ new_git_repository(
name = "paper_toolbar",
build_file = "bower.BUILD",
remote = "https://github.com/polymerelements/paper-toolbar.git",
- tag = "v1.1.2",
+ tag = "v1.1.4",
)
new_git_repository(
@@ -399,7 +399,7 @@ new_git_repository(
name = "polymer",
build_file = "bower.BUILD",
remote = "https://github.com/polymer/polymer.git",
- tag = "v1.4.0",
+ tag = "v1.5.0",
)
new_git_repository(
diff --git a/tensorflow/tensorboard/bower.json b/tensorflow/tensorboard/bower.json
index 8ba58c5a26..b470a75f71 100644
--- a/tensorflow/tensorboard/bower.json
+++ b/tensorflow/tensorboard/bower.json
@@ -39,7 +39,7 @@
"graphlib": "1.0.7",
"iron-a11y-announcer": "PolymerElements/iron-a11y-announcer#1.0.4",
"iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#1.1.2",
- "iron-ajax": "PolymerElements/iron-ajax#1.1.1",
+ "iron-ajax": "PolymerElements/iron-ajax#1.2.0",
"iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#1.0.11",
"iron-behaviors": "PolymerElements/iron-behaviors#1.0.16",
"iron-checked-element-behavior": "PolymerElements/iron-checked-element-behavior#1.0.4",
@@ -81,13 +81,13 @@
"paper-ripple": "PolymerElements/paper-ripple#1.0.5",
"paper-slider": "PolymerElements/paper-slider#1.0.10",
"paper-styles": "PolymerElements/paper-styles#1.1.1",
- "paper-tabs": "PolymerElements/paper-tabs#1.5.0",
+ "paper-tabs": "PolymerElements/paper-tabs#1.6.2",
"paper-toggle-button": "PolymerElements/paper-toggle-button#1.1.2",
- "paper-toolbar": "PolymerElements/paper-toolbar#1.1.2",
+ "paper-toolbar": "PolymerElements/paper-toolbar#1.1.4",
"plottable": "1.16.1",
- "polymer": "1.4.0",
+ "polymer": "1.5.0",
"promise-polyfill": "polymerlabs/promise-polyfill#1.0.0",
- "web-animations-js": "web-animations/web-animations-js#2.0.0",
+ "web-animations-js": "web-animations/web-animations-js#2.2.1",
"webcomponentsjs": "webcomponents/webcomponentsjs#0.7.22"
},
"description": "TensorBoard: Visualizations for TensorFlow",
@@ -113,7 +113,7 @@
"graphlib": "1.0.7",
"iron-a11y-announcer": "1.0.4",
"iron-a11y-keys-behavior": "1.1.2",
- "iron-ajax": "1.1.1",
+ "iron-ajax": "1.2.0",
"iron-autogrow-textarea": "1.0.11",
"iron-behaviors": "1.0.16",
"iron-checked-element-behavior": "1.0.4",
@@ -155,13 +155,13 @@
"paper-ripple": "1.0.5",
"paper-slider": "1.0.10",
"paper-styles": "1.1.1",
- "paper-tabs": "1.5.0",
+ "paper-tabs": "1.6.2",
"paper-toggle-button": "1.1.2",
- "paper-toolbar": "1.1.2",
+ "paper-toolbar": "1.1.4",
"plottable": "1.16.1",
- "polymer": "1.4.0",
+ "polymer": "1.5.0",
"promise-polyfill": "1.0.0",
- "web-animations-js": "2.0.0",
+ "web-animations-js": "2.2.1",
"webcomponentsjs": "0.7.22"
},
"version": "0.0.0"
diff --git a/tensorflow/tensorboard/dist/tf-tensorboard.html b/tensorflow/tensorboard/dist/tf-tensorboard.html
index 25048790ae..f76ad5aec6 100644
--- a/tensorflow/tensorboard/dist/tf-tensorboard.html
+++ b/tensorflow/tensorboard/dist/tf-tensorboard.html
@@ -18,7 +18,9 @@ Instead, use `gulp regenerate` to create a new version with your changes.
-->
<html><head><meta charset="UTF-8">
-<script>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
+
+</head><body><div hidden="" by-vulcanize=""><dom-module id="tf-globals" assetpath="../tf-globals/">
+ <script>/* Copyright 2015 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -32,75 +34,18 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
+/* tslint:disable:no-namespace */
var TF;
(function (TF) {
- var TensorBoard;
- (function (TensorBoard) {
- TensorBoard.TABS = ['events', 'images', 'audio', 'graphs', 'histograms'];
- })(TensorBoard = TF.TensorBoard || (TF.TensorBoard = {}));
+ var Globals;
+ (function (Globals) {
+ Globals.TABS = ['events', 'images', 'audio', 'graphs', 'histograms'];
+ })(Globals = TF.Globals || (TF.Globals = {}));
})(TF || (TF = {}));
</script>
-<script>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+</dom-module>
-http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-==============================================================================*/
-var TF;
-(function (TF) {
- var TensorBoard;
- (function (TensorBoard) {
- TensorBoard.AUTORELOAD_LOCALSTORAGE_KEY = 'TF.TensorBoard.autoReloadEnabled';
- var getAutoReloadFromLocalStorage = function () {
- var val = window.localStorage.getItem(TensorBoard.AUTORELOAD_LOCALSTORAGE_KEY);
- return val === 'true' || val == null; // defaults to true
- };
- TensorBoard.AutoReloadBehavior = {
- properties: {
- autoReloadEnabled: {
- type: Boolean,
- observer: '_autoReloadObserver',
- value: getAutoReloadFromLocalStorage,
- },
- _autoReloadId: {
- type: Number,
- },
- autoReloadIntervalSecs: {
- type: Number,
- value: 120,
- },
- },
- detached: function () { window.clearTimeout(this._autoReloadId); },
- _autoReloadObserver: function (autoReload) {
- window.localStorage.setItem(TensorBoard.AUTORELOAD_LOCALSTORAGE_KEY, autoReload);
- if (autoReload) {
- var _this = this;
- this._autoReloadId = window.setTimeout(this._doAutoReload.bind(this), this.autoReloadIntervalSecs * 1000);
- }
- else {
- window.clearTimeout(this._autoReloadId);
- }
- },
- _doAutoReload: function () {
- if (this.reload == null) {
- throw new Error('AutoReloadBehavior requires a reload method');
- }
- this.reload();
- this._autoReloadId = window.setTimeout(this._doAutoReload.bind(this), this.autoReloadIntervalSecs * 1000);
- }
- };
- })(TensorBoard = TF.TensorBoard || (TF.TensorBoard = {}));
-})(TF || (TF = {}));
-</script>
-</head><body><div hidden="" by-vulcanize="">
<dom-module id="scrollbar-style" assetpath="../tf-dashboard-common/">
<template>
<style>
@@ -552,13 +497,15 @@ var TF;
'#f4b400' // google yellow 700
],
googleColorBlindAssist: [
- '#c53929',
'#ff7043',
- '#f7cb4d',
+ '#00ACC1',
+ '#AB47BC',
+ '#2A56C6',
'#0b8043',
- '#80deea',
- '#4285f4',
- '#5e35b1' // deep purple 600
+ '#F7CB4D',
+ '#c0ca33',
+ '#5e35b1',
+ '#A52714',
],
// These palettes try to be better for color differentiation.
// https://personal.sron.nl/~pault/
@@ -579,11 +526,6 @@ var TF;
mldash: [
'#E47EAD', '#F4640D', '#FAA300', '#F5E636', '#00A077', '#0077B8',
'#00B7ED'
- ],
- // This rainbow palette attempts to keep a constant brightness across hues.
- constantValue: [
- '#f44336', '#ffa216', '#c2d22d', '#51b455', '#1ca091', '#505ec4',
- '#a633ba'
]
};
})(TF || (TF = {}));
@@ -602,20 +544,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
-// Each color scale is initialized with a configurable number of base hues.
-// There are also several palettes available.
-// TF.palettes.googleStandard, TF.palettes.googleColorBlind,
-// TF.palettes.googleCool, TF.palettes.googleWarm, TF.palettes.constantValue
-// Each string is hashed to an integer,
-// then mapped to one of the base hues above.
-// If there is a collision, the color that is later in an alphabetical sort
-// gets nudged a little darker or lighter to disambiguate.
-// I would call it mostly stable, in that the same array of strings will
-// always return the same colors, but the same individual string may
-// shift a little depending on its peers.
-//
+// Example usage:
// runs = ["train", "test", "test1", "test2"]
-// ccs = new TF.ColorScale(12, "googleStandard");
+// ccs = new TF.ColorScale();
// ccs.domain(runs);
// ccs.getColor("train");
// ccs.getColor("test1");
@@ -623,104 +554,39 @@ var TF;
(function (TF) {
var ColorScale = (function () {
/**
- * The palette you provide defines your spectrum. The colorscale will
- * always use the full spectrum you provide. When you define "numColors"
- * it resamples at regular intervals along the full extent of the spectrum.
- * Thus you get the maximum distance between hues for the "numColors"
- * given. This allows the programmer to tweak the algorithm depending on
- * how big your expected domain is. If you generally think you're going to
- * have a small number of elements in the domain, then a small numColors
- * will be serviceable. With large domains, a small numColors would produce
- * too many hash collisions, so you'd want to bump it up to the threshold
- * of human perception (probably around 14 or 18).
- *
- * @param {string[]} [palette=TF.palettes.googleColorBlind] - The color
- * palette you want as an Array of hex strings. Note, the
- * length of the array in this palette is independent of the
- * param numColors above. The scale will interpolate to
- * create the proper "numColors" given in the first param.
- *
- * @param {number} [numColors] - The number of base colors you want
- * in the palette. The more colors, the smaller the number
- * the more hash collisions you will have, but the more
- * differentiable the base colors will be.
+ * Creates a color scale with optional custom palette.
+ * @param {string[]} [palette=TF.palettes.googleColorBlind] - The color
+ * palette you want as an Array of hex strings.
*/
- function ColorScale(palette, numColors) {
+ function ColorScale(palette) {
if (palette === void 0) { palette = TF.palettes.googleColorBlindAssist; }
- this.LIGHTNESS_NUDGE = 0.8;
- this.numColors = numColors ? numColors : palette.length;
- this.domain([]);
- if (palette.length < 2) {
- throw new Error('Not enough colors in palette. Must be more than one.');
- }
- var k = (this.numColors - 1) / (palette.length - 1);
- this.internalColorScale =
- d3.scale.linear()
- .domain(d3.range(palette.length).map(function (i) { return i * k; }))
- .range(palette);
+ this.identifiers = d3.map();
+ this.palette = palette;
}
- ColorScale.prototype.hash = function (s) {
- function h(hash, str) {
- hash = (hash << 5) - hash + str.charCodeAt(0);
- return hash & hash;
- }
- return Math.abs(Array.prototype.reduce.call(s, h, 0)) % this.numColors;
- };
/**
- * Set the domain of strings so we can calculate collisions preemptively.
- * Can be reset at any point.
- *
- * @param {string[]} strings - An array of strings to use as the domain
- * for your scale.
+ * Set the domain of strings.
+ * @param {string[]} strings - An array of possible strings to use as the
+ * domain for your scale.
*/
ColorScale.prototype.domain = function (strings) {
var _this = this;
- this.buckets = d3.range(this.numColors).map(function () { return []; });
- var sortedUniqueKeys = d3.set(strings).values().sort(function (a, b) {
- return a.localeCompare(b);
+ this.identifiers = d3.map();
+ strings.forEach(function (s, i) {
+ _this.identifiers.set(s, _this.palette[i % _this.palette.length]);
});
- sortedUniqueKeys.forEach(function (s) { return _this.addToDomain(s); });
return this;
};
- ColorScale.prototype.getBucketForString = function (s) {
- var bucketIdx = this.hash(s);
- return this.buckets[bucketIdx];
- };
- ColorScale.prototype.addToDomain = function (s) {
- var bucketIdx = this.hash(s);
- var bucket = this.buckets[bucketIdx];
- if (bucket.indexOf(s) === -1) {
- bucket.push(s);
- }
- };
- ColorScale.prototype.nudge = function (color, amount) {
- // If amount is zero, just give back same color
- if (amount === 0) {
- return color;
- }
- else if (amount === 1) {
- return d3.hcl(color).brighter(this.LIGHTNESS_NUDGE);
- }
- else {
- return d3.hcl(color).darker((amount - 1) * this.LIGHTNESS_NUDGE);
- }
- };
/**
* Use the color scale to transform an element in the domain into a color.
- * If there was a hash conflict, the color will be "nudged" darker or
- * lighter so that it is unique.
* @param {string} The input string to map to a color.
* @return {string} The color corresponding to that input string.
* @throws Will error if input string is not in the scale's domain.
*/
ColorScale.prototype.scale = function (s) {
- var bucket = this.getBucketForString(s);
- var idx = bucket.indexOf(s);
- if (idx === -1) {
+ if (!this.identifiers.has(s)) {
throw new Error('String was not in the domain.');
}
- var color = this.internalColorScale(this.hash(s));
- return this.nudge(color, idx).toString();
+ return this.identifiers.get(s);
};
return ColorScale;
}());
@@ -2662,40 +2528,30 @@ var TF;
}
/**
* Returns a listing of all the available data in the TensorBoard backend.
- * Will be deprecated in the future, in favor of
- * per-data-type methods.
*/
Backend.prototype.runs = function () {
return this.requestManager.request(this.router.runs());
};
/**
* Return a promise showing the Run-to-Tag mapping for scalar data.
- * TODO(cassandrax): Replace this with the direct route, when
- * available.
*/
Backend.prototype.scalarRuns = function () {
return this.runs().then(function (x) { return _.mapValues(x, 'scalars'); });
};
/**
* Return a promise showing the Run-to-Tag mapping for histogram data.
- * TODO(cassandrax): Replace this with the direct route, when
- * available.
*/
Backend.prototype.histogramRuns = function () {
return this.runs().then(function (x) { return _.mapValues(x, 'histograms'); });
};
/**
* Return a promise showing the Run-to-Tag mapping for image data.
- * TODO(cassandrax): Replace this with the direct route, when
- * available.
*/
Backend.prototype.imageRuns = function () {
return this.runs().then(function (x) { return _.mapValues(x, 'images'); });
};
/**
* Return a promise showing the Run-to-Tag mapping for audio data.
- * TODO(cassandrax): Replace this with the direct route, when
- * available.
*/
Backend.prototype.audioRuns = function () {
return this.runs().then(function (x) { return _.mapValues(x, 'audio'); });
@@ -2703,24 +2559,18 @@ var TF;
/**
* Return a promise showing the Run-to-Tag mapping for compressedHistogram
* data.
- * TODO(cassandrax): Replace this with the direct route, when
- * available.
*/
Backend.prototype.compressedHistogramRuns = function () {
return this.runs().then(function (x) { return _.mapValues(x, 'compressedHistograms'); });
};
/**
* Return a promise showing list of runs that contain graphs.
- * TODO(cassandrax): Replace this with the direct route, when
- * available.
*/
Backend.prototype.graphRuns = function () {
return this.runs().then(function (x) { return _.keys(x).filter(function (k) { return x[k].graph; }); });
};
/**
* Return a promise showing the Run-to-Tag mapping for run_metadata objects.
- * TODO(cassandrax): Replace this with the direct route, when
- * available.
*/
Backend.prototype.runMetadataRuns = function () {
return this.runs().then(function (x) { return _.mapValues(x, 'run_metadata'); });
@@ -5567,10 +5417,7 @@ var tf;
* element. The padding amounts are applied using an SVG transform of X and
* Y coordinates.
*/
- padding: {
- paddingTop: 40,
- paddingLeft: 20
- }
+ padding: { paddingTop: 40, paddingLeft: 20 }
},
subscene: {
meta: {
@@ -5601,6 +5448,7 @@ var tf;
meta: {
radius: 5,
width: 60,
+ maxLabelWidth: 52,
/** A scale for the node's height based on number of nodes inside */
height: d3.scale.linear().domain([1, 200]).range([15, 60]).clamp(true),
/** The radius of the circle denoting the expand button. */
@@ -5611,7 +5459,8 @@ var tf;
width: 15,
height: 6,
radius: 3,
- labelOffset: -8
+ labelOffset: -8,
+ maxLabelWidth: 30
},
/** Size of series nodes. */
series: {
@@ -5652,16 +5501,9 @@ var tf;
},
shortcutSize: {
/** Size of shortcuts for op nodes */
- op: {
- width: 10,
- height: 4
- },
+ op: { width: 10, height: 4 },
/** Size of shortcuts for meta nodes */
- meta: {
- width: 12,
- height: 4,
- radius: 1
- },
+ meta: { width: 12, height: 4, radius: 1 },
/** Size of shortcuts for series nodes */
series: {
width: 14,
@@ -5679,15 +5521,10 @@ var tf;
yOffset: 3,
/** X-space between each annotation-node and its label. */
labelOffset: 2,
- /** Estimate max width for annotation label */
- labelWidth: 35
- },
- constant: {
- size: {
- width: 4,
- height: 4
- }
+ /** Defines the max width for annotation label */
+ maxLabelWidth: 120
},
+ constant: { size: { width: 4, height: 4 } },
series: {
/** Maximum number of repeated item for unexpanded series node. */
maxStackCount: 3,
@@ -7794,22 +7631,19 @@ var tf;
function addAnnotationLabelFromNode(aGroup, a) {
var namePath = a.node.name.split('/');
var text = namePath[namePath.length - 1];
- var shortenedText = text.length > 8 ? text.substring(0, 8) + '...' : text;
- return addAnnotationLabel(aGroup, shortenedText, a, null, text);
+ return addAnnotationLabel(aGroup, text, a, null);
}
- function addAnnotationLabel(aGroup, label, a, additionalClassNames, fullLabel) {
+ function addAnnotationLabel(aGroup, label, a, additionalClassNames) {
var classNames = scene.Class.Annotation.LABEL;
if (additionalClassNames) {
classNames += ' ' + additionalClassNames;
}
- var titleText = fullLabel ? fullLabel : label;
- return aGroup.append('text')
+ var txtElement = aGroup.append('text')
.attr('class', classNames)
.attr('dy', '.35em')
.attr('text-anchor', a.isIn ? 'end' : 'start')
- .text(label)
- .append('title')
- .text(titleText);
+ .text(label);
+ return tf.graph.scene.node.enforceLabelWidth(txtElement, -1);
}
function addInteraction(selection, d, annotation, sceneElement) {
selection
@@ -7837,7 +7671,7 @@ var tf;
* @param aGroup selection of a 'g.annotation' element.
* @param d Host node data.
* @param a annotation node data.
- * @param scene <tf-graph-scene> polymer element.
+ * @param sceneElement <tf-graph-scene> polymer element.
*/
function update(aGroup, d, a, sceneElement) {
var cx = graph.layout.computeCXPositionOfNodeShape(d);
@@ -8606,10 +8440,73 @@ var tf;
var scale = getLabelFontScale(sceneElement);
label.attr('font-size', scale(text.length) + 'px');
}
- label.text(text);
+ var txtElement = label.text(text);
+ enforceLabelWidth(txtElement, renderNodeInfo.node.type, renderNodeInfo);
return label;
}
- ;
+ /**
+ * This function shortens text which would exceed the maximum pixel width of
+ * a label.
+ *
+ * @param txtElementSelection The text element containing the label's text as d3
+ * selection.
+ * @param nodeType The type of the node the label belongs to. If the node is
+ * an annotation, the value is -1. Label widths are defined in
+ * layout.PARAMS.nodeSize.{meta|op|...}.maxLabelWidth for nodes and
+ * layout.PARAMS.annotations.labelWidth for annotations.
+ * @param renderNodeInfo The render information about the node, required to
+ * determine whether META nodes are collapsed or expanded.
+ */
+ function enforceLabelWidth(txtElementSelection, nodeType, renderNodeInfo) {
+ // Get text element itself and its on-screen width.
+ var txtNode = txtElementSelection.node();
+ var computedTxtLength = txtNode.getComputedTextLength();
+ var labelContent = txtNode.textContent;
+ // Get maximum length from settings.
+ var maxLength = null;
+ switch (nodeType) {
+ case graph.NodeType.META:
+ if (renderNodeInfo && !renderNodeInfo.expanded) {
+ // node expanded.
+ maxLength = graph.layout.PARAMS.nodeSize.meta.maxLabelWidth;
+ }
+ break;
+ case graph.NodeType.OP:
+ maxLength = graph.layout.PARAMS.nodeSize.op.maxLabelWidth;
+ break;
+ case -1:
+ maxLength = graph.layout.PARAMS.annotations.maxLabelWidth;
+ break;
+ default:
+ break;
+ }
+ // Return if no max length provided for node type, or current label length is
+ // less than or equal to the provided length limit.
+ if (maxLength === null || computedTxtLength <= maxLength) {
+ return;
+ }
+ // Find the index of the character which exceeds the width.
+ // getSubStringLength performs far better than getComputedTextLength, and
+ // results in a 3x speed-up on average.
+ var index = 1;
+ while (txtNode.getSubStringLength(0, index) < maxLength) {
+ index++;
+ }
+ // Shorten the label starting at the string length known to be one
+ // character above max pixel length.
+ // When shortened the original label's substring is concatenated with
+ // '...', baseText contains the substring not including the '...'.
+ var baseText = txtNode.textContent.substr(0, index);
+ do {
+ baseText = baseText.substr(0, baseText.length - 1);
+ // Recompute text length.
+ txtNode.textContent = baseText + '...';
+ computedTxtLength = txtNode.getComputedTextLength();
+ } while (computedTxtLength > maxLength && baseText.length > 0);
+ // Add tooltip with full name and return.
+ return txtElementSelection.append('title').text(labelContent);
+ }
+ node_1.enforceLabelWidth = enforceLabelWidth;
/**
* d3 scale used for sizing font of labels, used by labelBuild,
* initialized once by getLabelFontScale.
@@ -9987,11 +9884,11 @@ var tf;
downloadContext.clearRect(0, 0, _this.downloadCanvas.width, _this.downloadCanvas.height);
downloadContext.drawImage(image, 0, 0, _this.downloadCanvas.width, _this.downloadCanvas.height);
};
- image.onerror = function() {
- var blob = new Blob([svgXml], {type: "image/svg+xml;charset=utf-8"});
- image.src = URL.createObjectURL(blob);
+ image.onerror = function () {
+ var blob = new Blob([svgXml], { type: 'image/svg+xml;charset=utf-8' });
+ image.src = URL.createObjectURL(blob);
};
- image.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svgXml);
+ image.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgXml);
};
/**
* Handles changes in zooming/panning. Should be called from the main svg
@@ -10167,8 +10064,8 @@ Polymer({
stroke-width: 3;
}
-:content .annotation.meta.selected > .nodeshape > rect,
-:content .annotation.meta.selected > .annotation-node > rect {
+::content .annotation.meta.selected > .nodeshape > rect,
+::content .annotation.meta.selected > .annotation-node > rect {
stroke: red;
stroke-width: 2;
}
@@ -13026,7 +12923,211 @@ Polymer({
});
})();
</script>
-</div><dom-module id="tf-tensorboard">
+<dom-module id="tf-storage" assetpath="../tf-storage/">
+ <script>/* Copyright 2015 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+/* tslint:disable:no-namespace */
+/**
+ * The Storage Module provides storage for URL parameters, and an API for
+ * getting and setting TensorBoard's stateful URI.
+ *
+ * It generates URI components like: events&runPrefix=train*
+ * which TensorBoard uses after like localhost:8000/#events&runPrefix=train*
+ * to store state in the URI.
+ */
+var TF;
+(function (TF) {
+ var URIStorage;
+ (function (URIStorage) {
+ /**
+ * A key that users cannot use, since TensorBoard uses this to store info
+ * about the active tab.
+ */
+ URIStorage.TAB = '__tab__';
+ /**
+ * Return a string stored in the URI, given a corresonding key.
+ * Null if not found.
+ */
+ function getString(key) {
+ var items = _componentToDict(_readComponent());
+ return _.isUndefined(items[key]) ? null : items[key];
+ }
+ URIStorage.getString = getString;
+ /**
+ * Store a string in the URI, with a corresponding key.
+ */
+ function setString(key, value) {
+ var items = _componentToDict(_readComponent());
+ items[key] = value;
+ _writeComponent(_dictToComponent(items));
+ }
+ URIStorage.setString = setString;
+ /**
+ * Return a number stored in the URI, given a corresponding key.
+ */
+ function getNumber(key) {
+ var items = _componentToDict(_readComponent());
+ return _.isUndefined(items[key]) ? null : +items[key];
+ }
+ URIStorage.getNumber = getNumber;
+ /**
+ * Store a number in the URI, with a corresponding key.
+ */
+ function setNumber(key, value) {
+ var items = _componentToDict(_readComponent());
+ items[key] = '' + value;
+ _writeComponent(_dictToComponent(items));
+ }
+ URIStorage.setNumber = setNumber;
+ /**
+ * Return an object stored in the URI, given a corresponding key.
+ */
+ function getObject(key) {
+ var items = _componentToDict(_readComponent());
+ return _.isUndefined(items[key]) ? null : JSON.parse(atob(items[key]));
+ }
+ URIStorage.getObject = getObject;
+ /**
+ * Store an object in the URI, with a corresponding key.
+ */
+ function setObject(key, value) {
+ var items = _componentToDict(_readComponent());
+ items[key] = btoa(JSON.stringify(value));
+ _writeComponent(_dictToComponent(items));
+ }
+ URIStorage.setObject = setObject;
+ /**
+ * Read component from URI (e.g. returns "events&runPrefix=train*").
+ */
+ function _readComponent() { return window.location.hash.slice(1); }
+ /**
+ * Write component to URI.
+ */
+ function _writeComponent(component) {
+ window.location.hash = component;
+ }
+ /**
+ * Convert dictionary of strings into a URI Component.
+ * All key value entries get added as key value pairs in the component,
+ * with the exception of a key with the TAB value, which if present
+ * gets prepended to the URI Component string for backwards comptability
+ * reasons.
+ */
+ function _dictToComponent(items) {
+ var component = '';
+ // Add the tab name e.g. 'events', 'images', 'histograms' as a prefix
+ // for backwards compatbility.
+ if (items[URIStorage.TAB] !== undefined) {
+ component += items[URIStorage.TAB];
+ }
+ // Join other strings with &key=value notation
+ var nonTab = _.pairs(items)
+ .filter(function (pair) { return pair[0] !== URIStorage.TAB; })
+ .map(function (pair) {
+ return encodeURIComponent(pair[0]) + '=' +
+ encodeURIComponent(pair[1]);
+ })
+ .join('&');
+ return nonTab.length > 0 ? (component + '&' + nonTab) : component;
+ }
+ /**
+ * Convert a URI Component into a dictionary of strings.
+ * Component should consist of key-value pairs joined by a delimiter
+ * with the exception of the tabName.
+ * Returns dict consisting of all key-value pairs and
+ * dict[TAB] = tabName
+ */
+ function _componentToDict(component) {
+ var items = {};
+ var tokens = component.split('&');
+ tokens.forEach(function (token) {
+ var kv = token.split('=');
+ // Special backwards compatibility for URI components like #events
+ if (kv.length === 1 && _.contains(TF.Globals.TABS, kv[0])) {
+ items[URIStorage.TAB] = kv[0];
+ }
+ else if (kv.length === 2) {
+ items[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1]);
+ }
+ });
+ return items;
+ }
+ })(URIStorage = TF.URIStorage || (TF.URIStorage = {}));
+})(TF || (TF = {}));
+</script>
+</dom-module>
+<script>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+var TF;
+(function (TF) {
+ var TensorBoard;
+ (function (TensorBoard) {
+ TensorBoard.AUTORELOAD_LOCALSTORAGE_KEY = 'TF.TensorBoard.autoReloadEnabled';
+ var getAutoReloadFromLocalStorage = function () {
+ var val = window.localStorage.getItem(TensorBoard.AUTORELOAD_LOCALSTORAGE_KEY);
+ return val === 'true' || val == null; // defaults to true
+ };
+ TensorBoard.AutoReloadBehavior = {
+ properties: {
+ autoReloadEnabled: {
+ type: Boolean,
+ observer: '_autoReloadObserver',
+ value: getAutoReloadFromLocalStorage,
+ },
+ _autoReloadId: {
+ type: Number,
+ },
+ autoReloadIntervalSecs: {
+ type: Number,
+ value: 120,
+ },
+ },
+ detached: function () { window.clearTimeout(this._autoReloadId); },
+ _autoReloadObserver: function (autoReload) {
+ window.localStorage.setItem(TensorBoard.AUTORELOAD_LOCALSTORAGE_KEY, autoReload);
+ if (autoReload) {
+ var _this = this;
+ this._autoReloadId = window.setTimeout(this._doAutoReload.bind(this), this.autoReloadIntervalSecs * 1000);
+ }
+ else {
+ window.clearTimeout(this._autoReloadId);
+ }
+ },
+ _doAutoReload: function () {
+ if (this.reload == null) {
+ throw new Error('AutoReloadBehavior requires a reload method');
+ }
+ this.reload();
+ this._autoReloadId = window.setTimeout(this._doAutoReload.bind(this), this.autoReloadIntervalSecs * 1000);
+ }
+ };
+ })(TensorBoard = TF.TensorBoard || (TF.TensorBoard = {}));
+})(TF || (TF = {}));
+</script></div><dom-module id="tf-tensorboard">
<template>
<paper-dialog with-backdrop="" id="settings">
<h2>Settings</h2>
@@ -13170,13 +13271,13 @@ Polymer({
tabs: {
type: Array,
readOnly: true,
- value: TF.TensorBoard.TABS,
+ value: TF.Globals.TABS,
},
},
_getModeFromIndex: function(modeIndex) {
var mode = this.tabs[modeIndex];
if (!this.noHash) {
- window.location.hash = mode;
+ TF.URIStorage.setString(TF.URIStorage.TAB, this.tabs[0]);
}
return mode;
},
@@ -13212,11 +13313,10 @@ Polymer({
}.bind(this));
},
_getModeFromHash: function() {
- // Return the mode as it is stored in the hash.
- var tabName = window.location.hash.trim().slice(1);
+ var tabName = TF.URIStorage.getString(TF.URIStorage.TAB);
var modeIndex = this.tabs.indexOf(tabName);
if (modeIndex == -1 && this.modeIndex == null) {
- // Selecting the first tab as default.
+ // Select the first tab as default.
this.set('modeIndex', 0);
}
if (modeIndex != -1 && modeIndex != this.modeIndex) {