<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[196297] trunk/PerformanceTests</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/196297">196297</a></dd>
<dt>Author</dt> <dd>jonlee@apple.com</dd>
<dt>Date</dt> <dd>2016-02-08 19:30:47 -0800 (Mon, 08 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Move ResultsTable functionality not needed for release tests out.
Move reporting of score and mean to selection of the time-based graph.

* Animometer/developer.html: Rename graph-options to time-graph-options.
* Animometer/resources/debug-runner/animometer.js:
(DeveloperResultsTable): Moved from runner/animometer.js. Switch from mean
values to &quot;average&quot; objects which can hold stdev. Move graph button and
calculation of noisy measurements here. Sophisticated header processing
is not needed in release suite.
(populateTable): Use DeveloperResultsTable.
* Animometer/resources/debug-runner/graph.js: Pull time graph creation to
its own function, and add a new onGraphTypeChanged handler in preparation
of a complexity graph to be added later.
* Animometer/resources/runner/animometer.js:
(ResultsTable): Simplify to just handle test names and scores.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsAnimometerdeveloperhtml">trunk/PerformanceTests/Animometer/developer.html</a></li>
<li><a href="#trunkPerformanceTestsAnimometerresourcesdebugrunneranimometerjs">trunk/PerformanceTests/Animometer/resources/debug-runner/animometer.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometerresourcesdebugrunnergraphjs">trunk/PerformanceTests/Animometer/resources/debug-runner/graph.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometerresourcesrunneranimometerjs">trunk/PerformanceTests/Animometer/resources/runner/animometer.js</a></li>
<li><a href="#trunkPerformanceTestsChangeLog">trunk/PerformanceTests/ChangeLog</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkPerformanceTestsAnimometerdeveloperhtml"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/developer.html (196296 => 196297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/developer.html        2016-02-09 03:30:44 UTC (rev 196296)
+++ trunk/PerformanceTests/Animometer/developer.html        2016-02-09 03:30:47 UTC (rev 196297)
</span><span class="lines">@@ -8,14 +8,14 @@
</span><span class="cx">     &lt;script src=&quot;resources/strings.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;resources/extensions.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> 
</span><del>-    &lt;script src=&quot;resources/runner/tests.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
</del><ins>+    &lt;script src=&quot;resources/runner/tests.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;resources/debug-runner/tests.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
</span><del>-    &lt;script src=&quot;resources/runner/animometer.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
</del><ins>+    &lt;script src=&quot;resources/runner/animometer.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;resources/debug-runner/animometer.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;resources/runner/benchmark-runner.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;resources/debug-runner/d3.min.js&quot;&gt;&lt;/script&gt;
</span><del>-    &lt;script src=&quot;resources/debug-runner/graph.js&quot;&gt;&lt;/script&gt;
</del><ins>+    &lt;script src=&quot;resources/debug-runner/graph.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> &lt;/head&gt;
</span><span class="cx"> &lt;body&gt;
</span><span class="cx">     &lt;main&gt;
</span><span class="lines">@@ -103,7 +103,7 @@
</span><span class="cx">                 &lt;h1&gt;Graph:&lt;/h1&gt;
</span><span class="cx">             &lt;/header&gt;
</span><span class="cx">             &lt;nav&gt;
</span><del>-                &lt;form name=&quot;graph-options&quot;&gt;
</del><ins>+                &lt;form name=&quot;time-graph-options&quot;&gt;
</ins><span class="cx">                     &lt;ul&gt;
</span><span class="cx">                         &lt;li&gt;&lt;label&gt;&lt;input type=&quot;checkbox&quot; name=&quot;markers&quot; checked&gt; Markers&lt;/label&gt;
</span><span class="cx">                             &lt;span&gt;time: &lt;span class=&quot;time&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometerresourcesdebugrunneranimometerjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/resources/debug-runner/animometer.js (196296 => 196297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/resources/debug-runner/animometer.js        2016-02-09 03:30:44 UTC (rev 196296)
+++ trunk/PerformanceTests/Animometer/resources/debug-runner/animometer.js        2016-02-09 03:30:47 UTC (rev 196297)
</span><span class="lines">@@ -19,6 +19,111 @@
</span><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+DeveloperResultsTable = Utilities.createSubclass(ResultsTable,
+    function(element, headers)
+    {
+        ResultsTable.call(this, element, headers);
+    }, {
+
+    _addGraphButton: function(td, testName, testResults)
+    {
+        var data = testResults[Strings.json.samples];
+        if (!data)
+            return;
+
+        var button = Utilities.createElement(&quot;button&quot;, { class: &quot;small-button&quot; }, td);
+
+        button.addEventListener(&quot;click&quot;, function() {
+            var graphData = {
+                axes: [Strings.text.complexity, Strings.text.frameRate],
+                samples: data,
+                complexityAverageSamples: testResults[Strings.json.complexityAverageSamples],
+                averages: {},
+                marks: testResults[Strings.json.marks]
+            };
+            [Strings.json.experiments.complexity, Strings.json.experiments.frameRate].forEach(function(experiment) {
+                if (experiment in testResults)
+                    graphData.averages[experiment] = testResults[experiment];
+            });
+
+            [
+                Strings.json.score,
+                Strings.json.regressions.timeRegressions,
+                Strings.json.regressions.complexityRegression,
+                Strings.json.regressions.complexityAverageRegression,
+                Strings.json.targetFrameLength
+            ].forEach(function(key) {
+                if (testResults[key])
+                    graphData[key] = testResults[key];
+            });
+
+            benchmarkController.showTestGraph(testName, graphData);
+        });
+
+        button.textContent = Strings.text.graph + &quot;...&quot;;
+    },
+
+    _isNoisyMeasurement: function(jsonExperiment, data, measurement, options)
+    {
+        const percentThreshold = 10;
+        const averageThreshold = 2;
+
+        if (measurement == Strings.json.measurements.percent)
+            return data[Strings.json.measurements.percent] &gt;= percentThreshold;
+
+        if (jsonExperiment == Strings.json.experiments.frameRate &amp;&amp; measurement == Strings.json.measurements.average)
+            return Math.abs(data[Strings.json.measurements.average] - options[&quot;frame-rate&quot;]) &gt;= averageThreshold;
+
+        return false;
+    },
+
+    _addTest: function(testName, testResults, options)
+    {
+        var row = Utilities.createElement(&quot;tr&quot;, {}, this.element);
+
+        var isNoisy = false;
+        [Strings.json.experiments.complexity, Strings.json.experiments.frameRate].forEach(function (experiment) {
+            var data = testResults[experiment];
+            for (var measurement in data) {
+                if (this._isNoisyMeasurement(experiment, data, measurement, options))
+                    isNoisy = true;
+            }
+        }, this);
+
+        this._flattenedHeaders.forEach(function (header) {
+            var className = &quot;&quot;;
+            if (header.className) {
+                if (typeof header.className == &quot;function&quot;)
+                    className = header.className(testResults, options);
+                else
+                    className = header.className;
+            }
+
+            if (header.title == Strings.text.testName) {
+                if (isNoisy)
+                    className += &quot; noisy-results&quot;;
+                var td = Utilities.createElement(&quot;td&quot;, { class: className }, row);
+                td.textContent = testName;
+                return;
+            }
+
+            var td = Utilities.createElement(&quot;td&quot;, { class: className }, row);
+            if (header.title == Strings.text.graph) {
+                this._addGraphButton(td, testName, testResults);
+            } else if (!(&quot;text&quot; in header)) {
+                td.textContent = testResults[header.title];
+            } else if (typeof header.text == &quot;string&quot;) {
+                var data = testResults[header.text];
+                if (typeof data == &quot;number&quot;)
+                    data = data.toFixed(2);
+                td.textContent = data;
+            } else {
+                td.textContent = header.text(testResults, testName);
+            }
+        }, this);
+    }
+});
+
</ins><span class="cx"> Utilities.extendObject(window.benchmarkRunnerClient, {
</span><span class="cx">     testsCount: null,
</span><span class="cx">     progressBar: null,
</span><span class="lines">@@ -45,6 +150,12 @@
</span><span class="cx">     setSectionHeader: function(sectionIdentifier, title)
</span><span class="cx">     {
</span><span class="cx">         document.querySelector(&quot;#&quot; + sectionIdentifier + &quot; h1&quot;).textContent = title;
</span><ins>+    },
+
+    populateTable: function(tableIdentifier, headers, data)
+    {
+        var table = new DeveloperResultsTable(document.getElementById(tableIdentifier), headers);
+        table.showIterations(data, benchmarkRunnerClient.options);
</ins><span class="cx">     }
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -343,7 +454,7 @@
</span><span class="cx">     initialize: function()
</span><span class="cx">     {
</span><span class="cx">         document.forms[&quot;benchmark-options&quot;].addEventListener(&quot;change&quot;, benchmarkController.onBenchmarkOptionsChanged, true);
</span><del>-        document.forms[&quot;graph-options&quot;].addEventListener(&quot;change&quot;, benchmarkController.onGraphOptionsChanged, true);
</del><ins>+        document.forms[&quot;time-graph-options&quot;].addEventListener(&quot;change&quot;, benchmarkController.onTimeGraphOptionsChanged, true);
</ins><span class="cx">         optionsManager.updateUIFromLocalStorage();
</span><span class="cx">         suitesManager.createElements();
</span><span class="cx">         suitesManager.updateUIFromLocalStorage();
</span><span class="lines">@@ -397,10 +508,9 @@
</span><span class="cx">         document.querySelector(&quot;#results-json div&quot;).classList.remove(&quot;hidden&quot;);
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    showTestGraph: function(testName, score, mean, graphData)
</del><ins>+    showTestGraph: function(testName, graphData)
</ins><span class="cx">     {
</span><span class="cx">         sectionsManager.setSectionHeader(&quot;test-graph&quot;, testName);
</span><del>-        sectionsManager.setSectionScore(&quot;test-graph&quot;, score, mean);
</del><span class="cx">         sectionsManager.showSection(&quot;test-graph&quot;, true);
</span><span class="cx">         this.updateGraphData(graphData);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometerresourcesdebugrunnergraphjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/resources/debug-runner/graph.js (196296 => 196297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/resources/debug-runner/graph.js        2016-02-09 03:30:44 UTC (rev 196296)
+++ trunk/PerformanceTests/Animometer/resources/debug-runner/graph.js        2016-02-09 03:30:47 UTC (rev 196297)
</span><span class="lines">@@ -5,12 +5,22 @@
</span><span class="cx">     {
</span><span class="cx">         var element = document.getElementById(&quot;test-graph-data&quot;);
</span><span class="cx">         element.innerHTML = &quot;&quot;;
</span><ins>+        element.graphData = graphData;
</ins><span class="cx">         document.querySelector(&quot;hr&quot;).style.width = this.layoutCounter++ + &quot;px&quot;;
</span><span class="cx"> 
</span><span class="cx">         var margins = new Insets(30, 30, 30, 40);
</span><span class="cx">         var size = Point.elementClientSize(element).subtract(margins.size);
</span><span class="cx"> 
</span><ins>+        this.createTimeGraph(graphData, margins, size);
+        this.onTimeGraphOptionsChanged();
+
+        this.onGraphTypeChanged();
+    },
+
+    createTimeGraph: function(graphData, margins, size)
+    {
</ins><span class="cx">         var svg = d3.select(&quot;#test-graph-data&quot;).append(&quot;svg&quot;)
</span><ins>+            .attr(&quot;id&quot;, &quot;time-graph&quot;)
</ins><span class="cx">             .attr(&quot;width&quot;, size.width + margins.left + margins.right)
</span><span class="cx">             .attr(&quot;height&quot;, size.height + margins.top + margins.bottom)
</span><span class="cx">             .append(&quot;g&quot;)
</span><span class="lines">@@ -22,10 +32,14 @@
</span><span class="cx">         // Axis scales
</span><span class="cx">         var x = d3.scale.linear()
</span><span class="cx">                 .range([0, size.width])
</span><del>-                .domain([0, d3.max(graphData.samples, function(s) { return s.time; })]);
</del><ins>+                .domain([
+                    Math.min(d3.min(graphData.samples, function(s) { return s.time; }), 0),
+                    d3.max(graphData.samples, function(s) { return s.time; })]);
+        var complexityMax = d3.max(graphData.samples, function(s) { return s.complexity; });
+
</ins><span class="cx">         var yLeft = d3.scale.linear()
</span><span class="cx">                 .range([size.height, 0])
</span><del>-                .domain([0, d3.max(graphData.samples, function(s) { return s.complexity; })]);
</del><ins>+                .domain([0, complexityMax]);
</ins><span class="cx">         var yRight = d3.scale.linear()
</span><span class="cx">                 .range([size.height, 0])
</span><span class="cx">                 .domain([1000/20, 1000/60]);
</span><span class="lines">@@ -98,32 +112,33 @@
</span><span class="cx">                 .attr(&quot;class&quot;, &quot;marker&quot;)
</span><span class="cx">                 .attr(&quot;transform&quot;, &quot;translate(&quot; + xLocation + &quot;, 0)&quot;);
</span><span class="cx">             markerGroup.append(&quot;text&quot;)
</span><del>-                    .attr(&quot;transform&quot;, &quot;translate(10, &quot; + (yMin - 10) + &quot;) rotate(-90)&quot;)
-                    .style(&quot;text-anchor&quot;, &quot;start&quot;)
-                    .text(markName)
</del><ins>+                .attr(&quot;transform&quot;, &quot;translate(10, &quot; + (yMin - 10) + &quot;) rotate(-90)&quot;)
+                .style(&quot;text-anchor&quot;, &quot;start&quot;)
+                .text(markName)
</ins><span class="cx">             markerGroup.append(&quot;line&quot;)
</span><del>-                    .attr(&quot;x1&quot;, 0)
-                    .attr(&quot;x2&quot;, 0)
-                    .attr(&quot;y1&quot;, yMin)
-                    .attr(&quot;y2&quot;, yMax);
</del><ins>+                .attr(&quot;x1&quot;, 0)
+                .attr(&quot;x2&quot;, 0)
+                .attr(&quot;y1&quot;, yMin)
+                .attr(&quot;y2&quot;, yMax);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        // left-mean
-        svg.append(&quot;line&quot;)
-            .attr(&quot;x1&quot;, x(0))
-            .attr(&quot;x2&quot;, size.width)
-            .attr(&quot;y1&quot;, yLeft(graphData.mean[0]))
-            .attr(&quot;y2&quot;, yLeft(graphData.mean[0]))
-            .attr(&quot;class&quot;, &quot;left-mean mean&quot;);
</del><ins>+        if (Strings.json.experiments.complexity in graphData.averages) {
+            var complexity = graphData.averages[Strings.json.experiments.complexity];
+            var regression = svg.append(&quot;g&quot;)
+                .attr(&quot;class&quot;, &quot;complexity mean&quot;);
+            this._addRegressionLine(regression, x, yLeft, [[graphData.samples[0].time, complexity.average], [graphData.samples[graphData.samples.length - 1].time, complexity.average]], complexity.stdev);
+        }
+        if (Strings.json.experiments.frameRate in graphData.averages) {
+            var frameRate = graphData.averages[Strings.json.experiments.frameRate];
+            var average = yRight(1000/frameRate.average);
+            svg.append(&quot;line&quot;)
+                .attr(&quot;x1&quot;, x(0))
+                .attr(&quot;x2&quot;, size.width)
+                .attr(&quot;y1&quot;, average)
+                .attr(&quot;y2&quot;, average)
+                .attr(&quot;class&quot;, &quot;fps mean&quot;);
+        }
</ins><span class="cx"> 
</span><del>-        // right-mean
-        svg.append(&quot;line&quot;)
-            .attr(&quot;x1&quot;, x(0))
-            .attr(&quot;x2&quot;, size.width)
-            .attr(&quot;y1&quot;, yRight(graphData.mean[1]))
-            .attr(&quot;y2&quot;, yRight(graphData.mean[1]))
-            .attr(&quot;class&quot;, &quot;right-mean mean&quot;);
-
</del><span class="cx">         // right-target
</span><span class="cx">         if (targetFrameLength) {
</span><span class="cx">             svg.append(&quot;line&quot;)
</span><span class="lines">@@ -135,7 +150,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Cursor
</span><del>-        var cursorGroup = svg.append(&quot;g&quot;).attr(&quot;id&quot;, &quot;cursor&quot;);
</del><ins>+        var cursorGroup = svg.append(&quot;g&quot;).attr(&quot;class&quot;, &quot;cursor&quot;);
</ins><span class="cx">         cursorGroup.append(&quot;line&quot;)
</span><span class="cx">             .attr(&quot;x1&quot;, 0)
</span><span class="cx">             .attr(&quot;x2&quot;, 0)
</span><span class="lines">@@ -179,19 +194,19 @@
</span><span class="cx">             .attr(&quot;fill&quot;, &quot;transparent&quot;)
</span><span class="cx">             .attr(&quot;x&quot;, 0)
</span><span class="cx">             .attr(&quot;y&quot;, 0)
</span><del>-            .attr(&quot;width&quot;, size.x)
-            .attr(&quot;height&quot;, size.y);
</del><ins>+            .attr(&quot;width&quot;, size.width)
+            .attr(&quot;height&quot;, size.height);
</ins><span class="cx"> 
</span><span class="cx">         var timeBisect = d3.bisector(function(d) { return d.time; }).right;
</span><span class="cx">         var statsToHighlight = [&quot;complexity&quot;, &quot;rawFPS&quot;, &quot;filteredFPS&quot;];
</span><span class="cx">         area.on(&quot;mouseover&quot;, function() {
</span><del>-            document.getElementById(&quot;cursor&quot;).classList.remove(&quot;hidden&quot;);
</del><ins>+            document.querySelector(&quot;#time-graph .cursor&quot;).classList.remove(&quot;hidden&quot;);
</ins><span class="cx">             document.querySelector(&quot;#test-graph nav&quot;).classList.remove(&quot;hide-data&quot;);
</span><span class="cx">         }).on(&quot;mouseout&quot;, function() {
</span><del>-            document.getElementById(&quot;cursor&quot;).classList.add(&quot;hidden&quot;);
</del><ins>+            document.querySelector(&quot;#time-graph .cursor&quot;).classList.add(&quot;hidden&quot;);
</ins><span class="cx">             document.querySelector(&quot;#test-graph nav&quot;).classList.add(&quot;hide-data&quot;);
</span><span class="cx">         }).on(&quot;mousemove&quot;, function() {
</span><del>-            var form = document.forms[&quot;graph-options&quot;].elements;
</del><ins>+            var form = document.forms[&quot;time-graph-options&quot;].elements;
</ins><span class="cx"> 
</span><span class="cx">             var mx_domain = x.invert(d3.mouse(this)[0]);
</span><span class="cx">             var index = Math.min(timeBisect(allData, mx_domain), allData.length - 1);
</span><span class="lines">@@ -229,9 +244,9 @@
</span><span class="cx">                     cursorGroup.select(&quot;.&quot; + name)
</span><span class="cx">                         .attr(&quot;cx&quot;, cursor_x)
</span><span class="cx">                         .attr(&quot;cy&quot;, data_y);
</span><del>-                    document.querySelector(&quot;#cursor .&quot; + name).classList.remove(&quot;hidden&quot;);
</del><ins>+                    document.querySelector(&quot;#time-graph .cursor .&quot; + name).classList.remove(&quot;hidden&quot;);
</ins><span class="cx">                 } else
</span><del>-                    document.querySelector(&quot;#cursor .&quot; + name).classList.add(&quot;hidden&quot;);
</del><ins>+                    document.querySelector(&quot;#time-graph .cursor .&quot; + name).classList.add(&quot;hidden&quot;);
</ins><span class="cx">             });
</span><span class="cx"> 
</span><span class="cx">             if (form[&quot;rawFPS&quot;].checked)
</span><span class="lines">@@ -243,27 +258,58 @@
</span><span class="cx">                 .attr(&quot;y2&quot;, Math.max.apply(null, ys));
</span><span class="cx"> 
</span><span class="cx">         });
</span><del>-        this.onGraphOptionsChanged();
</del><span class="cx">     },
</span><span class="cx"> 
</span><del>-    onGraphOptionsChanged: function() {
-        var form = document.forms[&quot;graph-options&quot;].elements;
</del><ins>+    _showOrHideNodes: function(isShown, selector) {
+        var nodeList = document.querySelectorAll(selector);
+        if (isShown) {
+            for (var i = 0; i &lt; nodeList.length; ++i)
+                nodeList[i].classList.remove(&quot;hidden&quot;);
+        } else {
+            for (var i = 0; i &lt; nodeList.length; ++i)
+                nodeList[i].classList.add(&quot;hidden&quot;);
+        }
+    },
</ins><span class="cx"> 
</span><del>-        function showOrHideNodes(isShown, selector) {
-            var nodeList = document.querySelectorAll(selector);
-            if (isShown) {
-                for (var i = 0; i &lt; nodeList.length; ++i)
-                    nodeList[i].classList.remove(&quot;hidden&quot;);
-            } else {
-                for (var i = 0; i &lt; nodeList.length; ++i)
-                    nodeList[i].classList.add(&quot;hidden&quot;);
</del><ins>+    onTimeGraphOptionsChanged: function() {
+        var form = document.forms[&quot;time-graph-options&quot;].elements;
+        benchmarkController._showOrHideNodes(form[&quot;markers&quot;].checked, &quot;.marker&quot;);
+        benchmarkController._showOrHideNodes(form[&quot;averages&quot;].checked, &quot;#test-graph-data .mean&quot;);
+        benchmarkController._showOrHideNodes(form[&quot;complexity&quot;].checked, &quot;#complexity&quot;);
+        benchmarkController._showOrHideNodes(form[&quot;rawFPS&quot;].checked, &quot;#rawFPS&quot;);
+        benchmarkController._showOrHideNodes(form[&quot;filteredFPS&quot;].checked, &quot;#filteredFPS&quot;);
+        benchmarkController._showOrHideNodes(form[&quot;regressions&quot;].checked, &quot;#regressions&quot;);
+    },
+
+    onGraphTypeChanged: function() {
+        var form = document.forms[&quot;graph-type&quot;].elements;
+        var graphData = document.getElementById(&quot;test-graph-data&quot;).graphData;
+        var isTimeSelected = true; 
+
+        benchmarkController._showOrHideNodes(isTimeSelected, &quot;#time-graph&quot;);
+        benchmarkController._showOrHideNodes(isTimeSelected, &quot;form[name=time-graph-options]&quot;);
+
+        var score, mean;
+        if (isTimeSelected) {
+            score = graphData.score.toFixed(2);
+
+            var regression = graphData.averages.complexity;
+            mean = [
+                &quot;mean: &quot;,
+                regression.average.toFixed(2),
+                &quot; ± &quot;,
+                regression.stdev.toFixed(2),
+                &quot; (&quot;,
+                regression.percent.toFixed(2),
+                &quot;%)&quot;];
+            if (regression.concern) {
+                mean = mean.concat([
+                    &quot;, worst 5%: &quot;,
+                    regression.concern.toFixed(2)]);
</ins><span class="cx">             }
</span><ins>+            mean = mean.join(&quot;&quot;);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        showOrHideNodes(form[&quot;markers&quot;].checked, &quot;.marker&quot;);
-        showOrHideNodes(form[&quot;averages&quot;].checked, &quot;.mean&quot;);
-        showOrHideNodes(form[&quot;complexity&quot;].checked, &quot;#complexity&quot;);
-        showOrHideNodes(form[&quot;rawFPS&quot;].checked, &quot;#rawFPS&quot;);
-        showOrHideNodes(form[&quot;filteredFPS&quot;].checked, &quot;#filteredFPS&quot;);
</del><ins>+        sectionsManager.setSectionScore(&quot;test-graph&quot;, score, mean);
</ins><span class="cx">     }
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometerresourcesrunneranimometerjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/resources/runner/animometer.js (196296 => 196297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/resources/runner/animometer.js        2016-02-09 03:30:44 UTC (rev 196296)
+++ trunk/PerformanceTests/Animometer/resources/runner/animometer.js        2016-02-09 03:30:47 UTC (rev 196297)
</span><span class="lines">@@ -98,58 +98,6 @@
</span><span class="cx">         });
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    _addGraphButton: function(td, testName, testResults)
-    {
-        var data = testResults[Strings.json.samples];
-        if (!data)
-            return;
-
-        var button = Utilities.createElement(&quot;button&quot;, { class: &quot;small-button&quot; }, td);
-
-        button.addEventListener(&quot;click&quot;, function() {
-            var score = testResults[Strings.json.score].toFixed(2);
-            var complexity = testResults[Strings.json.experiments.complexity];
-            var mean = [
-                &quot;mean: &quot;,
-                complexity[Strings.json.measurements.average].toFixed(2),
-                &quot; ± &quot;,
-                complexity[Strings.json.measurements.stdev].toFixed(2),
-                &quot; (&quot;,
-                complexity[Strings.json.measurements.percent].toFixed(2),
-                &quot;%), worst 5%: &quot;,
-                complexity[Strings.json.measurements.concern].toFixed(2)].join(&quot;&quot;);
-
-            var graphData = {
-                axes: [Strings.text.experiments.complexity, Strings.text.experiments.frameRate],
-                mean: [
-                    testResults[Strings.json.experiments.complexity][Strings.json.measurements.average],
-                    1000 / testResults[Strings.json.experiments.frameRate][Strings.json.measurements.average]
-                ],
-                samples: data,
-                marks: testResults[Strings.json.marks]
-            }
-            if (testResults[Strings.json.targetFrameLength])
-                graphData.targetFrameLength = testResults[Strings.json.targetFrameLength];
-            benchmarkController.showTestGraph(testName, score, mean, graphData);
-        });
-
-        button.textContent = Strings.text.results.graph + &quot;...&quot;;
-    },
-
-    _isNoisyMeasurement: function(jsonExperiment, data, measurement, options)
-    {
-        const percentThreshold = 10;
-        const averageThreshold = 2;
-
-        if (measurement == Strings.json.measurements.percent)
-            return data[Strings.json.measurements.percent] &gt;= percentThreshold;
-
-        if (jsonExperiment == Strings.json.experiments.frameRate &amp;&amp; measurement == Strings.json.measurements.average)
-            return Math.abs(data[Strings.json.measurements.average] - options[&quot;frame-rate&quot;]) &gt;= averageThreshold;
-
-        return false;
-    },
-
</del><span class="cx">     _addEmptyRow: function()
</span><span class="cx">     {
</span><span class="cx">         var row = Utilities.createElement(&quot;tr&quot;, {}, this.element);
</span><span class="lines">@@ -162,45 +110,15 @@
</span><span class="cx">     {
</span><span class="cx">         var row = Utilities.createElement(&quot;tr&quot;, {}, this.element);
</span><span class="cx"> 
</span><del>-        var isNoisy = false;
-        [Strings.json.experiments.complexity, Strings.json.experiments.frameRate].forEach(function (experiment) {
-            var data = testResults[experiment];
-            for (var measurement in data) {
-                if (this._isNoisyMeasurement(experiment, data, measurement, options))
-                    isNoisy = true;
-            }
-        }, this);
-
</del><span class="cx">         this._flattenedHeaders.forEach(function (header) {
</span><del>-            var className = &quot;&quot;;
-            if (header.className) {
-                if (typeof header.className == &quot;function&quot;)
-                    className = header.className(testResults, options);
-                else
-                    className = header.className;
-            }
-
</del><ins>+            var td = Utilities.createElement(&quot;td&quot;, {}, row);
</ins><span class="cx">             if (header.title == Strings.text.testName) {
</span><del>-                var titleClassName = className;
-                if (isNoisy)
-                    titleClassName += &quot; noisy-results&quot;;
-                var td = Utilities.createElement(&quot;td&quot;, { class: titleClassName }, row);
</del><span class="cx">                 td.textContent = testName;
</span><del>-                return;
-            }
-
-            var td = Utilities.createElement(&quot;td&quot;, { class: className }, row);
-            if (header.title == Strings.text.results.graph) {
-                this._addGraphButton(td, testName, testResults);
-            } else if (!(&quot;text&quot; in header)) {
-                td.textContent = testResults[header.title];
-            } else if (typeof header.text == &quot;string&quot;) {
</del><ins>+            } else if (header.text) {
</ins><span class="cx">                 var data = testResults[header.text];
</span><span class="cx">                 if (typeof data == &quot;number&quot;)
</span><span class="cx">                     data = data.toFixed(2);
</span><span class="cx">                 td.textContent = data;
</span><del>-            } else {
-                td.textContent = header.text(testResults, testName);
</del><span class="cx">             }
</span><span class="cx">         }, this);
</span><span class="cx">     },
</span></span></pre></div>
<a id="trunkPerformanceTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/ChangeLog (196296 => 196297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/ChangeLog        2016-02-09 03:30:44 UTC (rev 196296)
+++ trunk/PerformanceTests/ChangeLog        2016-02-09 03:30:47 UTC (rev 196297)
</span><span class="lines">@@ -1,5 +1,23 @@
</span><span class="cx"> 2016-02-07  Jon Lee  &lt;jonlee@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Move ResultsTable functionality not needed for release tests out.
+        Move reporting of score and mean to selection of the time-based graph.
+
+        * Animometer/developer.html: Rename graph-options to time-graph-options.
+        * Animometer/resources/debug-runner/animometer.js:
+        (DeveloperResultsTable): Moved from runner/animometer.js. Switch from mean
+        values to &quot;average&quot; objects which can hold stdev. Move graph button and
+        calculation of noisy measurements here. Sophisticated header processing
+        is not needed in release suite.
+        (populateTable): Use DeveloperResultsTable.
+        * Animometer/resources/debug-runner/graph.js: Pull time graph creation to
+        its own function, and add a new onGraphTypeChanged handler in preparation
+        of a complexity graph to be added later.
+        * Animometer/resources/runner/animometer.js:
+        (ResultsTable): Simplify to just handle test names and scores.
+
+2016-02-07  Jon Lee  &lt;jonlee@apple.com&gt;
+
</ins><span class="cx">         Tests: reuse objects already made.
</span><span class="cx"> 
</span><span class="cx">         Avoid thrash of object creation and removal by maintaining an index that
</span></span></pre>
</div>
</div>

</body>
</html>