// --- BEGIN Global variables -----------------------------------
var database = null;
var currDate = null;
var host = null;
var platform = null;
var branch = null;
var snapshots = null;
var plot = null;
// --- END Global variables -----------------------------------
function tooltipText_ms() {
return "Missing snapshots, i.e. the number of " +
"target snapshots for which no results exist." +
"
A high value might indicate unstable execution.";
}
function tooltipText_lsd() {
return "Last Snapshot Distance, i.e. distance " +
"between the last target snapshot and " +
"the last snapshot in this time series." +
"
If the last target snapshot is the " +
"last one available in the database, " +
"a high value might indicate that the benchmark " +
"currently fails to produce results.";
}
function tooltipText_ni() {
return "Total number of observations " +
"explicitly flagged as invalid.
" +
"An invalid observation is typically " +
"caused by a failed QVERIFY() etc.";
}
function tooltipText_nz() {
return "Total number of non-positive observations.
" +
"Normally an observation must be positive to be valid.
" +
"Note: A non-positive observation is not " +
"necessarily flagged as invalid (see NI).";
}
function tooltipText_nc() {
return "Number of significant changes, i.e. changes that are either " +
"better than DT or worse than 1 / DT, where DT " +
"is the difference tolerance.
" +
"A high value might indicate unstable or fluctuating results.";
}
function tooltipText_mdrse() {
return "Median of the valid relative standard errors of all " +
"snapshots.
" +
" " +
"" +
"
A high value might indicate " +
"unstable or fluctuating results.";
}
function tooltipText_rsemd() {
return "Relative standard error of the valid median observations " +
"of all snapshots.
" +
" " +
"" +
"
A high value might indicate either 1)" +
"unstable or fluctuating results
" +
"or 2) stable changes of a high magnitude.";
}
function tooltipText_lc() {
return "Last significant change. (See documentation elsewhere for a " +
"definition of how the significant changes of a time series are " +
"computed!)
" +
"The higher the value is above 1, the more strongly it " +
"represents an improvement.
" +
"The lower the value is below 1, the more strongly it " +
"represents a regression.";
}
function tooltipText_lcda() {
return "Days ago (relative to the report date) since the first " +
"observation for the last significant change snapshot was uploaded " +
"to the database." +
"
The distance (in terms of number of target snapshots) " +
"between the last significant change snapshot and the last target " +
"snapshot is shown in parentheses.";
}
function tooltipText_lcms() {
return "Magnitude score of the last significant change. This score " +
"indicates the strength of the last signicifant change as a value " +
"ranging from 0 (weak) to 1 (strong):
" +
" " +
"";
}
function tooltipText_lcss() {
return "Stability score for the last significant change:
" +
" " +
"LCMS * LCGSS * LCLSS * LCDS1 * LCDS2
" +
"The higher this score, the higher the likelihood that the last " +
"significant change is or will become permanent.";
}
function tooltipText_lcss1() {
return "Stability score for the last significant change that does not " +
"consider the history after the latter:
" +
" " +
"LCMS * LCGSS * LCLSS * LCDS1
" +
"The higher this score, the higher the likelihood that the last " +
"signicifant change is or will become permanent, but since LCDS2 is " +
"omitted from the product, a high LCSS1 is more likely to be caused " +
"by an outlier than a high LCSS!";
}
function tooltipText_lcgss() {
return "Global separation score for the last significant change. " +
"This score indicates how well the median observation " +
"at the last significant change snapshot are separated from the " +
"median observations at all preceding snapshots in the " +
"time series. The median observation at the base snapshot " +
"(i.e. the snapshot of the second to last significant change or " +
"the first snapshot in the time series) is used as the maximum " +
"separation reference." +
"
The score ranges from 0 (weak separation) to 1 " +
"(strong separation)." +
"
This score roughly measures how close the median " +
"observation at the last significant change is to represent an " +
"\"all time high(low)\" up to this point in the history.";
}
function tooltipText_lclss() {
return "Local separation score for the last significant change. " +
"This score indicates how well the median observations on each side " +
"of the last significant change snapshot are separated from each " +
"other. Snapshots before the base snapshot (i.e. the snapshot of " +
"the second to last significant change or the first snapshot in the " +
"time series) are not considered. " +
"The median observation at the base snapshot is used as the maximum " +
"separation reference. " +
"
The score ranges from 0 (weak separation) to 1 " +
"(strong separation).";
}
function tooltipText_lcds1() {
return "Duration score 1 for the last significant change. " +
"This score indicates the distance (in terms of number of snapshots) " +
"from the last significant change to the base snapshot (i.e. the " +
"snapshot of the second to last significant change or the first " +
"snapshot in the time series)." +
"
The score ranges from 0 (short duration) to 1 " +
"(long duration), and is scaled against the min/max duration " +
"tolerances." +
"
This score measures for how long the median " +
"observation stayed near the base value until the last significant " +
"change occurred.";
}
function tooltipText_lcds2() {
return "Duration score 2 for the last significant change. " +
"This score indicates the distance (in terms of number of snapshots) " +
"from the last significant change to the end of the time series." +
"
The score ranges from 0 (short duration) to 1 " +
"(long duration), and is scaled against the min/max duration " +
"tolerances." +
"
This score measures for how long the median " +
"observation at the last change significant change has stayed " +
"essentially the same.";
}
function tooltipText_rse_plot() {
return "Relative standard error of the valid and positive observations " +
"in this sample.
" +
"
" +
"Note: RSE is not defined for less than two values.";
}
function tooltipText_medobs_plot() {
return "The median of the valid and positive observations in this sample." +
"
This is often the most representative/typical value " +
"in the sample.";
}
function tooltipText_change_plot() {
return "The factor by which the selected result improves over " +
"the base result wrt the median observation." +
"
The values 0.5, 1, and 2 indicate " +
"half, equal, and double performance respectively.";
}
// A Flot plugin to draw a horizontal age bar above a time series.
// Snapshots are assumed to be regularly spaced.
// ### 2 B DOCUMENTED!
(function ($) {
var options = {
ageBar: {
// no options
}
};
function init(plot) {
function drawAgeBar(plot, ctx) {
//var opt = plot.getOptions().ageBar;
var currTime = dateToTimestamp(currDate);
var topGap = 5;
var y1 = -topGap;
var y2 = -20;
var nsnapshots = snapshots.length;
var w = plot.width() / (nsnapshots - 1);
var w_2 = w * 0.5;
var plotOffset = plot.getPlotOffset();
for (var i = 0; i < nsnapshots; ++i) {
var secsAgo = currTime - snapshots[i][1];
var color = ageColor(secsAgo);
var x1 = i * w - w_2;
var x2 = x1 + w;
x1 = Math.max(-w_2, x1);
x2 = Math.min(plot.width() + w_2, x2);
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x1, y2);
ctx.lineTo(x2, y2);
ctx.lineTo(x2, y1);
ctx.lineTo(x1, y1);
ctx.fill();
ctx.restore();
}
}
plot.hooks.drawOverlay.push(drawAgeBar);
}
$.plot.plugins.push({
init: init,
options: options,
name: "agebar",
version: "0.1"
});
})(jQuery);
function drawHighlightedSnapshot(
plot, ctx, index, precIndex, nsnapshots, color) {
if ((index < 0) || (index >= nsnapshots))
return;
if (nsnapshots < 0)
return;
var plotOffset = plot.getPlotOffset();
var w = plot.width() / (nsnapshots - 1);
var x = (index / (nsnapshots - 1.0)) * plot.width();
var x1 = -1;
if (precIndex >= 0)
x1 = x - ((index - precIndex) + 0.5) * w;
else
x1 = x - 0.5 * w;
var x2 = x + 0.5 * w;
var topExcess = 5;
var bottomExcess = 7;
var y1 = -topExcess;
var y2 = 0;
var y3 = plot.height();
var y4 = plot.height() + bottomExcess;
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x1, y2);
ctx.lineTo(x2, y2);
ctx.lineTo(x2, y1);
ctx.lineTo(x1, y1);
ctx.fill();
ctx.strokeStyle = color;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(x1, y2);
ctx.lineTo(x1, y3);
ctx.lineTo(x2, y3);
ctx.lineTo(x2, y2);
ctx.lineTo(x1, y2);
ctx.stroke();
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(x1, y3);
ctx.lineTo(x1, y4);
ctx.lineTo(x2, y4);
ctx.lineTo(x2, y3);
ctx.lineTo(x1, y3);
ctx.fill();
ctx.restore();
}
// A Flot plugin to manipulate highlighting of a hovered snapshot
// in a time series. Snapshots are assumed to be regularly spaced.
// ### 2 B DOCUMENTED!
(function ($) {
var index = -1;
var precIndex = -1;
var options = {
hoveredSnapshot: {
size: -1,
color: "rgba(80, 80, 80, 0.3)"
}
};
function init(plot) {
plot.setHoveredSnapshot = function setHoveredSnapshot(i, pi) {
index = i;
precIndex = pi;
}
plot.clearHoveredSnapshot = function clearHoveredSnapshot() {
index = -1;
precIndex = -1;
}
function drawHoveredSnapshot(plot, ctx) {
var opt = plot.getOptions().hoveredSnapshot;
drawHighlightedSnapshot(
plot, ctx, index, precIndex, opt.size, opt.color);
}
plot.hooks.drawOverlay.push(drawHoveredSnapshot);
}
$.plot.plugins.push({
init: init,
options: options,
name: "hoveredsnapshot",
version: "0.1"
});
})(jQuery);
// A Flot plugin to manipulate highlighting of a clicked snapshot
// in a time series. Snapshots are assumed to be regularly spaced.
// ### 2 B DOCUMENTED!
(function ($) {
var index = -1;
var precIndex = -1;
var options = {
clickedSnapshot: {
size: -1,
color: "rgba(0, 0, 255, 0.5)"
}
};
function init(plot) {
plot.setClickedSnapshot = function setClickedSnapshot(i, pi) {
index = i;
precIndex = pi;
}
plot.clearClickedSnapshot = function clearClickedSnapshot() {
index = -1;
precIndex = -1;
}
function drawClickedSnapshot(plot, ctx) {
var opt = plot.getOptions().clickedSnapshot;
drawHighlightedSnapshot(
plot, ctx, index, precIndex, opt.size, opt.color);
}
plot.hooks.drawOverlay.push(drawClickedSnapshot);
}
$.plot.plugins.push({
init: init,
options: options,
name: "clickedsnapshot",
version: "0.1"
});
})(jQuery);
// A Flot plugin to manipulate highlighting of missing snapshots
// in a time series. Snapshots are assumed to be regularly spaced.
// ### 2 B DOCUMENTED!
(function ($) {
var missing = null;
var options = {
missingSnapshots: {
size: -1,
color: "rgba(255, 0, 0, 0.2)"
}
};
function init(plot) {
plot.setMissingSnapshots = function setMissingSnapshots(m) {
missing = m;
}
function drawMissingSnapshots(plot, ctx) {
if (missing == null) {
return;
}
var opt = plot.getOptions().missingSnapshots;
if (opt.size < 0) {
return;
}
var plotOffset = plot.getPlotOffset();
//var w_2 = 0.5 * (plot.width() / (opt.size - 1));
var w_2 = 2;
for (var i = 0; i < missing.length; ++i) {
var x = (missing[i] / (opt.size - 1.0)) * plot.width();
var x1 = x - w_2;
var x2 = x + w_2;
var y1 = 0;
var y2 = plot.height();
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
ctx.strokeStyle = "rgba(0, 0, 0, 1)";
ctx.fillStyle = opt.color;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x1, y2);
ctx.lineTo(x2, y2);
ctx.lineTo(x2, y1);
ctx.lineTo(x1, y1);
//ctx.stroke();
ctx.fill();
ctx.restore();
}
}
plot.hooks.drawOverlay.push(drawMissingSnapshots);
}
$.plot.plugins.push({
init: init,
options: options,
name: "missingsnapshots",
version: "0.1"
});
})(jQuery);
function clearPlot() {
plot = $.plot(
$("#plot_canvas"),
[
{
color: "#000",
data: null
}
],
{
grid: {
show: false
}
}
);
$("#sample1 tr:gt(0)").remove();
$("#sample2 tr:gt(0)").remove();
$("#benchmark").text("");
$("#metric").text("");
$("#bmstats_ms").text("");
$("#bmstats_lsd").text("");
$("#bmstats_ni").text("");
$("#bmstats_nz").text("");
$("#bmstats_nc").text("");
$("#bmstats_mdrse").text("");
$("#bmstats_rsemd").text("");
$("#bmstats_lc").text("");
$("#bmstats_lcda").text("");
$("#bmstats_lcms").text("");
$("#bmstats_lcss").text("");
$("#bmstats_lcss1").text("");
$("#bmstats_lcgss").text("");
$("#bmstats_lclss").text("");
$("#bmstats_lcds1").text("");
$("#bmstats_lcds2").text("");
$("#base_res_sha1").html(emptySHA1());
$("#base_res_rse").text("");
$("#base_res_median_obs").text("");
$("#curr_sshot_sha1").html(emptySHA1());
$("#curr_sshot_rse").text("");
$("#curr_sshot_median_obs").text("");
$("#curr_sshot_change").text("");
hideTSBMURL();
}
// Creates a plot that shows the time series and significant changes
// for a single benchmark.
function createPlot(
timeSeries, changes, benchmark, metric, lowerIsBetter, ms, lsd, ni, nz,
nc, mdrse, rsemd, lc, lcda, lcd, lcms, lcss, lcss1, lcgss, lclss, lcds1,
lcds2) {
clearPlot();
var prevHoverIndex = -1;
var prevClickIndex = -1;
var maxSampleSize = null;
for (var i = 0; i < timeSeries.length; ++i) {
sampleSize = timeSeries[i][2];
if (i == 0) {
maxSampleSize = sampleSize;
} else {
maxSampleSize = Math.max(maxSampleSize, sampleSize);
}
}
var minVal = null;
var maxVal = null;
var tsValCoords = [];
var tsSampleSizeCoords = [];
var tsNRSECoords = []; // NRSE = Normalized Relative Standard Error
var tsNRSEVals = [];
var tsInvalidCoords = [];
var tsZeroCoords = [];
var isMissing = [];
for (i = 0; i < snapshots.length; ++i)
isMissing[isMissing.length] = true;
minMaxValSet = false;
for (var i = 0; i < timeSeries.length; ++i) {
index = timeSeries[i][0];
isMissing[index] = false;
val = timeSeries[i][1];
if (val > 0) {
tsValCoords[tsValCoords.length] = [index, val];
if (!minMaxValSet) {
minVal = maxVal = val;
minMaxValSet = true;
} else {
minVal = Math.min(minVal, val);
maxVal = Math.max(maxVal, val);
}
}
sampleSize = timeSeries[i][2];
tsSampleSizeCoords[tsSampleSizeCoords.length] = [index, sampleSize];
if (sampleSize > 1) {
var nrse = timeSeries[i][3];
if (val > 0)
tsNRSEVals[tsNRSEVals.length] = nrse;
scaledNRSE = nrse * maxSampleSize;
tsNRSECoords[tsNRSECoords.length] = [index, scaledNRSE];
} else if (val > 0) {
tsNRSEVals[tsNRSEVals.length] = -1;
}
invalidCount = timeSeries[i][4];
if (invalidCount > 0)
tsInvalidCoords[tsInvalidCoords.length] = [index, invalidCount];
zeroCount = timeSeries[i][5];
if (zeroCount > 0)
tsZeroCoords[tsZeroCoords.length] = [index, zeroCount];
}
var missing = [];
for (var i = 0; i < isMissing.length; ++i) {
if (isMissing[i]) {
missing[missing.length] = i;
}
}
plot.setMissingSnapshots(missing);
var goodChangeCoords = [];
var badChangeCoords = [];
for (i = 0; i < changes.length; ++i) {
tsIndex = changes[i][0];
val = changes[i][1];
if (val > 1) {
goodChangeCoords[goodChangeCoords.length] = tsValCoords[tsIndex];
} else {
badChangeCoords[badChangeCoords.length] = tsValCoords[tsIndex];
}
}
var currTime = dateToTimestamp(currDate);
var options = {
xaxis: {
min: 0,
max: snapshots.length - 1 ,
tickFormatter: function(x) {
var i = parseInt(x);
if ((i < 0) || (i >= snapshots.length))
return "";
var secsAgo = currTime - snapshots[i][1];
return secsToDays(secsAgo);
}
},
yaxis: {
min: minVal,
max: maxVal
},
y2axis: {
min: 0,
max: maxSampleSize,
tickDecimals: 0
},
grid: {
show: true,
hoverable: true,
clickable: true,
mouseActiveRadius: 5,
autoHighlight: true,
// backgroundColor: "#ffffff",
backgroundColor: null,
borderColor: "#ddd"
},
ageBar: {
// no options
},
hoveredSnapshot: {
size: snapshots.length
},
clickedSnapshot: {
size: snapshots.length
},
missingSnapshots: {
size: snapshots.length
},
lineWidth: 0
};
plot = $.plot(
$("#plot_canvas"),
[
{
hoverable: false,
clickable: false,
color: "#8ff",
bars: {
show: true,
align: "center",
lineWidth: 0,
fill: true
},
data: tsSampleSizeCoords,
yaxis: 2
},
{
hoverable: false,
clickable: false,
color: "#f22",
bars: {
show: true,
align: "center",
lineWidth: 0,
fill: true
},
data: tsZeroCoords,
yaxis: 2
},
{
hoverable: false,
clickable: false,
color: "#f0f",
bars: {
show: true,
align: "center",
lineWidth: 2,
fill: false
},
data: tsInvalidCoords,
yaxis: 2
},
{
hoverable: false,
clickable: false,
color: "#770",
lineWidth: 0,
points: {
show: true,
radius: 3,
lineWidth: 0,
fillColor: "#ff0",
fill: true
},
shadowSize: 0,
data: tsNRSECoords,
yaxis: 2
},
{
hoverable: false,
clickable: false,
color: "#000",
lines: {
show: true,
lineWidth: 1,
},
points: {
show: true,
radius: 2,
fill: false
},
shadowSize: 2,
data: tsValCoords
},
{
hoverable: false,
clickable: false,
color: "#0a0",
lines: {
show: false
},
points: {
show: true,
radius: 5,
fill: false
},
data: goodChangeCoords
},
{
hoverable: false,
clickable: false,
color: "#f00",
lines: {
show: false
},
points: {
show: true,
radius: 5,
fill: false
},
data: badChangeCoords
}
],
options
);
function clearHoverHighlighting() {
plot.clearHoveredSnapshot();
plot.triggerRedrawOverlay();
prevHoverIndex = -1;
}
$("#plot_canvas").unbind("mouseleave");
$("#plot_canvas").bind("mouseleave", function (event, pos, item) {
clearHoverHighlighting();
});
$("#plot_canvas").unbind("plothover");
$("#plot_canvas").bind("plothover", function (event, pos, item) {
snIndex = Math.floor(pos.x + 0.5); // Snapshot index
if ((snIndex < 0) || (snIndex >= snapshots.length))
return;
if (snIndex == prevHoverIndex)
// No change, so just ignore:
return;
prevHoverIndex = snIndex;
var tsIndex = -1; // Time series index
for (tsIndex = 0; tsIndex < tsValCoords.length; ++tsIndex) {
if (tsValCoords[tsIndex][0] == snIndex)
break;
}
if (tsIndex == tsValCoords.length)
// The time series is missing the clicked snapshot:
tsIndex = -1;
plot.setHoveredSnapshot(snIndex, snIndex);
plot.triggerRedrawOverlay();
// $("#curr_sshot_sha1").text(snapshots[tsValCoords[tsIndex][0]][0]);
// $("#curr_sshot_median_obs").text(tsValCoords[tsIndex][1]);
// if (tsIndex > 0) {
// var val1 = tsValCoords[tsIndex - 1][1];
// var val2 = tsValCoords[tsIndex][1];
// if (lowerIsBetter) {
// ratio = val1 / val2;
// } else {
// ratio = val2 / val1;
// }
// $("#base_res_median_obs").text(val1);
// $("#curr_sshot_change").text(ratio);
// sha1 = snapshots[tsValCoords[tsIndex][0]][0];
// sha1_prec = snapshots[tsValCoords[tsIndex - 1][0]][0];
// fetchResultDetails2(benchmark, metric, sha1_prec, sha1);
// } else {
// $("#base_res_median_obs").text("none");
// $("#curr_sshot_change").text("");
// }
});
function clearClickHighlighting() {
plot.clearClickedSnapshot();
plot.triggerRedrawOverlay();
prevClickIndex = -1;
$("#base_res_sha1").html(emptySHA1());
$("#base_res_rse").text("");
$("#base_res_median_obs").text("");
$("#curr_sshot_sha1").html(emptySHA1());
$("#curr_sshot_rse").text("");
$("#curr_sshot_median_obs").text("");
$("#curr_sshot_change").text("");
$("#sample1 tr:gt(0)").remove();
$("#sample2 tr:gt(0)").remove();
}
$("#plot_canvas").unbind("plotclick");
$("#plot_canvas").bind("plotclick", function (event, pos, item) {
snIndex = Math.floor(pos.x + 0.5); // Snapshot index
if ((snIndex < 0) || (snIndex >= snapshots.length))
return;
if (snIndex == prevClickIndex) {
// No change ...
clearClickHighlighting();
return;
}
prevClickIndex = snIndex;
var tsIndex = -1; // Time series index
for (tsIndex = 0; tsIndex < tsValCoords.length; ++tsIndex) {
if (tsValCoords[tsIndex][0] == snIndex)
break;
}
if (tsIndex == tsValCoords.length)
// The time series is missing the clicked snapshot:
tsIndex = -1;
plot.setClickedSnapshot(snIndex, snIndex);
plot.triggerRedrawOverlay();
$("#base_res_sha1").html(emptySHA1());
$("#base_res_rse").text("");
$("#base_res_median_obs").text("");
$("#curr_sshot_sha1").text(snapshots[snIndex][0]);
$("#curr_sshot_rse").text("");
$("#curr_sshot_median_obs").text("");
$("#curr_sshot_change").text("");
$("#sample1 tr:gt(0)").remove();
$("#sample2 tr:gt(0)").remove();
if (tsIndex >= 0) {
$("#curr_sshot_median_obs").text(tsValCoords[tsIndex][1]);
var nrse = tsNRSEVals[tsIndex];
if (nrse >= 0)
$("#curr_sshot_rse").text((nrse * 100).toFixed(2));
else
$("#curr_sshot_rse").text("");
if (tsIndex > 0) {
var i;
var baseIndex = 0;
for (i = 0; i < changes.length; ++i) {
changeIndex = changes[i][0];
if (tsIndex <= changeIndex)
break;
baseIndex = changeIndex;
}
var baseVal = tsValCoords[baseIndex][1];
var changeVal = tsValCoords[tsIndex][1];
if (lowerIsBetter)
ratio = baseVal / changeVal;
else
ratio = changeVal / baseVal;
var baseTsIndex = tsValCoords[baseIndex][0];
$("#base_res_sha1").text(snapshots[baseTsIndex][0]);
$("#base_res_median_obs").text(baseVal);
var nrse = tsNRSEVals[baseIndex];
if (nrse >= 0)
$("#base_res_rse").text((nrse * 100).toFixed(2));
else
$("#base_rse_rse").text("");
$("#curr_sshot_change").text(ratio);
$("#curr_sshot_change").css(
"color", (ratio > 1) ? "#0a0"
: ((ratio < 1) ? "f00" : "000"));
var sha1 = snapshots[tsValCoords[tsIndex][0]][0];
var sha1_prec = snapshots[tsValCoords[baseIndex][0]][0];
fetchResultDetails2(benchmark, metric, sha1_prec, sha1);
} else {
var sha1 = snapshots[tsValCoords[tsIndex][0]][0];
fetchResultDetails2(benchmark, metric, "", sha1);
}
}
});
clearHoverHighlighting();
clearClickHighlighting();
$("#benchmark").html(benchmark.replace(anySpace, " "));
$("#metric").text(metric);
if (!isNaN(ms)) $("#bmstats_ms").text(ms);
if (!isNaN(lsd)) $("#bmstats_lsd").text(lsd);
if (!isNaN(ni)) $("#bmstats_ni").text(ni);
if (!isNaN(nz)) $("#bmstats_nz").text(nz);
if (!isNaN(nc)) $("#bmstats_nc").text(nc);
if (!isNaN(mdrse)) $("#bmstats_mdrse").text(parseFloat(mdrse).toFixed(2));
if (!isNaN(rsemd)) $("#bmstats_rsemd").text(parseFloat(rsemd).toFixed(2));
if (!isNaN(lc)) {
$("#bmstats_lc").text(lc);
$("#bmstats_lc").css(
"color", ((lc < 1) ? "#a00" : ((lc > 1) ? "#0a0" : "#000")));
}
if (!isNaN(lcda)) {
$("#bmstats_lcda").html(lcda.toFixed(2) + " (" + lcd + ")");
var secsAgo = daysToSecs(lcda);
var ageColor_ = ageColor(secsAgo);
$("#bmstats_lcda").css("background-color", ageColor_);
}
if (!isNaN(lcms)) $("#bmstats_lcms").text(lcms);
if (!isNaN(lcss)) $("#bmstats_lcss").text(lcss);
if (!isNaN(lcss1)) $("#bmstats_lcss1").text(lcss1);
if (!isNaN(lcgss)) $("#bmstats_lcgss").text(lcgss);
if (!isNaN(lclss)) $("#bmstats_lclss").text(lclss);
if (!isNaN(lcds1)) $("#bmstats_lcds1").text(lcds1);
if (!isNaN(lcds2)) $("#bmstats_lcds2").text(lcds2);
}
// ### REFACTOR: Similar function in stats2.js! 2 B DONE!
function fetchResultDetails2(benchmark, metric, sha11, sha12) {
updateStatus("fetching result details ...", true);
query = "?db=" + database +
"&cmd=result_details2" +
"&host1=" + encodeURIComponent(host) +
"&platform1=" + encodeURIComponent(platform) +
"&branch1=" + encodeURIComponent(branch) +
"&sha11=" + sha11 +
"&host2=" + encodeURIComponent(host) +
"&platform2=" + encodeURIComponent(platform) +
"&branch2=" + encodeURIComponent(branch) +
"&sha12=" + sha12 +
"&benchmark=" + encodeURIComponent(benchmark) +
"&metric=" + encodeURIComponent(metric);
url = "http://" + location.host + "/cgi-bin/getstatswrapper" + query;
//alert("url: >" + url + "<");
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: function(data, textStatus, request) {
if (request.readyState == 4) {
if (request.status == 200) {
if (data.error != null) {
updateStatus(
"fetching result details ... failed: " +
data.error, false);
return;
}
updateStatus("fetching result details ... done", false);
updateStatus("", false);
// Show samples ...
samples = { "1": data.sample1, "2": data.sample2 };
var currTime = dateToTimestamp(currDate);
for (key in samples) {
// $("#sample" + key + " option").remove();
sample = samples[key];
nValidAndPos = 0;
for (i = 0; i < sample.length; ++i)
nValidAndPos += (
sample[i].valid && sample[i].value > 0);
medianIndex = Math.floor(nValidAndPos / 2);
twoMedianIndexes = ((nValidAndPos % 2) == 0);
validIndex = 0;
html = "";
for (i = 0; i < sample.length; ++i) {
value = sample[i].value;
valid = sample[i].valid;
secsAgo = currTime - sample[i].timestamp;
ageColor_ = ageColor(secsAgo);
if (!valid) {
bgColor = "#faa";
} else {
if ((validIndex == medianIndex) ||
(twoMedianIndexes
&& (validIndex == (medianIndex - 1)))) {
bgColor = "#ff0";
} else {
bgColor = "#fff";
}
validIndex++;
}
// $("#sample" + key).append(
// "");
html += "