summaryrefslogtreecommitdiffstats
path: root/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/graph.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/graph.js
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/graph.js615
1 files changed, 615 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/graph.js b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/graph.js
new file mode 100644
index 0000000000..4803936219
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/graph.js
@@ -0,0 +1,615 @@
+Utilities.extendObject(window.benchmarkController, {
+ updateGraphData: function(testResult, testData, options)
+ {
+ var element = document.getElementById("test-graph-data");
+ element.innerHTML = "";
+ element._testResult = testResult;
+ element._options = options;
+
+ var margins = new Insets(30, 30, 30, 40);
+ var size = Point.elementClientSize(element);
+ size.y = window.innerHeight - element.offsetTop;
+ size = size.subtract(margins.size);
+
+ // Convert from compact JSON output to propertied data
+ var samplesWithProperties = {};
+ [Strings.json.controller, Strings.json.complexity, Strings.json.complexityAverage].forEach(function(seriesName) {
+ var series = testData[Strings.json.samples][seriesName];
+ samplesWithProperties[seriesName] = series.toArray();
+ })
+
+ this.createTimeGraph(testResult, samplesWithProperties[Strings.json.controller], testData[Strings.json.marks], testData[Strings.json.controller], options, margins, size);
+ this.onTimeGraphOptionsChanged();
+
+ this._showOrHideNodes(true, "form[name=graph-type]");
+ document.forms["graph-type"].elements["type"] = "complexity";
+ this.createComplexityGraph(testResult, testData[Strings.json.controller], samplesWithProperties, options, margins, size);
+ this.onComplexityGraphOptionsChanged();
+
+ this.onGraphTypeChanged();
+ },
+
+ _addRegressionLine: function(parent, xScale, yScale, points, range, isAlongYAxis)
+ {
+ var polygon = [];
+ var line = []
+ var xRange = isAlongYAxis ? range : 0;
+ var yRange = isAlongYAxis ? 0 : range;
+ for (var i = 0; i < points.length; ++i) {
+ var point = points[i];
+ var x;
+ if (xRange instanceof Array)
+ x = xRange[0];
+ else
+ x = point[0] + xRange;
+ polygon.push(xScale(x), yScale(point[1] + yRange));
+ line.push(xScale(point[0]), yScale(point[1]));
+ }
+ for (var i = points.length - 1; i >= 0; --i) {
+ var point = points[i];
+ var x;
+ if (xRange instanceof Array)
+ x = xRange[1];
+ else
+ x = point[0] - xRange;
+ polygon.push(xScale(x), yScale(point[1] - yRange));
+ }
+ parent.append("polygon")
+ .attr("points", polygon.join(","));
+ parent.append("line")
+ .attr("x1", line[0])
+ .attr("y1", line[1])
+ .attr("x2", line[2])
+ .attr("y2", line[3]);
+ },
+
+ _addRegression: function(data, svg, xScale, yScale)
+ {
+ svg.append("circle")
+ .attr("cx", xScale(data.segment1[1][0]))
+ .attr("cy", yScale(data.segment1[1][1]))
+ .attr("r", 5);
+ this._addRegressionLine(svg, xScale, yScale, data.segment1, data.stdev);
+ this._addRegressionLine(svg, xScale, yScale, data.segment2, data.stdev);
+ },
+
+ createComplexityGraph: function(result, timeRegressions, data, options, margins, size)
+ {
+ var svg = d3.select("#test-graph-data").append("svg")
+ .attr("id", "complexity-graph")
+ .attr("class", "hidden")
+ .attr("width", size.width + margins.left + margins.right)
+ .attr("height", size.height + margins.top + margins.bottom)
+ .append("g")
+ .attr("transform", "translate(" + margins.left + "," + margins.top + ")");
+
+ var timeSamples = data[Strings.json.controller];
+
+ var xMin = 100000, xMax = 0;
+ if (timeRegressions) {
+ timeRegressions.forEach(function(regression) {
+ for (var i = regression.startIndex; i <= regression.endIndex; ++i) {
+ xMin = Math.min(xMin, timeSamples[i].complexity);
+ xMax = Math.max(xMax, timeSamples[i].complexity);
+ }
+ });
+ } else {
+ xMin = d3.min(timeSamples, function(s) { return s.complexity; });
+ xMax = d3.max(timeSamples, function(s) { return s.complexity; });
+ }
+
+ var xScale = d3.scale.linear()
+ .range([0, size.width])
+ .domain([xMin, xMax]);
+ var yScale = d3.scale.linear()
+ .range([size.height, 0])
+ .domain([1000/20, 1000/60]);
+
+ var xAxis = d3.svg.axis()
+ .scale(xScale)
+ .orient("bottom");
+ var yAxis = d3.svg.axis()
+ .scale(yScale)
+ .tickValues([1000/20, 1000/25, 1000/30, 1000/35, 1000/40, 1000/45, 1000/50, 1000/55, 1000/60])
+ .tickFormat(function(d) { return (1000 / d).toFixed(0); })
+ .orient("left");
+
+ // x-axis
+ svg.append("g")
+ .attr("class", "x axis")
+ .attr("transform", "translate(0," + size.height + ")")
+ .call(xAxis);
+
+ // y-axis
+ svg.append("g")
+ .attr("class", "y axis")
+ .call(yAxis);
+
+ // time result
+ var mean = svg.append("g")
+ .attr("class", "mean complexity");
+ var timeResult = result[Strings.json.controller];
+ var yMin = yScale.domain()[0], yMax = yScale.domain()[1];
+ this._addRegressionLine(mean, xScale, yScale, [[timeResult.average, yMin], [timeResult.average, yMax]], timeResult.stdev, true);
+
+ // regression
+ this._addRegression(result[Strings.json.complexity], svg.append("g").attr("class", "regression raw"), xScale, yScale);
+ this._addRegression(result[Strings.json.complexityAverage], svg.append("g").attr("class", "regression average"), xScale, yScale);
+
+ var bootstrapResult = result[Strings.json.complexity][Strings.json.bootstrap];
+ if (bootstrapResult) {
+ var histogram = d3.layout.histogram()
+ .bins(xScale.ticks(100))(bootstrapResult.data);
+ var yBootstrapScale = d3.scale.linear()
+ .range([size.height/2, 0])
+ .domain([0, d3.max(histogram, function(d) { return d.y; })]);
+ group = svg.append("g").attr("class", "bootstrap");
+ var bar = group.selectAll(".bar")
+ .data(histogram)
+ .enter().append("g")
+ .attr("class", "bar")
+ .attr("transform", function(d) { return "translate(" + xScale(d.x) + "," + yBootstrapScale(d.y) + ")"; });
+ bar.append("rect")
+ .attr("x", 1)
+ .attr("y", size.height/2)
+ .attr("width", xScale(histogram[1].x) - xScale(histogram[0].x) - 1)
+ .attr("height", function(d) { return size.height/2 - yBootstrapScale(d.y); });
+ group = group.append("g").attr("class", "median");
+ this._addRegressionLine(group, xScale, yScale, [[bootstrapResult.median, yMin], [bootstrapResult.median, yMax]], [bootstrapResult.confidenceLow, bootstrapResult.confidenceHigh], true);
+ group.append("circle")
+ .attr("cx", xScale(bootstrapResult.median))
+ .attr("cy", yScale(1000/60))
+ .attr("r", 5);
+ }
+
+ // series
+ group = svg.append("g")
+ .attr("class", "series raw")
+ .selectAll("line")
+ .data(data[Strings.json.complexity])
+ .enter();
+ group.append("line")
+ .attr("x1", function(d) { return xScale(d.complexity) - 3; })
+ .attr("x2", function(d) { return xScale(d.complexity) + 3; })
+ .attr("y1", function(d) { return yScale(d.frameLength) - 3; })
+ .attr("y2", function(d) { return yScale(d.frameLength) + 3; });
+ group.append("line")
+ .attr("x1", function(d) { return xScale(d.complexity) - 3; })
+ .attr("x2", function(d) { return xScale(d.complexity) + 3; })
+ .attr("y1", function(d) { return yScale(d.frameLength) + 3; })
+ .attr("y2", function(d) { return yScale(d.frameLength) - 3; });
+
+ group = svg.append("g")
+ .attr("class", "series average")
+ .selectAll("circle")
+ .data(data[Strings.json.complexityAverage])
+ .enter();
+ group.append("circle")
+ .attr("cx", function(d) { return xScale(d.complexity); })
+ .attr("cy", function(d) { return yScale(d.frameLength); })
+ .attr("r", 3)
+ group.append("line")
+ .attr("x1", function(d) { return xScale(d.complexity); })
+ .attr("x2", function(d) { return xScale(d.complexity); })
+ .attr("y1", function(d) { return yScale(d.frameLength - d.stdev); })
+ .attr("y2", function(d) { return yScale(d.frameLength + d.stdev); });
+
+ // Cursor
+ var cursorGroup = svg.append("g").attr("class", "cursor hidden");
+ cursorGroup.append("line")
+ .attr("class", "x")
+ .attr("x1", 0)
+ .attr("x2", 0)
+ .attr("y1", yScale(yAxis.scale().domain()[0]) + 10)
+ .attr("y2", yScale(yAxis.scale().domain()[1]));
+ cursorGroup.append("line")
+ .attr("class", "y")
+ .attr("x1", xScale(xAxis.scale().domain()[0]) - 10)
+ .attr("x2", xScale(xAxis.scale().domain()[1]))
+ .attr("y1", 0)
+ .attr("y2", 0)
+ cursorGroup.append("text")
+ .attr("class", "label x")
+ .attr("x", 0)
+ .attr("y", yScale(yAxis.scale().domain()[0]) + 15)
+ .attr("baseline-shift", "-100%")
+ .attr("text-anchor", "middle");
+ cursorGroup.append("text")
+ .attr("class", "label y")
+ .attr("x", xScale(xAxis.scale().domain()[0]) - 15)
+ .attr("y", 0)
+ .attr("baseline-shift", "-30%")
+ .attr("text-anchor", "end");
+ // Area to handle mouse events
+ var area = svg.append("rect")
+ .attr("fill", "transparent")
+ .attr("x", 0)
+ .attr("y", 0)
+ .attr("width", size.width)
+ .attr("height", size.height);
+
+ area.on("mouseover", function() {
+ document.querySelector("#complexity-graph .cursor").classList.remove("hidden");
+ }).on("mouseout", function() {
+ document.querySelector("#complexity-graph .cursor").classList.add("hidden");
+ }).on("mousemove", function() {
+ var location = d3.mouse(this);
+ var location_domain = [xScale.invert(location[0]), yScale.invert(location[1])];
+ cursorGroup.select("line.x")
+ .attr("x1", location[0])
+ .attr("x2", location[0]);
+ cursorGroup.select("text.x")
+ .attr("x", location[0])
+ .text(location_domain[0].toFixed(1));
+ cursorGroup.select("line.y")
+ .attr("y1", location[1])
+ .attr("y2", location[1]);
+ cursorGroup.select("text.y")
+ .attr("y", location[1])
+ .text((1000 / location_domain[1]).toFixed(1));
+ });
+ },
+
+ createTimeGraph: function(result, samples, marks, regressions, options, margins, size)
+ {
+ var svg = d3.select("#test-graph-data").append("svg")
+ .attr("id", "time-graph")
+ .attr("width", size.width + margins.left + margins.right)
+ .attr("height", size.height + margins.top + margins.bottom)
+ .append("g")
+ .attr("transform", "translate(" + margins.left + "," + margins.top + ")");
+
+ // Axis scales
+ var x = d3.scale.linear()
+ .range([0, size.width])
+ .domain([
+ Math.min(d3.min(samples, function(s) { return s.time; }), 0),
+ d3.max(samples, function(s) { return s.time; })]);
+ var complexityMax = d3.max(samples, function(s) {
+ if (s.time > 0)
+ return s.complexity;
+ return 0;
+ });
+
+ var yLeft = d3.scale.linear()
+ .range([size.height, 0])
+ .domain([0, complexityMax]);
+ var yRight = d3.scale.linear()
+ .range([size.height, 0])
+ .domain([1000/20, 1000/60]);
+
+ // Axes
+ var xAxis = d3.svg.axis()
+ .scale(x)
+ .orient("bottom")
+ .tickFormat(function(d) { return (d/1000).toFixed(0); });
+ var yAxisLeft = d3.svg.axis()
+ .scale(yLeft)
+ .orient("left");
+ var yAxisRight = d3.svg.axis()
+ .scale(yRight)
+ .tickValues([1000/20, 1000/25, 1000/30, 1000/35, 1000/40, 1000/45, 1000/50, 1000/55, 1000/60])
+ .tickFormat(function(d) { return (1000/d).toFixed(0); })
+ .orient("right");
+
+ // x-axis
+ svg.append("g")
+ .attr("class", "x axis")
+ .attr("fill", "rgb(235, 235, 235)")
+ .attr("transform", "translate(0," + size.height + ")")
+ .call(xAxis)
+ .append("text")
+ .attr("class", "label")
+ .attr("x", size.width)
+ .attr("y", -6)
+ .attr("fill", "rgb(235, 235, 235)")
+ .style("text-anchor", "end")
+ .text("time");
+
+ // yLeft-axis
+ svg.append("g")
+ .attr("class", "yLeft axis")
+ .attr("fill", "#7ADD49")
+ .call(yAxisLeft)
+ .append("text")
+ .attr("class", "label")
+ .attr("transform", "rotate(-90)")
+ .attr("y", 6)
+ .attr("fill", "#7ADD49")
+ .attr("dy", ".71em")
+ .style("text-anchor", "end")
+ .text(Strings.text.complexity);
+
+ // yRight-axis
+ svg.append("g")
+ .attr("class", "yRight axis")
+ .attr("fill", "#FA4925")
+ .attr("transform", "translate(" + size.width + ", 0)")
+ .call(yAxisRight)
+ .append("text")
+ .attr("class", "label")
+ .attr("x", 9)
+ .attr("y", -20)
+ .attr("fill", "#FA4925")
+ .attr("dy", ".71em")
+ .style("text-anchor", "start")
+ .text(Strings.text.frameRate);
+
+ // marks
+ var yMin = yRight(yAxisRight.scale().domain()[0]);
+ var yMax = yRight(yAxisRight.scale().domain()[1]);
+ for (var markName in marks) {
+ var mark = marks[markName];
+ var xLocation = x(mark.time);
+
+ var markerGroup = svg.append("g")
+ .attr("class", "marker")
+ .attr("transform", "translate(" + xLocation + ", 0)");
+ markerGroup.append("text")
+ .attr("transform", "translate(10, " + (yMin - 10) + ") rotate(-90)")
+ .style("text-anchor", "start")
+ .text(markName)
+ markerGroup.append("line")
+ .attr("x1", 0)
+ .attr("x2", 0)
+ .attr("y1", yMin)
+ .attr("y2", yMax);
+ }
+
+ if (Strings.json.controller in result) {
+ var complexity = result[Strings.json.controller];
+ var regression = svg.append("g")
+ .attr("class", "complexity mean");
+ this._addRegressionLine(regression, x, yLeft, [[samples[0].time, complexity.average], [samples[samples.length - 1].time, complexity.average]], complexity.stdev);
+ }
+ if (Strings.json.frameLength in result) {
+ var frameLength = result[Strings.json.frameLength];
+ var regression = svg.append("g")
+ .attr("class", "fps mean");
+ this._addRegressionLine(regression, x, yRight, [[samples[0].time, 1000/frameLength.average], [samples[samples.length - 1].time, 1000/frameLength.average]], frameLength.stdev);
+ }
+
+ // right-target
+ if (options["controller"] == "adaptive") {
+ var targetFrameLength = 1000 / options["frame-rate"];
+ svg.append("line")
+ .attr("x1", x(0))
+ .attr("x2", size.width)
+ .attr("y1", yRight(targetFrameLength))
+ .attr("y2", yRight(targetFrameLength))
+ .attr("class", "target-fps marker");
+ }
+
+ // Cursor
+ var cursorGroup = svg.append("g").attr("class", "cursor");
+ cursorGroup.append("line")
+ .attr("x1", 0)
+ .attr("x2", 0)
+ .attr("y1", yMin)
+ .attr("y2", yMin);
+
+ // Data
+ var allData = samples;
+ var filteredData = samples.filter(function (sample) {
+ return "smoothedFrameLength" in sample;
+ });
+
+ function addData(name, data, yCoordinateCallback, pointRadius, omitLine) {
+ var svgGroup = svg.append("g").attr("id", name);
+ if (!omitLine) {
+ svgGroup.append("path")
+ .datum(data)
+ .attr("d", d3.svg.line()
+ .x(function(d) { return x(d.time); })
+ .y(yCoordinateCallback));
+ }
+ svgGroup.selectAll("circle")
+ .data(data)
+ .enter()
+ .append("circle")
+ .attr("cx", function(d) { return x(d.time); })
+ .attr("cy", yCoordinateCallback)
+ .attr("r", pointRadius);
+
+ cursorGroup.append("circle")
+ .attr("class", name)
+ .attr("r", pointRadius + 2);
+ }
+
+ addData("complexity", allData, function(d) { return yLeft(d.complexity); }, 2);
+ addData("rawFPS", allData, function(d) { return yRight(d.frameLength); }, 1);
+ addData("filteredFPS", filteredData, function(d) { return yRight(d.smoothedFrameLength); }, 2);
+
+ // regressions
+ var regressionGroup = svg.append("g")
+ .attr("id", "regressions");
+ if (regressions) {
+ var complexities = [];
+ regressions.forEach(function (regression) {
+ if (!isNaN(regression.segment1[0][1]) && !isNaN(regression.segment1[1][1])) {
+ regressionGroup.append("line")
+ .attr("x1", x(regression.segment1[0][0]))
+ .attr("x2", x(regression.segment1[1][0]))
+ .attr("y1", yRight(regression.segment1[0][1]))
+ .attr("y2", yRight(regression.segment1[1][1]));
+ }
+ if (!isNaN(regression.segment2[0][1]) && !isNaN(regression.segment2[1][1])) {
+ regressionGroup.append("line")
+ .attr("x1", x(regression.segment2[0][0]))
+ .attr("x2", x(regression.segment2[1][0]))
+ .attr("y1", yRight(regression.segment2[0][1]))
+ .attr("y2", yRight(regression.segment2[1][1]));
+ }
+ // inflection point
+ regressionGroup.append("circle")
+ .attr("cx", x(regression.segment1[1][0]))
+ .attr("cy", yLeft(regression.complexity))
+ .attr("r", 5);
+ complexities.push(regression.complexity);
+ });
+ if (complexities.length) {
+ var yLeftComplexities = d3.svg.axis()
+ .scale(yLeft)
+ .tickValues(complexities)
+ .tickSize(10)
+ .orient("left");
+ svg.append("g")
+ .attr("class", "complexity yLeft axis")
+ .call(yLeftComplexities);
+ }
+ }
+
+ // Area to handle mouse events
+ var area = svg.append("rect")
+ .attr("fill", "transparent")
+ .attr("x", 0)
+ .attr("y", 0)
+ .attr("width", size.width)
+ .attr("height", size.height);
+
+ var timeBisect = d3.bisector(function(d) { return d.time; }).right;
+ var statsToHighlight = ["complexity", "rawFPS", "filteredFPS"];
+ area.on("mouseover", function() {
+ document.querySelector("#time-graph .cursor").classList.remove("hidden");
+ document.querySelector("#test-graph nav").classList.remove("hide-data");
+ }).on("mouseout", function() {
+ document.querySelector("#time-graph .cursor").classList.add("hidden");
+ document.querySelector("#test-graph nav").classList.add("hide-data");
+ }).on("mousemove", function() {
+ var form = document.forms["time-graph-options"].elements;
+
+ var mx_domain = x.invert(d3.mouse(this)[0]);
+ var index = Math.min(timeBisect(allData, mx_domain), allData.length - 1);
+ var data = allData[index];
+ var cursor_x = x(data.time);
+ var cursor_y = yAxisRight.scale().domain()[1];
+ var ys = [yRight(yAxisRight.scale().domain()[0]), yRight(yAxisRight.scale().domain()[1])];
+
+ document.querySelector("#test-graph nav .time").textContent = (data.time / 1000).toFixed(4) + "s (" + index + ")";
+ statsToHighlight.forEach(function(name) {
+ var element = document.querySelector("#test-graph nav ." + name);
+ var content = "";
+ var data_y = null;
+ switch (name) {
+ case "complexity":
+ content = data.complexity;
+ data_y = yLeft(data.complexity);
+ break;
+ case "rawFPS":
+ content = (1000/data.frameLength).toFixed(2);
+ data_y = yRight(data.frameLength);
+ break;
+ case "filteredFPS":
+ if ("smoothedFrameLength" in data) {
+ content = (1000/data.smoothedFrameLength).toFixed(2);
+ data_y = yRight(data.smoothedFrameLength);
+ }
+ break;
+ }
+
+ element.textContent = content;
+
+ if (form[name].checked && data_y !== null) {
+ ys.push(data_y);
+ cursorGroup.select("." + name)
+ .attr("cx", cursor_x)
+ .attr("cy", data_y);
+ document.querySelector("#time-graph .cursor ." + name).classList.remove("hidden");
+ } else
+ document.querySelector("#time-graph .cursor ." + name).classList.add("hidden");
+ });
+
+ if (form["rawFPS"].checked)
+ cursor_y = Math.max(cursor_y, data.frameLength);
+ cursorGroup.select("line")
+ .attr("x1", cursor_x)
+ .attr("x2", cursor_x)
+ .attr("y1", Math.min.apply(null, ys))
+ .attr("y2", Math.max.apply(null, ys));
+
+ });
+ },
+
+ _showOrHideNodes: function(isShown, selector) {
+ var nodeList = document.querySelectorAll(selector);
+ if (isShown) {
+ for (var i = 0; i < nodeList.length; ++i)
+ nodeList[i].classList.remove("hidden");
+ } else {
+ for (var i = 0; i < nodeList.length; ++i)
+ nodeList[i].classList.add("hidden");
+ }
+ },
+
+ onComplexityGraphOptionsChanged: function() {
+ var form = document.forms["complexity-graph-options"].elements;
+ benchmarkController._showOrHideNodes(form["series-raw"].checked, "#complexity-graph .series.raw");
+ benchmarkController._showOrHideNodes(form["series-average"].checked, "#complexity-graph .series.average");
+ benchmarkController._showOrHideNodes(form["regression-time-score"].checked, "#complexity-graph .mean.complexity");
+ benchmarkController._showOrHideNodes(form["bootstrap-score"].checked, "#complexity-graph .bootstrap");
+ benchmarkController._showOrHideNodes(form["complexity-regression-aggregate-raw"].checked, "#complexity-graph .regression.raw");
+ benchmarkController._showOrHideNodes(form["complexity-regression-aggregate-average"].checked, "#complexity-graph .regression.average");
+ },
+
+ onTimeGraphOptionsChanged: function() {
+ var form = document.forms["time-graph-options"].elements;
+ benchmarkController._showOrHideNodes(form["markers"].checked, ".marker");
+ benchmarkController._showOrHideNodes(form["averages"].checked, "#test-graph-data .mean");
+ benchmarkController._showOrHideNodes(form["complexity"].checked, "#complexity");
+ benchmarkController._showOrHideNodes(form["rawFPS"].checked, "#rawFPS");
+ benchmarkController._showOrHideNodes(form["filteredFPS"].checked, "#filteredFPS");
+ benchmarkController._showOrHideNodes(form["regressions"].checked, "#regressions");
+ },
+
+ onGraphTypeChanged: function() {
+ var form = document.forms["graph-type"].elements;
+ var testResult = document.getElementById("test-graph-data")._testResult;
+ var isTimeSelected = form["graph-type"].value == "time";
+
+ benchmarkController._showOrHideNodes(isTimeSelected, "#time-graph");
+ benchmarkController._showOrHideNodes(isTimeSelected, "form[name=time-graph-options]");
+ benchmarkController._showOrHideNodes(!isTimeSelected, "#complexity-graph");
+ benchmarkController._showOrHideNodes(!isTimeSelected, "form[name=complexity-graph-options]");
+
+ var score = "", mean = "";
+ if (isTimeSelected) {
+ score = testResult[Strings.json.score].toFixed(2);
+
+ var regression = testResult[Strings.json.controller];
+ mean = [
+ "mean: ",
+ regression.average.toFixed(2),
+ " ± ",
+ regression.stdev.toFixed(2),
+ " (",
+ regression.percent.toFixed(2),
+ "%)"];
+ if (regression.concern) {
+ mean = mean.concat([
+ ", worst 5%: ",
+ regression.concern.toFixed(2)]);
+ }
+ mean = mean.join("");
+ } else {
+ var complexityRegression = testResult[Strings.json.complexity];
+ var complexityAverageRegression = testResult[Strings.json.complexityAverage];
+
+ document.getElementById("complexity-regression-aggregate-raw").textContent = complexityRegression.complexity.toFixed(2) + ", ±" + complexityRegression.stdev.toFixed(2) + "ms";
+ document.getElementById("complexity-regression-aggregate-average").textContent = complexityAverageRegression.complexity.toFixed(2) + ", ±" + complexityAverageRegression.stdev.toFixed(2) + "ms";
+
+ var bootstrap = complexityRegression[Strings.json.bootstrap];
+ if (bootstrap) {
+ score = bootstrap.median.toFixed(2);
+ mean = [
+ (bootstrap.confidencePercentage * 100).toFixed(0),
+ "% CI: ",
+ bootstrap.confidenceLow.toFixed(2),
+ "–",
+ bootstrap.confidenceHigh.toFixed(2)
+ ].join("");
+ }
+ }
+
+ sectionsManager.setSectionScore("test-graph", score, mean);
+ }
+});