| Index: tools/telemetry/support/html_output/results-template.html
|
| diff --git a/tools/telemetry/support/html_output/results-template.html b/tools/telemetry/support/html_output/results-template.html
|
| index 95da288ef231995c703d03cc5dba0f2469f7ccc3..b27c08003bb1bff6b8e2dd0d3c54e9303c80f8db 100644
|
| --- a/tools/telemetry/support/html_output/results-template.html
|
| +++ b/tools/telemetry/support/html_output/results-template.html
|
| @@ -249,7 +249,7 @@ td.missingReference {
|
| </head>
|
| <body onload="init()">
|
| <div style="padding: 0 10px; white-space: nowrap;">
|
| -Result <span id="time-memory" class="checkbox"><span class="checked">Time</span><span>Memory</span></span>
|
| +Result <span id="time-memory" class="checkbox"></span>
|
| Reference <span id="reference" class="checkbox"></span>
|
| Style <span id="scatter-line" class="checkbox"><span class="checked">Scatter</span><span>Line</span></span>
|
| <span class="checkbox"><span class="checked" id="undelete">Undelete</span></span><br>
|
| @@ -278,11 +278,6 @@ var GRAPH_INDENT = 64;
|
| var PADDING_UNDER_GRAPH = 5;
|
| // px Indentation for nested children left-margins
|
| var INDENTATION = 40;
|
| -// Bit field enums for active test types
|
| -var MEMORY_TEST = 1 << 0;
|
| -var TIME_TEST = 1 << 1;
|
| -var NO_TESTS = 0;
|
| -var ALL_TESTS = MEMORY_TEST | TIME_TEST;
|
|
|
| function TestResult(metric, values, associatedRun, std, degreesOfFreedom) {
|
| if (values) {
|
| @@ -319,13 +314,13 @@ function TestResult(metric, values, associatedRun, std, degreesOfFreedom) {
|
| values = [];
|
| }
|
|
|
| - this.test = function () { return metric; }
|
| - this.values = function () { return values.map(function (value) { return metric.scalingFactor() * value; }); }
|
| - this.unscaledMean = function () { return Statistics.sum(values) / values.length; }
|
| - this.mean = function () { return metric.scalingFactor() * this.unscaledMean(); }
|
| - this.min = function () { return metric.scalingFactor() * Statistics.min(values); }
|
| - this.max = function () { return metric.scalingFactor() * Statistics.max(values); }
|
| - this.confidenceIntervalDelta = function () {
|
| + this.test = function() { return metric; }
|
| + this.values = function() { return values.map(function(value) { return metric.scalingFactor() * value; }); }
|
| + this.unscaledMean = function() { return Statistics.sum(values) / values.length; }
|
| + this.mean = function() { return metric.scalingFactor() * this.unscaledMean(); }
|
| + this.min = function() { return metric.scalingFactor() * Statistics.min(values); }
|
| + this.max = function() { return metric.scalingFactor() * Statistics.max(values); }
|
| + this.confidenceIntervalDelta = function() {
|
| if (std !== undefined) {
|
| return metric.scalingFactor() * Statistics.confidenceIntervalDeltaFromStd(0.95, values.length,
|
| std, degreesOfFreedom);
|
| @@ -333,26 +328,26 @@ function TestResult(metric, values, associatedRun, std, degreesOfFreedom) {
|
| return metric.scalingFactor() * Statistics.confidenceIntervalDelta(0.95, values.length,
|
| Statistics.sum(values), Statistics.squareSum(values));
|
| }
|
| - this.confidenceIntervalDeltaRatio = function () { return this.confidenceIntervalDelta() / this.mean(); }
|
| + this.confidenceIntervalDeltaRatio = function() { return this.confidenceIntervalDelta() / this.mean(); }
|
| this.percentDifference = function(other) {
|
| if (other === undefined) {
|
| return undefined;
|
| }
|
| return (other.unscaledMean() - this.unscaledMean()) / this.unscaledMean();
|
| }
|
| - this.isStatisticallySignificant = function (other) {
|
| + this.isStatisticallySignificant = function(other) {
|
| if (other === undefined) {
|
| return false;
|
| }
|
| var diff = Math.abs(other.mean() - this.mean());
|
| return diff > this.confidenceIntervalDelta() && diff > other.confidenceIntervalDelta();
|
| }
|
| - this.run = function () { return associatedRun; }
|
| + this.run = function() { return associatedRun; }
|
| }
|
|
|
| function TestRun(entry) {
|
| this.id = function() { return entry['buildTime'].replace(/[:.-]/g,''); }
|
| - this.label = function () {
|
| + this.label = function() {
|
| if (labelKey in localStorage)
|
| return localStorage[labelKey];
|
| return entry['label'];
|
| @@ -395,9 +390,9 @@ function PerfTestMetric(name, metric, unit, isImportant) {
|
| }
|
| }
|
|
|
| - this.name = function () { return name + ':' + metric; }
|
| + this.name = function() { return name + ':' + metric; }
|
| this.isImportant = isImportant;
|
| - this.isMemoryTest = function () {
|
| + this.isMemoryTest = function() {
|
| return (unit == 'kb' ||
|
| unit == 'KB' ||
|
| unit == 'MB' ||
|
| @@ -405,21 +400,21 @@ function PerfTestMetric(name, metric, unit, isImportant) {
|
| unit == 'count' ||
|
| !metric.indexOf('V8.'));
|
| }
|
| - this.addResult = function (newResult) {
|
| + this.addResult = function(newResult) {
|
| testResults.push(newResult);
|
| cachedUnit = null;
|
| cachedScalingFactor = null;
|
| }
|
| - this.results = function () { return testResults; }
|
| + this.results = function() { return testResults; }
|
| this.scalingFactor = function() {
|
| computeScalingFactorIfNeeded();
|
| return cachedScalingFactor;
|
| }
|
| - this.unit = function () {
|
| + this.unit = function() {
|
| computeScalingFactorIfNeeded();
|
| return cachedUnit;
|
| }
|
| - this.biggerIsBetter = function () {
|
| + this.biggerIsBetter = function() {
|
| if (window.unitToBiggerIsBetter == undefined) {
|
| window.unitToBiggerIsBetter = {};
|
| var units = JSON.parse(document.getElementById('units-json').textContent);
|
| @@ -536,7 +531,7 @@ function createPlot(container, test, useLargeLinePlots) {
|
| attachLinePlots(test, section.children('.line-plots'), useLargeLinePlots);
|
|
|
| var tooltip = section.children('.tooltip');
|
| - plotContainer.bind('plothover', function (event, position, item) {
|
| + plotContainer.bind('plothover', function(event, position, item) {
|
| if (item) {
|
| var postfix = item.series.id ? ' (' + item.series.id + ')' : '';
|
| tooltip.html(item.datapoint[1].toPrecision(4) + postfix);
|
| @@ -546,10 +541,10 @@ function createPlot(container, test, useLargeLinePlots) {
|
| } else
|
| tooltip.hide();
|
| });
|
| - plotContainer.mouseout(function () {
|
| + plotContainer.mouseout(function() {
|
| tooltip.hide();
|
| });
|
| - plotContainer.click(function (event) {
|
| + plotContainer.click(function(event) {
|
| event.preventDefault();
|
| minIsZero = !minIsZero;
|
| attachPlot(test, plotContainer, minIsZero);
|
| @@ -592,7 +587,7 @@ function attachLinePlots(test, container, useLargeLinePlots) {
|
| xaxis: {min: -0.5, max: values.length - 0.5},
|
| points: {show: (values.length < 2) ? true : false}});
|
| }
|
| - $.plot(container.children().last(), [values.map(function (value, index) { return [index, value]; })], options);
|
| + $.plot(container.children().last(), [values.map(function(value, index) { return [index, value]; })], options);
|
| }
|
| if (!attachedPlot)
|
| container.children().remove();
|
| @@ -652,23 +647,23 @@ function attachLinePlotLabels(test, container) {
|
| function attachPlot(test, plotContainer, minIsZero) {
|
| var results = test.results();
|
|
|
| - var values = results.reduce(function (values, result, index) {
|
| + var values = results.reduce(function(values, result, index) {
|
| var newValues = result.values();
|
| - return newValues ? values.concat(newValues.map(function (value) { return [index, value]; })) : values;
|
| + return newValues ? values.concat(newValues.map(function(value) { return [index, value]; })) : values;
|
| }, []);
|
|
|
| var plotData = [$.extend(true, {}, subpointsPlotOptions, {data: values})];
|
| - plotData.push({id: 'μ', data: results.map(function (result, index) { return [index, result.mean()]; }), color: plotColor});
|
| + plotData.push({id: 'μ', data: results.map(function(result, index) { return [index, result.mean()]; }), color: plotColor});
|
|
|
| - var overallMax = Statistics.max(results.map(function (result, index) { return result.max(); }));
|
| - var overallMin = Statistics.min(results.map(function (result, index) { return result.min(); }));
|
| + var overallMax = Statistics.max(results.map(function(result, index) { return result.max(); }));
|
| + var overallMin = Statistics.min(results.map(function(result, index) { return result.min(); }));
|
| var margin = (overallMax - overallMin) * 0.1;
|
| var currentPlotOptions = $.extend(true, {}, mainPlotOptions, {yaxis: {
|
| min: minIsZero ? 0 : overallMin - margin,
|
| max: minIsZero ? overallMax * 1.1 : overallMax + margin}});
|
|
|
| currentPlotOptions.xaxis.max = results.length - 0.5;
|
| - currentPlotOptions.xaxis.ticks = results.map(function (result, index) { return [index, result.run().label()]; });
|
| + currentPlotOptions.xaxis.ticks = results.map(function(result, index) { return [index, result.run().label()]; });
|
|
|
| $.plot(plotContainer, plotData, currentPlotOptions);
|
| }
|
| @@ -695,39 +690,66 @@ function setUpSortClicks(runs)
|
| });
|
| }
|
|
|
| -function getTestTypes(tests) {
|
| - var testTypes = NO_TESTS;
|
| - for (testName in tests) {
|
| - if (tests[testName].isMemoryTest()) {
|
| - testTypes |= MEMORY_TEST;
|
| - } else {
|
| - testTypes |= TIME_TEST;
|
| +function TestTypeSelector(tests) {
|
| + this.recognizers = {
|
| + 'Time': function(test) { return test.isMemoryTest(); },
|
| + 'Memory': function(test) { return !test.isMemoryTest(); }
|
| + };
|
| + this.testTypeNames = this.generateUsedTestTypeNames(tests);
|
| + // Default to selecting the first test-type name in the list.
|
| + this.testTypeName = this.testTypeNames[0];
|
| +}
|
| +
|
| +TestTypeSelector.prototype = {
|
| + set testTypeName(testTypeName) {
|
| + this._testTypeName = testTypeName;
|
| + this.shouldShowTest = this.recognizers[testTypeName];
|
| + },
|
| +
|
| + generateUsedTestTypeNames: function(allTests) {
|
| + var testTypeNames = [];
|
| +
|
| + for (var recognizedTestName in this.recognizers) {
|
| + var recognizes = this.recognizers[recognizedTestName];
|
| + for (var testName in allTests) {
|
| + var test = allTests[testName];
|
| + if (recognizes(test)) {
|
| + testTypeNames.push(recognizedTestName);
|
| + break;
|
| + }
|
| + }
|
| }
|
| - if (testTypes === ALL_TESTS) {
|
| - // Early out as soon as we've found all the test types.
|
| - break;
|
| +
|
| + if (testTypeNames.length === 0) {
|
| + // No test types we recognize, add 'No Results' with a dummy recognizer.
|
| + var noResults = 'No Results';
|
| + this.recognizers[noResults] = function() { return false; };
|
| + testTypeNames.push(noResults);
|
| + } else if (testTypeNames.length > 1) {
|
| + // We have more than one test type, so add 'All' with a recognizer that always succeeds.
|
| + var allResults = 'All';
|
| + this.recognizers[allResults] = function() { return true; };
|
| + testTypeNames.push(allResults);
|
| }
|
| - }
|
| - return testTypes;
|
| - }
|
|
|
| -function areMemoryResultsIgnoredForTestTypes(testTypes) {
|
| - return testTypes !== MEMORY_TEST;
|
| -}
|
| + return testTypeNames;
|
| + },
|
|
|
| -function setUpUIForTestTypes(testTypes) {
|
| - var withFirstTestTypeRemoved = testTypes & (testTypes-1);
|
| - if (withFirstTestTypeRemoved === NO_TESTS) {
|
| - // Hide button when there are zero or one test types.
|
| - document.getElementById('time-memory').style.display = 'none';
|
| + buildButtonHTMLForUsedTestTypes: function() {
|
| + var selectedTestTypeName = this._testTypeName;
|
| + // Build spans for all recognised test names with the selected test highlighted.
|
| + return this.testTypeNames.map(function(testTypeName) {
|
| + var classAttribute = testTypeName === selectedTestTypeName ? ' class=checked' : '';
|
| + return '<span' + classAttribute + '>' + testTypeName + '</span>';
|
| + }).join('');
|
| }
|
| -}
|
| +};
|
|
|
| var topLevelRows;
|
| var allTableRows;
|
|
|
| -function createTable(tests, runs, shouldIgnoreMemory, referenceIndex, useLargeLinePlots) {
|
| - var resultHeaders = runs.map(function (run, index) {
|
| +function displayTable(tests, runs, testTypeSelector, referenceIndex, useLargeLinePlots) {
|
| + var resultHeaders = runs.map(function(run, index) {
|
| var header = '<th id="' + run.id() + '" ' +
|
| 'colspan=2 ' +
|
| 'title="' + run.description() + '">' +
|
| @@ -782,10 +804,9 @@ function createTable(tests, runs, shouldIgnoreMemory, referenceIndex, useLargeLi
|
| allTableRows = [];
|
| testNames.forEach(function(testName) {
|
| var test = tests[testName];
|
| - if (test.isMemoryTest() === shouldIgnoreMemory) {
|
| - return;
|
| + if (testTypeSelector.shouldShowTest(test)) {
|
| + allTableRows.push(new TableRow(runs, test, referenceIndex, useLargeLinePlots));
|
| }
|
| - allTableRows.push(new TableRow(runs, test, referenceIndex, useLargeLinePlots));
|
| });
|
|
|
| // Build a list of top level rows with attached children
|
| @@ -861,10 +882,10 @@ function createTable(tests, runs, shouldIgnoreMemory, referenceIndex, useLargeLi
|
| location.reload();
|
| }
|
| });
|
| - $('#labelEditor').click(function (event) {
|
| + $('#labelEditor').click(function(event) {
|
| event.stopPropagation();
|
| });
|
| - $('#labelEditor').mousedown(function (event) {
|
| + $('#labelEditor').mousedown(function(event) {
|
| event.stopPropagation();
|
| });
|
| $('#labelEditor').select();
|
| @@ -1376,7 +1397,7 @@ function init() {
|
| var runs = [];
|
| var metrics = {};
|
| var deletedRunsById = {};
|
| - $.each(JSON.parse(document.getElementById('results-json').textContent), function (index, entry) {
|
| + $.each(JSON.parse(document.getElementById('results-json').textContent), function(index, entry) {
|
| var run = new TestRun(entry);
|
| if (run.isHidden()) {
|
| deletedRunsById[run.id()] = run;
|
| @@ -1408,36 +1429,35 @@ function init() {
|
| });
|
|
|
| var useLargeLinePlots = false;
|
| -
|
| - var testTypes = getTestTypes(metrics);
|
| -
|
| - setUpUIForTestTypes(testTypes);
|
| - var shouldIgnoreMemory = areMemoryResultsIgnoredForTestTypes(testTypes);
|
| var referenceIndex = 0;
|
|
|
| - createTable(metrics, runs, shouldIgnoreMemory, referenceIndex, useLargeLinePlots);
|
| + var testTypeSelector = new TestTypeSelector(metrics);
|
| + var buttonHTML = testTypeSelector.buildButtonHTMLForUsedTestTypes();
|
| + $('#time-memory').append(buttonHTML);
|
|
|
| - $('#time-memory').bind('change', function (event, checkedElement) {
|
| - shouldIgnoreMemory = checkedElement.textContent == 'Time';
|
| - createTable(metrics, runs, shouldIgnoreMemory, referenceIndex, useLargeLinePlots);
|
| - });
|
| -
|
| - $('#scatter-line').bind('change', function (event, checkedElement) {
|
| + $('#scatter-line').bind('change', function(event, checkedElement) {
|
| useLargeLinePlots = checkedElement.textContent == 'Line';
|
| - createTable(metrics, runs, shouldIgnoreMemory, referenceIndex, useLargeLinePlots);
|
| + displayTable(metrics, runs, testTypeSelector, referenceIndex, useLargeLinePlots);
|
| });
|
|
|
| - runs.map(function (run, index) {
|
| + runs.map(function(run, index) {
|
| $('#reference').append('<span value="' + index + '"' + (index == referenceIndex ? ' class="checked"' : '') + ' title="' + run.description() + '">' + run.label() + '</span>');
|
| })
|
|
|
| - $('#reference').bind('change', function (event, checkedElement) {
|
| + $('#time-memory').bind('change', function(event, checkedElement) {
|
| + testTypeSelector.testTypeName = checkedElement.textContent;
|
| + displayTable(metrics, runs, testTypeSelector, referenceIndex, useLargeLinePlots);
|
| + });
|
| +
|
| + $('#reference').bind('change', function(event, checkedElement) {
|
| referenceIndex = parseInt(checkedElement.getAttribute('value'));
|
| - createTable(metrics, runs, shouldIgnoreMemory, referenceIndex, useLargeLinePlots);
|
| + displayTable(metrics, runs, testTypeSelector, referenceIndex, useLargeLinePlots);
|
| });
|
|
|
| - $('.checkbox').each(function (index, checkbox) {
|
| - $(checkbox).children('span').click(function (event) {
|
| + displayTable(metrics, runs, testTypeSelector, referenceIndex, useLargeLinePlots);
|
| +
|
| + $('.checkbox').each(function(index, checkbox) {
|
| + $(checkbox).children('span').click(function(event) {
|
| if ($(this).hasClass('checked'))
|
| return;
|
| $(checkbox).children('span').removeClass('checked');
|
| @@ -1451,7 +1471,7 @@ function init() {
|
| if (runToUndelete) {
|
| $('#undelete').html('Undelete ' + runToUndelete.label());
|
| $('#undelete').attr('title', runToUndelete.description());
|
| - $('#undelete').click(function (event) {
|
| + $('#undelete').click(function(event) {
|
| runToUndelete.show();
|
| undeleteManager.undeleteMostRecent();
|
| location.reload();
|
|
|