Title: [179710] trunk/Websites/perf.webkit.org
Revision
179710
Author
[email protected]
Date
2015-02-05 14:34:13 -0800 (Thu, 05 Feb 2015)

Log Message

New perf dashboard should compare results to baseline and target
https://bugs.webkit.org/show_bug.cgi?id=141286

Reviewed by Chris Dumez.

Compare the selected value against baseline and target values as done in v1. e.g. "5% below target"
Also use d3.format to format the selected value to show four significant figures.

* public/v2/app.js:
(App.Pane.searchCommit):
(App.Pane._fetch): Create time series here via createChartData so that _computeStatus can use them
to compute the status text without having to recreate them.
(App.createChartData): Added.
(App.PaneController._updateDetails): Use 3d.format on current and old values.
(App.PaneController._computeStatus): Added. Computes the status text.
(App.PaneController._relativeDifferentToLaterPointInTimeSeries): Added.
(App.AnalysisTaskController._fetchedManifest): Use createChartData as done in App.Pane._fetch. Also
format the values using chartData.formatter.

* public/v2/chart-pane.css: Enlarge the status text. Show the status text in red if it's worse than
the baseline and in blue if it's better than the target.

* public/v2/data.js:
(TimeSeries.prototype.findPointAfterTime): Added.

* public/v2/index.html: Added a new tbody for the status text and the selected value. Also fixed
the bug that we were not showing the old value's unit.

* public/v2/interactive-chart.js:
(App.InteractiveChartComponent._constructGraphIfPossible): Use chartData.formatter. Also cleaned up
the code to show the baseline and the target lines.

* public/v2/manifest.js:
(App.Manifest.fetchRunsWithPlatformAndMetric): Added smallerIsBetter.

Modified Paths

Diff

Modified: trunk/Websites/perf.webkit.org/ChangeLog (179709 => 179710)


--- trunk/Websites/perf.webkit.org/ChangeLog	2015-02-05 22:17:38 UTC (rev 179709)
+++ trunk/Websites/perf.webkit.org/ChangeLog	2015-02-05 22:34:13 UTC (rev 179710)
@@ -1,5 +1,42 @@
 2015-02-05  Ryosuke Niwa  <[email protected]>
 
+        New perf dashboard should compare results to baseline and target
+        https://bugs.webkit.org/show_bug.cgi?id=141286
+
+        Reviewed by Chris Dumez.
+
+        Compare the selected value against baseline and target values as done in v1. e.g. "5% below target"
+        Also use d3.format to format the selected value to show four significant figures.
+
+        * public/v2/app.js:
+        (App.Pane.searchCommit):
+        (App.Pane._fetch): Create time series here via createChartData so that _computeStatus can use them
+        to compute the status text without having to recreate them.
+        (App.createChartData): Added.
+        (App.PaneController._updateDetails): Use 3d.format on current and old values.
+        (App.PaneController._computeStatus): Added. Computes the status text.
+        (App.PaneController._relativeDifferentToLaterPointInTimeSeries): Added.
+        (App.AnalysisTaskController._fetchedManifest): Use createChartData as done in App.Pane._fetch. Also
+        format the values using chartData.formatter.
+
+        * public/v2/chart-pane.css: Enlarge the status text. Show the status text in red if it's worse than
+        the baseline and in blue if it's better than the target.
+
+        * public/v2/data.js:
+        (TimeSeries.prototype.findPointAfterTime): Added.
+
+        * public/v2/index.html: Added a new tbody for the status text and the selected value. Also fixed
+        the bug that we were not showing the old value's unit.
+
+        * public/v2/interactive-chart.js:
+        (App.InteractiveChartComponent._constructGraphIfPossible): Use chartData.formatter. Also cleaned up
+        the code to show the baseline and the target lines.
+
+        * public/v2/manifest.js:
+        (App.Manifest.fetchRunsWithPlatformAndMetric): Added smallerIsBetter.
+
+2015-02-05  Ryosuke Niwa  <[email protected]>
+
         Unreviewed build fix.
 
         * public/v2/app.js:

Modified: trunk/Websites/perf.webkit.org/public/v2/app.js (179709 => 179710)


--- trunk/Websites/perf.webkit.org/public/v2/app.js	2015-02-05 22:17:38 UTC (rev 179709)
+++ trunk/Websites/perf.webkit.org/public/v2/app.js	2015-02-05 22:34:13 UTC (rev 179710)
@@ -281,7 +281,7 @@
         CommitLogs.fetchForTimeRange(repositoryId, null, null, keyword).then(function (commits) {
             if (self.isDestroyed || !self.get('chartData') || !commits.length)
                 return;
-            var currentRuns = self.get('chartData').current.timeSeriesByCommitTime().series();
+            var currentRuns = self.get('chartData').current.series();
             if (!currentRuns.length)
                 return;
 
@@ -329,7 +329,7 @@
             App.Manifest.fetchRunsWithPlatformAndMetric(this.get('store'), platformId, metricId).then(function (result) {
                 self.set('platform', result.platform);
                 self.set('metric', result.metric);
-                self.set('chartData', result.runs);
+                self.set('chartData', App.createChartData(result));
             }, function (result) {
                 if (!result || typeof(result) === "string")
                     self.set('failure', 'Failed to fetch the JSON with an error: ' + result);
@@ -365,6 +365,19 @@
     }
 });
 
+App.createChartData = function (data)
+{
+    var runs = data.runs;
+    return {
+        current: runs.current.timeSeriesByCommitTime(),
+        baseline: runs.baseline ? runs.baseline.timeSeriesByCommitTime() : null,
+        target: runs.target ? runs.target.timeSeriesByCommitTime() : null,
+        unit: data.unit,
+        formatter: data.useSI ? d3.format('.4s') : d3.format('.4g'),
+        smallerIsBetter: data.smallerIsBetter,
+    };
+}
+
 App.encodePrettifiedJSON = function (plain)
 {
     function numberIfPossible(string) {
@@ -749,9 +762,11 @@
                 buildURL = builder.urlFromBuildNumber(buildNumber);
         }
 
+        var chartData = this.get('chartData');
         this.set('details', Ember.Object.create({
-            currentValue: currentMeasurement.mean().toFixed(2),
-            oldValue: oldMeasurement && selectedPoints ? oldMeasurement.mean().toFixed(2) : null,
+            status: this._computeStatus(currentPoint),
+            currentValue: chartData.formatter(currentMeasurement.mean()),
+            oldValue: oldMeasurement && selectedPoints ? chartData.formatter(oldMeasurement.mean()) : null,
             buildNumber: buildNumber,
             buildURL: buildURL,
             buildTime: currentMeasurement.formattedBuildTime(),
@@ -764,6 +779,40 @@
         var points = this.get('selectedPoints');
         this.set('cannotAnalyze', !this.get('newAnalysisTaskName') || !points || points.length < 2);
     }.observes('newAnalysisTaskName'),
+    _computeStatus: function (currentPoint)
+    {
+        var chartData = this.get('chartData');
+
+        var diffFromBaseline = this._relativeDifferentToLaterPointInTimeSeries(currentPoint, chartData.baseline);
+        var diffFromTarget = this._relativeDifferentToLaterPointInTimeSeries(currentPoint, chartData.target);
+
+        var label = '';
+        var className = '';
+        var formatter = d3.format('.3p');
+
+        var smallerIsBetter = chartData.smallerIsBetter;
+        if (diffFromBaseline !== undefined && diffFromBaseline > 0 == smallerIsBetter) {
+            label = formatter(Math.abs(diffFromBaseline)) + ' ' + (smallerIsBetter ? 'above' : 'below') + ' baseline';
+            className = 'worse';
+        } else if (diffFromTarget !== undefined && diffFromTarget < 0 == smallerIsBetter) {
+            label = formatter(Math.abs(diffFromTarget)) + ' ' + (smallerIsBetter ? 'below' : 'above') + ' target';
+            className = 'better';
+        } else if (diffFromTarget !== undefined)
+            label = formatter(Math.abs(diffFromTarget)) + ' until target';
+
+        return {className: className, label: label};
+    },
+    _relativeDifferentToLaterPointInTimeSeries: function (currentPoint, timeSeries)
+    {
+        if (!currentPoint || !timeSeries)
+            return undefined;
+        
+        var referencePoint = timeSeries.findPointAfterTime(currentPoint.time);
+        if (!referencePoint)
+            return undefined;
+
+        return (currentPoint.value - referencePoint.value) / referencePoint.value;
+    }
 });
 
 
@@ -835,17 +884,18 @@
         highlightedItems[start.measurement.id()] = true;
         highlightedItems[end.measurement.id()] = true;
 
+        var chartData = App.createChartData(data);
         var formatedPoints = currentTimeSeries.seriesBetweenPoints(start, end).map(function (point, index) {
             return {
                 id: point.measurement.id(),
                 measurement: point.measurement,
                 label: 'Point ' + (index + 1),
-                value: point.value + (runs.unit ? ' ' + runs.unit : ''),
+                value: chartData.formatter(point.value) + (data.unit ? ' ' + data.unit : ''),
             };
         });
 
         var margin = (end.time - start.time) * 0.1;
-        this.set('chartData', runs);
+        this.set('chartData', chartData);
         this.set('chartDomain', [start.time - margin, +end.time + margin]);
         this.set('highlightedItems', highlightedItems);
         this.set('analysisPoints', formatedPoints);

Modified: trunk/Websites/perf.webkit.org/public/v2/chart-pane.css (179709 => 179710)


--- trunk/Websites/perf.webkit.org/public/v2/chart-pane.css	2015-02-05 22:17:38 UTC (rev 179709)
+++ trunk/Websites/perf.webkit.org/public/v2/chart-pane.css	2015-02-05 22:34:13 UTC (rev 179710)
@@ -210,6 +210,7 @@
 .chart-pane .details-table td table td {
     word-break: break-word;
     border-top: solid 1px #ccc;
+    border-bottom: solid 1px #ccc;
     padding: 0.2rem;
 }
 
@@ -232,6 +233,14 @@
     content: " : ";
 }
 
+.chart-pane .details-table .status th {
+    visibility: hidden;
+}
+
+.chart-pane .details-table .status td {
+    font-size: 1rem;
+}
+
 .chart-pane .chart {
     height: 100%;
 }
@@ -257,10 +266,6 @@
     stroke-width: 1.5px;
 }
 
-.chart .commit-time-line {
-    stroke: #999;
-}
-
 .chart .dot {
     fill: #666;
     stroke: none;
@@ -272,17 +277,23 @@
     opacity: 0.8;
 }
 
-.chart path.area.baseline {
+.chart path.current {
+    stroke: #999;
+}
+
+.chart path.baseline {
     stroke: #f66;
-    fill: #fdd;
-    opacity: 0.4;
 }
+.chart-pane .status .worse {
+    color: #c33;
+}
 
-.chart path.area.target {
+.chart path.target {
     stroke: #66f;
-    fill: #ddf;
-    opacity: 0.4;
 }
+.chart-pane .status .better {
+    color: #33c;
+}
 
 .chart .axis,
 .chart .domain {

Modified: trunk/Websites/perf.webkit.org/public/v2/data.js (179709 => 179710)


--- trunk/Websites/perf.webkit.org/public/v2/data.js	2015-02-05 22:17:38 UTC (rev 179709)
+++ trunk/Websites/perf.webkit.org/public/v2/data.js	2015-02-05 22:34:13 UTC (rev 179710)
@@ -360,6 +360,11 @@
     return this._series.find(function (point) { return point.measurement.id() == measurementId; });
 }
 
+TimeSeries.prototype.findPointAfterTime = function (time)
+{
+    return this._series.find(function (point) { return point.time >= time; });
+}
+
 TimeSeries.prototype.seriesBetweenPoints = function (startPoint, endPoint)
 {
     if (!startPoint.seriesIndex || !endPoint.seriesIndex)

Modified: trunk/Websites/perf.webkit.org/public/v2/index.html (179709 => 179710)


--- trunk/Websites/perf.webkit.org/public/v2/index.html	2015-02-05 22:17:38 UTC (rev 179709)
+++ trunk/Websites/perf.webkit.org/public/v2/index.html	2015-02-05 22:34:13 UTC (rev 179710)
@@ -254,10 +254,21 @@
                 {{/if}}
             {{/each}}
             </tbody>
-            <tr><th>Current</th><td>{{details.currentValue}} {{chartData.unit}}
-            {{#if details.oldValue}}
-                (from {{details.oldValue}})
-            {{/if}}</td></tr>
+            <tbody class="status">
+                <tr>
+                    <th>Current</th>
+                    <td>
+                        {{details.currentValue}} {{chartData.unit}}
+                        {{#if details.oldValue}}
+                            (from {{details.oldValue}} {{chartData.unit}})
+                        {{/if}}
+                        {{#if details.status.label}}
+                            <br>
+                            <span {{bind-attr class=details.status.className}}>{{details.status.label}}</span>
+                        {{/if}}
+                    </td>
+                </tr>
+            </tbody>
             {{#if details.buildNumber}}
                 <tr>
                     <th>Build</th>

Modified: trunk/Websites/perf.webkit.org/public/v2/interactive-chart.js (179709 => 179710)


--- trunk/Websites/perf.webkit.org/public/v2/interactive-chart.js	2015-02-05 22:17:38 UTC (rev 179709)
+++ trunk/Websites/perf.webkit.org/public/v2/interactive-chart.js	2015-02-05 22:34:13 UTC (rev 179710)
@@ -66,8 +66,7 @@
         }
 
         if (this.get('showYAxis')) {
-            this._yAxis = d3.svg.axis().scale(this._y).orient("left").ticks(6).tickFormat(
-                chartData.useSI ? d3.format("s") : d3.format(".3g"));
+            this._yAxis = d3.svg.axis().scale(this._y).orient("left").ticks(6).tickFormat(chartData.formatter);
             this._yAxisLabels = svg.append("g")
                 .attr("class", "y axis");
         }
@@ -100,31 +99,24 @@
             this._highlights.remove();
         this._highlights = null;
 
-        this._currentTimeSeries = chartData.current.timeSeriesByCommitTime();
+        this._currentTimeSeries = chartData.current;
         this._currentTimeSeriesData = this._currentTimeSeries.series();
-        this._baselineTimeSeries = chartData.baseline ? chartData.baseline.timeSeriesByCommitTime() : null;
-        this._targetTimeSeries = chartData.target ? chartData.target.timeSeriesByCommitTime() : null;
+        this._baselineTimeSeries = chartData.baseline;
+        this._targetTimeSeries = chartData.target;
 
         this._yAxisUnit = chartData.unit;
 
-        var minMax = this._minMaxForAllTimeSeries();
-        var smallEnoughValue = minMax[0] - (minMax[1] - minMax[0]) * 10;
-        var largeEnoughValue = minMax[1] + (minMax[1] - minMax[0]) * 10;
-
-        // FIXME: Flip the sides based on smallerIsBetter-ness.
         if (this._baselineTimeSeries) {
-            var data = ""
-            this._areas.push(this._clippedContainer
+            this._paths.push(this._clippedContainer
                 .append("path")
-                .datum(data.map(function (point) { return {time: point.time, value: point.value, interval: point.interval ? point.interval : [point.value, largeEnoughValue]}; }))
-                .attr("class", "area baseline"));
+                .datum(this._baselineTimeSeries.series())
+                .attr("class", "baseline"));
         }
         if (this._targetTimeSeries) {
-            var data = ""
-            this._areas.push(this._clippedContainer
+            this._paths.push(this._clippedContainer
                 .append("path")
-                .datum(data.map(function (point) { return {time: point.time, value: point.value, interval: point.interval ? point.interval : [smallEnoughValue, point.value]}; }))
-                .attr("class", "area target"));
+                .datum(this._targetTimeSeries.series())
+                .attr("class", "target"));
         }
 
         this._areas.push(this._clippedContainer
@@ -135,7 +127,7 @@
         this._paths.push(this._clippedContainer
             .append("path")
             .datum(this._currentTimeSeriesData)
-            .attr("class", "commit-time-line"));
+            .attr("class", "current"));
 
         this._dots.push(this._clippedContainer
             .selectAll(".dot")

Modified: trunk/Websites/perf.webkit.org/public/v2/manifest.js (179709 => 179710)


--- trunk/Websites/perf.webkit.org/public/v2/manifest.js	2015-02-05 22:17:38 UTC (rev 179709)
+++ trunk/Websites/perf.webkit.org/public/v2/manifest.js	2015-02-05 22:34:13 UTC (rev 179710)
@@ -281,12 +281,9 @@
                 'Heap': 'bytes',
                 'Allocations': 'bytes'
             }[suffix];
+            var smallerIsBetter = unit != 'fps' && unit != '/s'; // Assume smaller is better for unit-less metrics.
 
-            // FIXME: Include this information in JSON and process it in RunsData.fetchRuns
-            runs.unit = unit;
-            runs.useSI = unit == 'bytes';
-
-            return {platform: platform, metric: metric, runs: runs};
+            return {platform: platform, metric: metric, runs: runs, unit: unit, useSI: unit == 'bytes', smallerIsBetter: smallerIsBetter};
         });
     },
 }).create();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to