Diff
Modified: trunk/Websites/perf.webkit.org/ChangeLog (179912 => 179913)
--- trunk/Websites/perf.webkit.org/ChangeLog 2015-02-11 02:41:20 UTC (rev 179912)
+++ trunk/Websites/perf.webkit.org/ChangeLog 2015-02-11 02:45:43 UTC (rev 179913)
@@ -1,5 +1,42 @@
2015-02-10 Ryosuke Niwa <rn...@webkit.org>
+ New perf dashboard shouldn't always show outliners
+ https://bugs.webkit.org/show_bug.cgi?id=141445
+
+ Reviewed by Chris Dumez.
+
+ Use the simple moving average with an average difference envelope to compute the y-axis range to show
+ to avoid expanding it spuriously to show one off outlier.
+
+ * public/v2/app.js:
+ (App.Pane): Don't show the full y-axis range by default.
+ (App.Pane._computeChartData): Use the first strategies for the moving average and the enveloping if
+ one is not specified by the user but without showing them in the charts.
+ (App.Pane._computeMovingAverage): Takes moving average and enveloping strategies as arguments instead
+ of retrieving via chosenMovingAverageStrategy and chosenEnvelopingStrategy.
+
+ (App.ChartsController._parsePaneList): Added showFullYAxis as a query string argument to each pane.
+ (App.ChartsController._serializePaneList): Ditto.
+
+ * public/v2/chart-pane.css: Added a CSS rule for when y-axis is clickable.
+
+ * public/v2/index.html: Pass in showFullYAxis as an argument to the main interactive chart.
+
+ * public/v2/interactive-chart.js:
+ (App.InteractiveChartComponent._constructGraphIfPossible): Add an event listener on y-axis labels when
+ the chart is interactive so that toggle showFullYAxis. Also hide the moving average and/or the envelope
+ if they are not specified by the user (i.e. only used to adjust y-axis range).
+ (App.InteractiveChartComponent._updateDomain): Don't exit early if y-axis domains are different even if
+ x-axis domain remained the same. Without this change, the charts would never redraw.
+ (App.InteractiveChartComponent._minMaxForAllTimeSeries): Use the moving average instead of the current
+ time series to compute the y-axis range if showFullYAxis is false. When showFullYAxis is true, expand
+ y-axis all the way down to 0 or the minimum value in the current time series whichever is smaller.
+
+ * public/v2/js/statistics.js:
+ (Statistics.MovingAverageStrategies): Use a wider window in Simple Moving Average by default.
+
+2015-02-10 Ryosuke Niwa <rn...@webkit.org>
+
Unreviewed build fix.
* public/v2/app.js:
Modified: trunk/Websites/perf.webkit.org/public/v2/app.js (179912 => 179913)
--- trunk/Websites/perf.webkit.org/public/v2/app.js 2015-02-11 02:41:20 UTC (rev 179912)
+++ trunk/Websites/perf.webkit.org/public/v2/app.js 2015-02-11 02:45:43 UTC (rev 179913)
@@ -297,6 +297,7 @@
metricId: null,
metric: null,
selectedItem: null,
+ showFullYAxis: false,
searchCommit: function (repository, keyword) {
var self = this;
var repositoryId = repository.get('id');
@@ -476,30 +477,36 @@
return;
var chartData = App.createChartData(this.get('fetchedData'));
- chartData.movingAverage = this._computeMovingAverage(chartData);
- this._updateStrategyConfigIfNeeded(this.get('chosenMovingAverageStrategy'), 'movingAverageConfig');
- this._updateStrategyConfigIfNeeded(this.get('chosenEnvelopingStrategy'), 'envelopingConfig');
+ var movingAverageStrategy = this.get('chosenMovingAverageStrategy');
+ this._updateStrategyConfigIfNeeded(movingAverageStrategy, 'movingAverageConfig');
+ var envelopingStrategy = this.get('chosenEnvelopingStrategy');
+ this._updateStrategyConfigIfNeeded(envelopingStrategy, 'envelopingConfig');
+
+ if (!movingAverageStrategy || !movingAverageStrategy.execute) {
+ movingAverageStrategy = Statistics.MovingAverageStrategies[0];
+ chartData.hideMovingAverage = true;
+ }
+ if (!envelopingStrategy || !envelopingStrategy.execute) {
+ envelopingStrategy = Statistics.EnvelopingStrategies[0];
+ chartData.hideEnvelope = true;
+ }
+
+ chartData.movingAverage = this._computeMovingAverage(chartData, movingAverageStrategy, envelopingStrategy);
+
this.set('chartData', chartData);
}.observes('chosenMovingAverageStrategy', 'chosenMovingAverageStrategy.parameterList.@each.value',
'chosenEnvelopingStrategy', 'chosenEnvelopingStrategy.parameterList.@each.value'),
- _computeMovingAverage: function (chartData)
+ _computeMovingAverage: function (chartData, movingAverageStrategy, envelopingStrategy)
{
var currentTimeSeriesData = chartData.current.series();
- var movingAverageStrategy = this.get('chosenMovingAverageStrategy');
- if (!movingAverageStrategy || !movingAverageStrategy.execute)
- return null;
-
var movingAverageValues = this._executeStrategy(movingAverageStrategy, currentTimeSeriesData);
if (!movingAverageValues)
return null;
- var envelopeDelta = null;
- var envelopingStrategy = this.get('chosenEnvelopingStrategy');
- if (envelopingStrategy && envelopingStrategy.execute)
- envelopeDelta = this._executeStrategy(envelopingStrategy, currentTimeSeriesData, [movingAverageValues]);
-
+ var envelopeDelta = this._executeStrategy(envelopingStrategy, currentTimeSeriesData, [movingAverageValues]);
+
return new TimeSeries(currentTimeSeriesData.map(function (point, index) {
var value = movingAverageValues[index];
return {
@@ -671,8 +678,9 @@
metricId: paneInfo[1],
selectedItem: selectedItem,
timeRange: timeRange,
- movingAverageConfig: paneInfo[3],
- envelopingConfig: paneInfo[4],
+ showFullYAxis: paneInfo[3],
+ movingAverageConfig: paneInfo[4],
+ envelopingConfig: paneInfo[5],
});
});
},
@@ -687,6 +695,7 @@
pane.get('platformId'),
pane.get('metricId'),
pane.get('timeRange') ? pane.get('timeRange').map(function (date) { return date.getTime() }) : pane.get('selectedItem'),
+ pane.get('showFullYAxis'),
pane.get('movingAverageConfig'),
pane.get('envelopingConfig'),
];
@@ -697,7 +706,7 @@
{
Ember.run.debounce(this, '_updateQueryString', 1000);
}.observes('sharedZoom', 'panes.@each.platform', 'panes.@each.metric', 'panes.@each.selectedItem', 'panes.@each.timeRange',
- 'panes.@each.movingAverageConfig', 'panes.@each.envelopingConfig'),
+ 'panes.@each.showFullYAxis', 'panes.@each.movingAverageConfig', 'panes.@each.envelopingConfig'),
_updateQueryString: function ()
{
Modified: trunk/Websites/perf.webkit.org/public/v2/chart-pane.css (179912 => 179913)
--- trunk/Websites/perf.webkit.org/public/v2/chart-pane.css 2015-02-11 02:41:20 UTC (rev 179912)
+++ trunk/Websites/perf.webkit.org/public/v2/chart-pane.css 2015-02-11 02:45:43 UTC (rev 179913)
@@ -442,6 +442,10 @@
stroke: none;
}
+.chart .axis.interactive text {
+ cursor: pointer;
+}
+
.chart .rangeBar {
display: block;
background-color: #fc6;
Modified: trunk/Websites/perf.webkit.org/public/v2/index.html (179912 => 179913)
--- trunk/Websites/perf.webkit.org/public/v2/index.html 2015-02-11 02:41:20 UTC (rev 179912)
+++ trunk/Websites/perf.webkit.org/public/v2/index.html 2015-02-11 02:45:43 UTC (rev 179913)
@@ -177,6 +177,7 @@
selection=timeRange
selectedPoints=selectedPoints
markedPoints=markedPoints
+ showFullYAxis=showFullYAxis
zoom="zoomed"}}
{{else}}
{{#if failure}}
Modified: trunk/Websites/perf.webkit.org/public/v2/interactive-chart.js (179912 => 179913)
--- trunk/Websites/perf.webkit.org/public/v2/interactive-chart.js 2015-02-11 02:41:20 UTC (rev 179912)
+++ trunk/Websites/perf.webkit.org/public/v2/interactive-chart.js 2015-02-11 02:45:43 UTC (rev 179913)
@@ -76,10 +76,15 @@
.attr("class", "x axis");
}
+ var isInteractive = this.get('interactive');
if (this.get('showYAxis')) {
this._yAxis = d3.svg.axis().scale(this._y).orient("left").ticks(6).tickFormat(chartData.formatter);
- this._yAxisLabels = svg.append("g")
- .attr("class", "y axis");
+
+ this._yAxisLabels = svg.append('g').attr('class', 'y axis' + (isInteractive ? ' interactive' : ''));
+ if (isInteractive) {
+ var self = this;
+ this._yAxisLabels.on('click', function () { self.toggleProperty('showFullYAxis'); });
+ }
}
this._clippedContainer = svg.append("g")
@@ -123,7 +128,8 @@
.attr("class", "target"));
}
- var foregroundClass = this._movingAverageTimeSeries ? '' : ' foreground';
+ var movingAverageIsVisible = this._movingAverageTimeSeries && !chartData.hideMovingAverage;
+ var foregroundClass = movingAverageIsVisible ? '' : ' foreground';
this._areas.push(this._clippedContainer
.append("path")
.datum(this._currentTimeSeriesData)
@@ -141,18 +147,21 @@
.attr("class", "dot" + foregroundClass)
.attr("r", this.get('chartPointRadius') || 1));
- if (this._movingAverageTimeSeries) {
+ if (movingAverageIsVisible) {
this._paths.push(this._clippedContainer
.append("path")
.datum(this._movingAverageTimeSeries.series())
.attr("class", "movingAverage"));
- this._areas.push(this._clippedContainer
- .append("path")
- .datum(this._movingAverageTimeSeries.series())
- .attr("class", "envelope"));
+
+ if (!chartData.hideEnvelope) {
+ this._areas.push(this._clippedContainer
+ .append("path")
+ .datum(this._movingAverageTimeSeries.series())
+ .attr("class", "envelope"));
+ }
}
- if (this.get('interactive')) {
+ if (isInteractive) {
this._currentItemLine = this._clippedContainer
.append("line")
.attr("class", "current-item");
@@ -193,11 +202,14 @@
var intrinsicXDomain = this._computeXAxisDomain(this._currentTimeSeriesData);
if (!xDomain)
xDomain = intrinsicXDomain;
- var currentDomain = this._x.domain();
- if (currentDomain && App.domainsAreEqual(currentDomain, xDomain))
+ var yDomain = this._computeYAxisDomain(xDomain[0], xDomain[1]);
+
+ var currentXDomain = this._x.domain();
+ var currentYDomain = this._y.domain();
+ if (currentXDomain && App.domainsAreEqual(currentXDomain, xDomain)
+ && currentYDomain && App.domainsAreEqual(currentYDomain, yDomain))
return currentDomain;
- var yDomain = this._computeYAxisDomain(xDomain[0], xDomain[1]);
this._x.domain(xDomain);
this._y.domain(yDomain);
return xDomain;
@@ -339,13 +351,17 @@
},
_minMaxForAllTimeSeries: function (startTime, endTime)
{
- var currentRange = this._currentTimeSeries.minMaxForTimeRange(startTime, endTime);
+ var shouldShowFullYAxis = this.get('showFullYAxis');
+ var mainTimeSeries = this._movingAverageTimeSeries && !shouldShowFullYAxis ? this._movingAverageTimeSeries : this._currentTimeSeries;
+ var currentRange = mainTimeSeries.minMaxForTimeRange(startTime, endTime);
+ if (shouldShowFullYAxis)
+ currentRange[0] = Math.min(0, currentRange[0]);
+
var baselineRange = this._baselineTimeSeries ? this._baselineTimeSeries.minMaxForTimeRange(startTime, endTime) : [Number.MAX_VALUE, Number.MIN_VALUE];
var targetRange = this._targetTimeSeries ? this._targetTimeSeries.minMaxForTimeRange(startTime, endTime) : [Number.MAX_VALUE, Number.MIN_VALUE];
- var movingAverageRange = this._movingAverageTimeSeries ? this._movingAverageTimeSeries.minMaxForTimeRange(startTime, endTime) : [Number.MAX_VALUE, Number.MIN_VALUE];
return [
- Math.min(currentRange[0], baselineRange[0], targetRange[0], movingAverageRange[0]),
- Math.max(currentRange[1], baselineRange[1], targetRange[1], movingAverageRange[1]),
+ Math.min(currentRange[0], baselineRange[0], targetRange[0]),
+ Math.max(currentRange[1], baselineRange[1], targetRange[1]),
];
},
_currentSelection: function ()
@@ -361,7 +377,7 @@
selection = null; // Otherwise the user has no way of clearing the selection.
this._relayoutDataAndAxes(selection);
- }.observes('domain'),
+ }.observes('domain', 'showFullYAxis'),
_selectionChanged: function ()
{
this._updateSelection(this.get('selection'));
Modified: trunk/Websites/perf.webkit.org/public/v2/js/statistics.js (179912 => 179913)
--- trunk/Websites/perf.webkit.org/public/v2/js/statistics.js 2015-02-11 02:41:20 UTC (rev 179912)
+++ trunk/Websites/perf.webkit.org/public/v2/js/statistics.js 2015-02-11 02:45:43 UTC (rev 179913)
@@ -104,8 +104,8 @@
id: 1,
label: 'Simple Moving Average',
parameterList: [
- {label: "Backward window size", value: 5, min: 2, step: 1},
- {label: "Forward window size", value: 3, min: 0, step: 1}
+ {label: "Backward window size", value: 8, min: 2, step: 1},
+ {label: "Forward window size", value: 4, min: 0, step: 1}
],
execute: function (backwardWindowSize, forwardWindowSize, values) {
var averages = new Array(values.length);