Current section

Files

Jump to
benchfella priv ui.js
Raw

priv/ui.js

var CHART_OFFSET_X = 150;
var CHART_WIDTH = 600;
var DATA_LABEL_OFFSET_X = 10;
var BAR_HEIGHT = 20;
var BAR_SPACING = 10;
var BAR_HEIGHT_TOTAL = BAR_HEIGHT + BAR_SPACING;
var BLUES = ["#deebf7", "#c6dbef", "#9ecae1", "#6baed6", "#4292c6", "#2171b5", "#08519c"];
var GREENS = ["#e5f5e0", "#c7e9c0", "#a1d99b", "#74c476", "#41ab5d", "#238b45", "#006d2c"];
var BLACKS = ["#f0f0f0", "#d9d9d9", "#bdbdbd", "#969696", "#737373", "#525252", "#252525"];
var ORANGES = ["#fee6ce", "#fdd0a2", "#fdae6b", "#fd8d3c", "#f16913", "#d94801", "#a63603"];
var VIOLETS = ["#efedf5", "#dadaeb", "#bcbddc", "#9e9ac8", "#807dba", "#6a51a3", "#54278f"];
var REDS = ["#fee0d2", "#fcbba1", "#fc9272", "#fb6a4a", "#ef3b2c", "#cb181d", "#a50f15"];
var NCOLORS = 7;
var COLORS = [BLUES, GREENS, ORANGES, VIOLETS, REDS, BLACKS];
var PALETTE = ["#edf8fb", "#ccece6", "#99d8c9", "#66c2a4", "#2ca25f", "#006d2c"].reverse();
//var PALETTE = ["#f1eef6", "#d4b9da", "#c994c7", "#df65b0", "#dd1c77", "#980043"].reverse();
//var PALETTE = ["#fee5d9", "#fcbba1", "#fc9272", "#fb6a4a", "#de2d26", "#a50f15"].reverse();
//var PALETTE = ["#f2f0f7", "#dadaeb", "#bcbddc", "#9e9ac8", "#756bb1", "#54278f"].reverse();
//var PALETTE = ["#ffffcc", "#c7e9b4", "#7fcdbb", "#41b6c4", "#2c7fb8", "#253494"].reverse();
function color_at(i, j) {
if (!j) j = 0;
return PALETTE[(i+j)%PALETTE.length];
//return COLORS[i % COLORS.length][NCOLORS - 1 - j % NCOLORS];
}
function format_time(time) {
return parseFloat(Math.round(time * 100) / 100).toFixed(2) + " µs/op";
}
function add_chart(name, tests, scale) {
d3.select("body").append("h2").text(name);
var svg = d3.select("body").append("svg");
make_chart(svg, name, tests, scale);
}
function make_chart(svg, name, tests, scale) {
var svgWidth = 1000;
var svgHeight = _.keys(tests).length * BAR_HEIGHT_TOTAL + 50;
svg.attr({
width: svgWidth,
height: svgHeight,
});
var nums = _.map(tests, function(val) { return val.elapsed / val.n; });
var names = _.map(tests, function(val, name) { return name; });
var dataScale;
if (scale == "linear") {
dataScale = d3.scale.linear().domain([0, d3.max(nums)]).range([0, CHART_WIDTH]);
} else if (scale == "log10") {
dataScale = d3.scale.log().domain([1, d3.max(nums)]).range([0, CHART_WIDTH]);
}
svg.selectAll("rect")
.data(nums)
.enter()
.append("rect")
.attr({
x: CHART_OFFSET_X,
y: function(d, i) { return i * (BAR_HEIGHT + BAR_SPACING); },
width: function(d) { return dataScale(d); },
height: BAR_HEIGHT,
fill: function(d, i) { return color_at(i, 0); },
});
svg.selectAll("text.label")
.data(names)
.enter()
.append("text")
.attr({
class: "label",
y: function(d, i) { return i * BAR_HEIGHT_TOTAL + BAR_HEIGHT_TOTAL/2; },
})
.text(function(d) { return d; });
svg.selectAll("text.timing")
.data(nums)
.enter()
.append("text")
.attr({
class: "timing",
x: CHART_OFFSET_X + CHART_WIDTH + DATA_LABEL_OFFSET_X,
y: function(d, i) { return i * 30 + 15; },
})
.text(function(d) { return format_time(d); });
var xAxis = d3.svg.axis()
.scale(dataScale)
.ticks(5);
var axisY = nums.length * 30;
svg.append("g")
.attr({transform: "translate("+CHART_OFFSET_X+", "+axisY+")"})
.attr("class", "data-axis")
.call(xAxis);
}
function add_comparison_chart(name, categories, scale) {
//d3.select("body").append("h2").text(name);
var svg = d3.select("body").append("svg");
make_comparison_chart(svg, categories, scale);
}
function make_comparison_chart(svg, categories, scale) {
var svgWidth = 1200;
var svgHeight = 500;
svg.attr({width: svgWidth, height: svgHeight});
var values = _.chain(categories)
.map(function(snapshots) { return snapshots; })
.flatten()
.map(function(dict) { return dict.elapsed / dict.n; })
.value();
var snapshotCount;
for (var key in categories) {
snapshotCount = categories[key].length;
break;
}
var catCount = _.size(categories);
var xPadding = 0;
var left = xPadding;
var right = svgWidth-2*xPadding;
var w0 = (right - left) / catCount;
var pad = 0.3;
var truePad = 1 - (1 - pad) / snapshotCount;
var xScale = d3.scale.ordinal()
.domain(_.map(categories, function(x, key) { return key; }))
.rangeBands([left, right-w0], truePad, 0);
//var nums = _.map(tests, function(val) { return val.elapsed / val.n; });
//var names = _.map(tests, function(val, name) { return name; });
var dataScale;
var yExtent = [0, svgHeight-50];
if (scale == "linear") {
dataScale = d3.scale.linear()
.domain([d3.max(values), 0])
.range(yExtent);
} else if (scale == "log10") {
dataScale = d3.scale.log()
.domain([d3.max(values), 0.01])
.range(yExtent);
}
var xOffset = 60;
var rectOffset = xOffset + 5;
for (var i = 0; i < snapshotCount; i++) {
// Go through the ith snapshot of each category
var sample = _.map(categories, function(snapshots, key) {
var val = snapshots[i];
return {cat: key, val: val.elapsed / val.n};
});
console.log(sample);
svg.append("g").selectAll("rect")
.data(sample)
.enter()
.append("rect")
.attr({
x: function(d) { return rectOffset+xScale(d.cat); },
y: function(d) { return dataScale(d.val); },
width: xScale.rangeBand(),
height: function(d) { return yExtent[1] - dataScale(d.val); },
fill: color_at(i),
});
rectOffset += xScale.rangeBand();
}
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate("+xOffset+"," + (svgHeight-45) + ")")
.call(xAxis)
.selectAll(".tick text")
.call(wordWrap, xScale.rangeBand());
var yAxis = d3.svg.axis()
.scale(dataScale)
.orient("left");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate("+xOffset+",0)")
.call(yAxis);
}
function wordWrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
var data = JSON.parse($("#json-data").html());
function make_tuple(size) {
var tuple = [];
for (var i = 0; i < size; i++) {
tuple.push(null);
}
return tuple;
}
var allTests = {};
var count = 0;
// loop over snapshots
_.each(data, function(dict, name) {
// loop tests
_.each(dict.tests, function(test) {
var modName = test["module"];
var testName = test["test"];
//var fullName = modName + "." + testName;
var fullName = testName;
if (!allTests[fullName]) {
allTests[fullName] = make_tuple(count);
}
var testCase = {
elapsed: test["elapsed"],
n: test["iter"],
};
allTests[fullName].push(testCase);
});
count++;
// fill missing snapshots
_.each(allTests, function(snapshots) {
while (snapshots.length < count) {
snapshots.push(null);
}
});
});
function redrawCharts(scale) {
$("h1").remove();
$("h2").remove();
$("svg").remove();
//add_chart(name, tests, scale);
add_comparison_chart("Snapshotting", allTests, scale);
}
$("#scale-selector").click(function() {
var scale = $(this).val();
redrawCharts(scale);
});
$(function() {
redrawCharts("linear");
});