aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2017-03-16 14:51:15 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2017-03-16 16:14:28 -0700
commit57737d10ef277e4ee4f0f89b0e55f02d71c043d6 (patch)
tree0946a19d77f232e248f9761b8be591230fef88e5
parent1316eeb6970839049329102e81297a216012db73 (diff)
Update opensource vulcanized HTML file for Tensorboard.
This update contains refinements to the charts in the scalars dashboard. Change: 150380169
-rw-r--r--tensorflow/tensorboard/dist/tf-tensorboard.html153
1 files changed, 133 insertions, 20 deletions
diff --git a/tensorflow/tensorboard/dist/tf-tensorboard.html b/tensorflow/tensorboard/dist/tf-tensorboard.html
index 635b93a2ac..7922c69793 100644
--- a/tensorflow/tensorboard/dist/tf-tensorboard.html
+++ b/tensorflow/tensorboard/dist/tf-tensorboard.html
@@ -1350,7 +1350,7 @@ var TF;
.sidebar-section {
border-top: solid 1px rgba(0, 0, 0, 0.12);
- padding: 20px 0px 20px 30px;
+ padding: 15px 0px 15px 30px;
}
.sidebar-section:first-child {
@@ -2853,7 +2853,7 @@ var TF;
<style>
:host {
display: block;
- padding-bottom: 15px;
+ padding-bottom: 5px;
}
paper-checkbox {
--paper-checkbox-checked-color: var(--paper-grey-600);
@@ -3673,6 +3673,11 @@ var Categorizer;
stroke-width: 1px;
}
+ #chartsvg line.guide-line {
+ stroke: #999;
+ stroke-width: 1.5px;
+ }
+
</style>
</template>
<script>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
@@ -3710,7 +3715,7 @@ var Plottable;
* Component Group.
* TODO(danmane) - merge this into Plottable
*/
- function DragZoomLayer(xScale, yScale) {
+ function DragZoomLayer(xScale, yScale, unzoomMethod) {
var _this = _super.call(this) || this;
_this.isZoomed = false;
_this.easeFn = d3.ease('cubic-in-out');
@@ -3722,6 +3727,7 @@ var Plottable;
_this._doubleClickInteraction = new Plottable.Interactions.DoubleClick();
_this._doubleClickInteraction.attachTo(_this);
_this.setupCallbacks();
+ _this.unzoomMethod = unzoomMethod;
return _this;
}
/**
@@ -3805,21 +3811,12 @@ var Plottable;
return;
}
this.isZoomed = false;
- // Some Plottable magic follows which ensures that when we un-zoom, we
- // un-zoom to the current extent of the data; i.e. if new data was loaded
- // since we zoomed, we should un-zoom to the extent of the new data.
- // this basically replicates the autoDomain logic in Plottable.
- // it uses the internal methods to get the same boundaries that autoDomain
- // would, but allows us to interpolate the zoom with a nice animation.
var xScale = this.xScale();
- var yScale = this.yScale();
xScale._domainMin = null;
xScale._domainMax = null;
- yScale._domainMin = null;
- yScale._domainMax = null;
var xDomain = xScale._getExtent();
- var yDomain = yScale._getExtent();
- this.interpolateZoom(xDomain[0], xDomain[1], yDomain[0], yDomain[1]);
+ this.xScale().domain(xDomain);
+ this.unzoomMethod();
};
// If we are zooming, disable interactions, to avoid contention
DragZoomLayer.prototype.isZooming = function (isZooming) {
@@ -3891,6 +3888,7 @@ var VZ;
this.colorScale = colorScale;
this.tooltip = tooltip;
this.datasets = [];
+ this._ignoreYOutliers = true;
// lastPointDataset is a dataset that contains just the last point of
// every dataset we're currently drawing.
this.lastPointsDataset = new Plottable.Dataset();
@@ -3914,12 +3912,15 @@ var VZ;
var yFormatter = VZ.ChartHelpers.multiscaleFormatter(VZ.ChartHelpers.Y_AXIS_FORMATTER_PRECISION);
this.yAxis.margin(0).tickLabelPadding(5).formatter(yFormatter);
this.yAxis.usesTextWidthApproximation(true);
- this.dzl = new Plottable.DragZoomLayer(this.xScale, this.yScale);
+ this.dzl = new Plottable.DragZoomLayer(this.xScale, this.yScale, this.updateSpecialDatasets.bind(this));
var center = this.buildPlot(this.xAccessor, this.xScale, this.yScale);
this.gridlines =
new Plottable.Components.Gridlines(this.xScale, this.yScale);
- this.center =
- new Plottable.Components.Group([this.gridlines, center, this.dzl]);
+ var xZeroLine = new Plottable.Components.GuideLineLayer('horizontal');
+ xZeroLine.scale(this.yScale).value(0);
+ var yZeroLine = new Plottable.Components.GuideLineLayer('vertical');
+ yZeroLine.scale(this.xScale).value(0);
+ this.center = new Plottable.Components.Group([this.gridlines, xZeroLine, yZeroLine, center, this.dzl]);
this.outer = new Plottable.Components.Table([
[this.yAxis, this.center],
[null, this.xAxis]
@@ -3975,6 +3976,12 @@ var VZ;
}
this.updateSpecialDatasets();
};
+ LineChart.prototype.ignoreYOutliers = function (ignoreYOutliers) {
+ if (ignoreYOutliers !== this._ignoreYOutliers) {
+ this._ignoreYOutliers = ignoreYOutliers;
+ this.updateSpecialDatasets();
+ }
+ };
LineChart.prototype.updateSpecialDatasets = function () {
if (this.smoothingEnabled) {
this.updateSpecialDatasetsWithAccessor(this.smoothedAccessor);
@@ -4038,6 +4045,13 @@ var VZ;
};
var nanData = _.flatten(this.datasets.map(datasetToNaNData));
this.nanDataset.data(nanData);
+ var datasetToValues = function (d) {
+ return d.data().map(function (x) { return accessor(x, -1, d); });
+ };
+ var vals = _.flatten(this.datasets.map(datasetToValues));
+ vals = vals.filter(function (x) { return x === x && x !== Infinity && x !== -Infinity; });
+ var domain = VZ.ChartHelpers.computeDomain(vals, this._ignoreYOutliers);
+ this.yScale.domain(domain);
};
LineChart.prototype.setupTooltips = function (plot) {
var _this = this;
@@ -4396,6 +4410,41 @@ var VZ;
};
}
ChartHelpers.multiscaleFormatter = multiscaleFormatter;
+ /* Compute an appropriate domain given an array of all the values that are
+ * going to be displayed. If ignoreOutliers is true, it will ignore the
+ * lowest 10% and highest 10% of the data when computing a domain.
+ * It has n log n performance when ignoreOutliers is true, as it needs to
+ * sort the data.
+ */
+ function computeDomain(values, ignoreOutliers) {
+ if (values.length === 0) {
+ return [-0.1, 1.1];
+ }
+ var a;
+ var b;
+ if (ignoreOutliers) {
+ var sorted = _.sortBy(values);
+ a = d3.quantile(sorted, 0.10);
+ b = d3.quantile(sorted, 0.90);
+ }
+ else {
+ a = d3.min(values);
+ b = d3.max(values);
+ }
+ // When the data all fits into the unit interval, we switch to a consistent
+ // domain for unit data. This is helpful for proportional parameters like
+ // error rates or % of queue that is full. This way, users can meaningfully
+ // compare charts and see information at a glance (if the value is always
+ // 1, it appears at top of the chart, 0 is bottom, etc.)
+ if (a >= 0 && b <= 1) {
+ return [-0.1, 1.1];
+ }
+ var padding = (b - a) * 0.20;
+ var domain = [a - padding, b + padding];
+ domain = d3.scale.linear().domain(domain).nice().domain();
+ return domain;
+ }
+ ChartHelpers.computeDomain = computeDomain;
function accessorize(key) {
return function (d, index, dataset) { return d[key]; };
}
@@ -4569,6 +4618,15 @@ var VZ;
},
/**
+ * Whether to ignore outlier data when computing the yScale domain.
+ */
+
+ ignoreYOutliers: {
+ type: Boolean,
+ value: true,
+ },
+
+ /**
* Change how the tooltip is sorted. Allows:
* - "default" - Sort the tooltip by input order.
* - "ascending" - Sort the tooltip by ascending value.
@@ -4610,7 +4668,8 @@ var VZ;
"_reloadFromCache(_chart)",
"_smoothingChanged(smoothingEnabled, smoothingWeight, _chart)",
"_tooltipSortingMethodChanged(tooltipSortingMethod, _chart)",
- "_tooltipPositionChanged(tooltipPosition, _chart)"
+ "_tooltipPositionChanged(tooltipPosition, _chart)",
+ "_outliersChanged(ignoreYOutliers, _chart)"
],
/**
@@ -4698,6 +4757,12 @@ var VZ;
this._chart.smoothingDisable();
}
},
+ _outliersChanged: function() {
+ if (!this._chart) {
+ return;
+ }
+ this._chart.ignoreYOutliers(this.ignoreYOutliers);
+ },
_tooltipSortingMethodChanged: function() {
if(this._chart) {
this._chart.setTooltipSortingMethod(this.tooltipSortingMethod);
@@ -4722,7 +4787,12 @@ var VZ;
<div class="sidebar">
<tf-sidebar-helper backend="[[backend]]" categories="{{_categories}}" color-scale="[[_colorScale]]" run2tag="[[run2tag]]" runs="[[runs]]" selected-runs="{{_selectedRuns}}">
<div class="extend-first-section">
- <paper-checkbox id="download-option" checked="{{_showDownloadLinks}}">Data download links</paper-checkbox>
+ <div class="line-item">
+ <paper-checkbox id="download-option" checked="{{_showDownloadLinks}}">Show data download links</paper-checkbox>
+ </div>
+ <div class="line-item">
+ <paper-checkbox id="outliersCheckbox" checked="{{_ignoreYOutliers}}">Ignore outliers in chart scaling</paper-checkbox>
+ </div>
<div id="tooltip-sorting">
<div id="tooltip-sorting-label">Tooltip sorting method:</div>
<paper-dropdown-menu no-label-float="" selected-item-label="{{_tooltipSortingMethod}}">
@@ -4750,7 +4820,7 @@ var VZ;
<div class="center">
<tf-panes-helper categories="[[_categories]]" color-scale="[[_colorScale]]" data-type="[[dataType]]" data-provider="[[dataProvider]]" run2tag="[[run2tag]]" selected-runs="[[_selectedRuns]]" show-download-links="[[_showDownloadLinks]]" download-link-url-function="[[scalarUrl]]">
<template>
- <vz-line-chart x-type="[[_xType]]" color-scale="[[_colorScale]]" smoothing-enabled="[[_smoothingEnabled]]" smoothing-weight="[[_smoothingWeight]]" tooltip-sorting-method="[[_tooltipSortingMethod]]"></vz-line-chart>
+ <vz-line-chart x-type="[[_xType]]" color-scale="[[_colorScale]]" smoothing-enabled="[[_smoothingEnabled]]" smoothing-weight="[[_smoothingWeight]]" tooltip-sorting-method="[[_tooltipSortingMethod]]" ignore-y-outliers="[[_ignoreYOutliers]]"></vz-line-chart>
<paper-icon-button class="log-button" icon="line-weight" on-tap="toggleLogScale" title="Toggle y-axis log scale"></paper-icon-button>
</template>
</tf-panes-helper>
@@ -4791,6 +4861,10 @@ var VZ;
--paper-input-container-focus-color: var(--tb-orange-strong);
width: 105px;
}
+ .line-item {
+ display: block;
+ padding-top: 5px;
+ }
</style>
</template>
@@ -4830,6 +4904,10 @@ var VZ;
type: Boolean,
computed: '_computeSmoothingEnabled(_smoothingWeight)'
},
+ _ignoreYOutliers: {
+ type: Boolean,
+ value: true,
+ },
_xType: {
type: String,
value: "step"
@@ -5061,6 +5139,41 @@ var VZ;
};
}
ChartHelpers.multiscaleFormatter = multiscaleFormatter;
+ /* Compute an appropriate domain given an array of all the values that are
+ * going to be displayed. If ignoreOutliers is true, it will ignore the
+ * lowest 10% and highest 10% of the data when computing a domain.
+ * It has n log n performance when ignoreOutliers is true, as it needs to
+ * sort the data.
+ */
+ function computeDomain(values, ignoreOutliers) {
+ if (values.length === 0) {
+ return [-0.1, 1.1];
+ }
+ var a;
+ var b;
+ if (ignoreOutliers) {
+ var sorted = _.sortBy(values);
+ a = d3.quantile(sorted, 0.10);
+ b = d3.quantile(sorted, 0.90);
+ }
+ else {
+ a = d3.min(values);
+ b = d3.max(values);
+ }
+ // When the data all fits into the unit interval, we switch to a consistent
+ // domain for unit data. This is helpful for proportional parameters like
+ // error rates or % of queue that is full. This way, users can meaningfully
+ // compare charts and see information at a glance (if the value is always
+ // 1, it appears at top of the chart, 0 is bottom, etc.)
+ if (a >= 0 && b <= 1) {
+ return [-0.1, 1.1];
+ }
+ var padding = (b - a) * 0.20;
+ var domain = [a - padding, b + padding];
+ domain = d3.scale.linear().domain(domain).nice().domain();
+ return domain;
+ }
+ ChartHelpers.computeDomain = computeDomain;
function accessorize(key) {
return function (d, index, dataset) { return d[key]; };
}