diff options
author | 2016-08-10 12:55:13 -0800 | |
---|---|---|
committer | 2016-08-10 14:03:33 -0700 | |
commit | abab14f46ae5ab12a351d3b1ca97e49f7fa8fe3b (patch) | |
tree | 149f5c5d05a15248040b79531162044f03ae137e | |
parent | 49675246e8650a6d3ab17216a17c7eb1ea4305d6 (diff) |
Integrate vz-histogram-timeseries into tensorboard.
Change: 129907147
4 files changed, 221 insertions, 3 deletions
diff --git a/tensorflow/tensorboard/components/tf-dashboard-common/dashboard-style.html b/tensorflow/tensorboard/components/tf-dashboard-common/dashboard-style.html index 095a6cf9a5..3884a26694 100644 --- a/tensorflow/tensorboard/components/tf-dashboard-common/dashboard-style.html +++ b/tensorflow/tensorboard/components/tf-dashboard-common/dashboard-style.html @@ -16,19 +16,23 @@ position: relative; } - .card .card-title { + .card .card-title, .card .card-subtitle { flex-grow: 0; flex-shrink: 0; - margin-bottom: 10px; font-size: 14px; text-overflow: ellipsis; overflow: hidden; } + .card .card-subtitle { + font-size: 12px; + } + .card .card-content { flex-grow: 1; flex-shrink: 1; display: flex; + margin-top: 10px; } .card .card-bottom-row { position: absolute; diff --git a/tensorflow/tensorboard/components/tf-globals/globals.ts b/tensorflow/tensorboard/components/tf-globals/globals.ts index 1e908ec034..f2902bf0c0 100644 --- a/tensorflow/tensorboard/components/tf-globals/globals.ts +++ b/tensorflow/tensorboard/components/tf-globals/globals.ts @@ -16,7 +16,8 @@ limitations under the License. /* tslint:disable:no-namespace */ module TF.Globals { // The names of TensorBoard tabs. - export var TABS = ['events', 'images', 'audio', 'graphs', 'distributions']; + export var TABS = + ['events', 'images', 'audio', 'graphs', 'distributions', 'histograms']; // If true, TensorBoard stores its hash in the URI state. // If false, tab switching in TensorBoard will not update location hash, diff --git a/tensorflow/tensorboard/components/tf-histogram-dashboard/tf-histogram-dashboard.html b/tensorflow/tensorboard/components/tf-histogram-dashboard/tf-histogram-dashboard.html new file mode 100644 index 0000000000..bc3348d85a --- /dev/null +++ b/tensorflow/tensorboard/components/tf-histogram-dashboard/tf-histogram-dashboard.html @@ -0,0 +1,202 @@ +<link rel="import" href="../polymer/polymer.html"> +<link rel="import" href="../tf-chart-scaffold/tf-chart-scaffold.html"> +<link rel="import" href="../tf-event-dashboard/tf-run-selector.html"> +<link rel="import" href="../tf-color-scale/tf-color-scale.html"> +<link rel="import" href="../tf-dashboard-common/tf-dashboard.html"> +<link rel="import" href="../tf-categorizer/tf-categorizer.html"> +<link rel="import" href="../tf-option-selector/tf-option-selector.html"> +<link rel="import" href="../tf-collapsable-pane/tf-collapsable-pane.html"> +<link rel="import" href="../vz-histogram-timeseries/vz-histogram-timeseries.html"> +<link rel="import" href="../iron-collapse/iron-collapse.html"> +<link rel="import" href="../paper-icon-button/paper-icon-button.html"> +<link rel="import" href="../tf-imports/lodash.html"> +<link rel="import" href="../tf-backend/tf-backend.html"> + +<!-- +tf-histogram-dashboard is a complete frontend that loads runs from a backend, +and creates chart panes that display data for those runs. + +It provides a categorizer, run selector, and x type selector, by which the user +can customize how data is organized and displayed. + +Each chart has a button that can toggle whether it is "selected"; selectedRuns +charts are larger. + +Organizationally, the #plumbing div contains components that have no concrete +manifestation and just effect data bindings or data loading. The #sidebar contains +shared controls like the tf-categorizer, tf-run-selector, and tf-x-type-selector. +The #center div contains vz-histogram-timeseries embedded inside +tf-collapsable-panes. +--> +<dom-module id="tf-histogram-dashboard"> + <template> + <div id="plumbing"> + <tf-color-scale + id="colorScale" + runs="[[runs]]" + out-color-scale="{{colorScale}}" + ></tf-color-scale> + </div> + + <tf-dashboard-layout> + <div class="sidebar"> + <div class="sidebar-section"> + <tf-categorizer + id="categorizer" + tags="[[_visibleTags]]" + categories="{{categories}}" + ></tf-categorizer> + </div> + <div class="sidebar-section"> + <tf-option-selector + id="histogramModeSelector" + name="Histogram Mode" + selected-id="{{_histogramMode}}" + > + <paper-button id="overlay">overlay</paper-button> + <paper-button id="offset">offset</paper-button> + </tf-option-selector> + </div> + <div class="sidebar-section"> + <tf-option-selector + id="timePropertySelector" + name="Offset Time Axis" + selected-id="{{_timeProperty}}" + > + <paper-button id="step">step</paper-button> + <paper-button id="relative">relative</paper-button> + <paper-button id="wall_time">wall</paper-button> + </tf-option-selector> + </div> + <div class="sidebar-section"> + <tf-run-selector + id="runSelector" + runs="[[runs]]" + color-scale="[[colorScale]]" + out-selected="{{selectedRuns}}" + ></tf-run-selector> + </div> + </div> + + <div class="center"> + <tf-no-data-warning + data-type="histogram" + show-warning="[[dataNotFound]]" + ></tf-no-data-warning> + <template is="dom-repeat" items="[[categories]]"> + <tf-collapsable-pane name="[[item.name]]" count="[[_count(item.tags, selectedRuns.*, runToCompressedHistograms.*)]]"> + <div class="layout horizontal wrap"> + <template is="dom-repeat" items="[[item.tags]]" as="tag"> + <template is="dom-repeat" items="[[selectedRuns]]" as="run"> + <template is="dom-if" if="[[_exists(run, tag, run2tag.*)]]"> + <div class="card"> + <span class="card-title">[[tag]]</span> + <span class="card-subtitle">[[run]]</span> + <div class="card-content"> + <tf-chart-scaffold + tag="[[tag]]" + visible-series="[[_array(run)]]" + data-provider="[[dataProvider]]" + > + <vz-histogram-timeseries + id="chart" + time-property="[[_timeProperty]]" + mode="[[_histogramMode]]" + color-scale="[[_colorScaleFunction]]" + on-keyup="toggleSelected" + tabindex="2" + ></vz-histogram-timeseries> + </tf-chart-scaffold> + <paper-icon-button + class="expand-button" + icon="fullscreen" + on-tap="toggleSelected" + ></paper-icon-button> + </div> + </div> + </template> + </template> + </template> + </div> + </tf-collapsable-pane> + </template> + </div> + </tf-dashboard-layout> + + <style include="dashboard-style"></style> + </template> + + <script> + Polymer({ + is: "tf-histogram-dashboard", + behaviors: [ + TF.Dashboard.ReloadBehavior("tf-chart-scaffold"), + TF.Backend.Behavior, + ], + properties: { + _histogramMode: { + type: String, + value: "offset" + }, + _timeProperty: { + type: String, + value: "step" + }, + _visibleTags: { + type: Array, + computed: "_getVisibleTags(selectedRuns.*, run2tag.*)" + }, + _colorScaleFunction: { + type: Function, + computed: "_getColorScaleFunction(colorScale)" + }, + colorScale: Object, + dataType: {value: "histogram"}, + }, + _exists: function(run, tag) { + return this.run2tag[run].indexOf(tag) !== -1; + }, + attached: function() { + this.async(function() { + this.fire("rendered"); + }); + }, + _array: function(x) { + return [x]; + }, + _count: function(tags) { + var targetTags = {}; + tags.forEach(function(t) { + targetTags[t] = true; + }); + var count = 0; + var _this = this; + this.selectedRuns.forEach(function(r) { + _this.run2tag[r].forEach(function(t) { + if (targetTags[t]) { + count++; + } + }); + }); + return count; + }, + _getVisibleTags: function() { + var keys = this.selectedRuns; + var dict = this.run2tag; + return _.union.apply(null, keys.map(function(k) {return dict[k]})); + }, + _getColorScaleFunction: function() { + return this.colorScale.scale.bind(this.colorScale); + }, + toggleSelected: function(e) { + var currentTarget = Polymer.dom(e.currentTarget); + var parentDiv = currentTarget.parentNode.parentNode; + parentDiv.classList.toggle("selected"); + var chartScaffold = currentTarget.previousElementSibling; + if (chartScaffold) { + chartScaffold.chart().redraw(); + } + }, + }); + </script> +</dom-module> diff --git a/tensorflow/tensorboard/components/tf-tensorboard/tf-tensorboard.html b/tensorflow/tensorboard/components/tf-tensorboard/tf-tensorboard.html index 953f6474a6..c45bdf00d5 100644 --- a/tensorflow/tensorboard/components/tf-tensorboard/tf-tensorboard.html +++ b/tensorflow/tensorboard/components/tf-tensorboard/tf-tensorboard.html @@ -8,6 +8,7 @@ <link rel="import" href="../tf-globals/tf-globals.html"> <link rel="import" href="../tf-event-dashboard/tf-event-dashboard.html"> <link rel="import" href="../tf-distribution-dashboard/tf-distribution-dashboard.html"> +<link rel="import" href="../tf-histogram-dashboard/tf-histogram-dashboard.html"> <link rel="import" href="../tf-image-dashboard/tf-image-dashboard.html"> <link rel="import" href="../tf-audio-dashboard/tf-audio-dashboard.html"> <link rel="import" href="../tf-graph-dashboard/tf-graph-dashboard.html"> @@ -96,6 +97,13 @@ allows the user to toggle between various dashboards. backend="[[_backend]]" ></tf-distribution-dashboard> </template> + + <template is="dom-if" if="[[_modeIsHistograms(mode)]]"> + <tf-histogram-dashboard + id="histograms" + backend="[[_backend]]" + ></tf-histogram-dashboard> + </template> </div> </paper-header-panel> @@ -230,6 +238,9 @@ allows the user to toggle between various dashboards. _modeIsDistributions: function(mode) { return mode === "distributions"; }, + _modeIsHistograms: function(mode) { + return mode === "histograms"; + }, selectedDashboard: function() { var dashboard = this.$$("#" + this.mode); if (dashboard == null) { |