diff --git a/codespeed/static/js/comparison.js b/codespeed/static/js/comparison.js
index 48415b3e..19ada2bc 100644
--- a/codespeed/static/js/comparison.js
+++ b/codespeed/static/js/comparison.js
@@ -16,6 +16,10 @@ var COLORS = [
];
function getColor(i) { return COLORS[i % COLORS.length]; }
+function getExeLabel(key) {
+ return $("label[for='exe_" + key.replace(/:/g, '\\:') + "']").text().trim();
+}
+
function getConfiguration() {
return {
exe: readCheckbox("input[name='executables']:checked"),
@@ -27,6 +31,86 @@ function getConfiguration() {
};
}
+function updateGraphTitle(exes, enviros, bens, baseline, chart, chartTitles) {
+ var $title = $("#graph-title");
+
+ if (enviros.length === 1 && exes.length === 2 && baseline !== "none" &&
+ chart !== "stacked bars" && compdata) {
+
+ var baselineExe = baseline, baselineEnv = null;
+ if (baseline.indexOf('@') !== -1) {
+ var bparts = baseline.split('@');
+ baselineExe = bparts[0];
+ baselineEnv = bparts[1];
+ }
+
+ var otherExes = exes.filter(function(e) { return e !== baselineExe; });
+ if (otherExes.length === 1) {
+ var otherExe = otherExes[0];
+ var envId = enviros[0];
+ var envForBase = baselineEnv !== null ? baselineEnv : envId;
+
+ var product = 1, count = 0;
+ for (var b = 0; b < bens.length; b++) {
+ var val = compdata[otherExe] && compdata[otherExe][envId]
+ ? compdata[otherExe][envId][bens[b]]
+ : null;
+ var baseval = compdata[baselineExe] && compdata[baselineExe][envForBase]
+ ? compdata[baselineExe][envForBase][bens[b]]
+ : null;
+ if (val !== null && baseval !== null && baseval !== 0 && val > 0) {
+ product *= val / baseval;
+ count++;
+ }
+ }
+
+ if (count > 0) {
+ var geomean = Math.pow(product, 1 / count);
+
+ var lessCount = 0, moreCount = 0;
+ var benSet = {};
+ for (var b = 0; b < bens.length; b++) { benSet[bens[b]] = true; }
+ for (var u in bench_units) {
+ var unitBens = bench_units[u][0];
+ var unitLess = bench_units[u][1].indexOf("less") !== -1;
+ for (var ub = 0; ub < unitBens.length; ub++) {
+ if (benSet[unitBens[ub]]) {
+ if (unitLess) { lessCount++; } else { moreCount++; }
+ }
+ }
+ }
+
+ var otherLabel = getExeLabel(otherExe);
+ var baselineLabel = getExeLabel(baselineExe);
+ if (baselineEnv !== null) {
+ baselineLabel += ' @ ' + $("label[for='env_" + baselineEnv + "']").text().trim();
+ }
+
+ var suffix;
+ if (moreCount === 0 && lessCount > 0) {
+ suffix = geomean < 1
+ ? ' or ' + (1 / geomean).toFixed(1) + '× faster'
+ : ' or ' + geomean.toFixed(1) + '× slower';
+ } else if (lessCount === 0 && moreCount > 0) {
+ suffix = geomean > 1
+ ? ' or ' + geomean.toFixed(1) + '× faster'
+ : ' or ' + (1 / geomean).toFixed(1) + '× slower';
+ } else {
+ suffix = ' relative to baseline';
+ }
+
+ $title.html('The geometric average of ' + count + ' benchmarks for ' +
+ otherLabel + ' is ' + geomean.toFixed(2) + '' +
+ suffix + ' than the baseline ' + baselineLabel + '');
+ return;
+ }
+ }
+ }
+
+ // Fall back to the chart title(s)
+ $title.text(chartTitles.join(' / '));
+}
+
function refreshContent() {
var conf = getConfiguration(),
exes = conf.exe.split(","),
@@ -34,6 +118,7 @@ function refreshContent() {
enviros = conf.env.split(","),
msg = "";
+ $("#graph-title").html("");
var h = $("#plotwrapper").height();//get height for error message
if (exes[0] === "") {
$("#plotwrapper").html('
No executables selected
');
@@ -73,6 +158,7 @@ function refreshContent() {
$("#plotwrapper").fadeOut("fast", function() {
$(this).html(msg).show();
var plotcounter = 1;
+ var chartTitles = [];
for (var unit in bench_units) {
var benchmarks = [];
for (var ben in bens) {
@@ -85,8 +171,9 @@ function refreshContent() {
var plotid = "plot" + plotcounter;
$("#plotwrapper").append('');
plotcounter++;
- renderComparisonPlot(plotid, unit, benchmarks, exes, enviros, conf.bas, conf.chart, conf.hor);
+ chartTitles.push(renderComparisonPlot(plotid, unit, benchmarks, exes, enviros, conf.bas, conf.chart, conf.hor));
}
+ updateGraphTitle(exes, enviros, bens, conf.bas, conf.chart, chartTitles);
});
}
@@ -114,7 +201,7 @@ function updateBaselineDropdown() {
if (multiEnv) {
enviros.forEach(function(envId) {
var envName = $("label[for='env_" + envId + "']").text().trim();
- $baseline.append($('