Skip to content

Instantly share code, notes, and snippets.

@joyeecheung
Last active April 13, 2017 06:44
Show Gist options
  • Save joyeecheung/5e048a02dfa84dd188403faa34f997cd to your computer and use it in GitHub Desktop.
Save joyeecheung/5e048a02dfa84dd188403faa34f997cd to your computer and use it in GitHub Desktop.
egg benchmark plots
<!DOCTYPE html>
<style>
.axis .domain {
display: none;
}
</style>
<svg width="1200" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="./plot.js"></script>
/* globals d3 */
'use strict';
d3.csv('./stats.csv', function(d) {
return {
config: d.config,
name: d.name,
req_per_sec: +d.req_per_sec,
byte_per_sec: +d.byte_per_sec / 1024,
};
}, function(error, data) {
if (error) throw error;
const svg = d3.select('svg');
const margin = { top: 20, right: 20, bottom: 30, left: 40 };
const width = +svg.attr('width') - margin.left - margin.right;
const height = +svg.attr('height') - margin.top - margin.bottom;
const canvas = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
const groupX = d3.scaleBand()
.rangeRound([ 0, width ])
.paddingInner(0.2);
const barX = d3.scaleBand()
.padding(0.1);
const y = d3.scaleLinear()
.rangeRound([ height, 0 ]);
const z = d3.scaleOrdinal()
.range([ '#00bcd4', '#ffc107' ]);
const groupKeys = Array.from(new Set(data.map(d => d.name)));
const valueKeys = [ 'req_per_sec', 'byte_per_sec' ];
const configKeys = Array.from(new Set(data.map(d => d.config)));
const barKeys = [];
for (const v of valueKeys) {
for (const b of configKeys) {
barKeys.push(`${v}:${b}`);
}
}
groupX.domain(groupKeys);
barX.domain(barKeys).rangeRound([ 0, groupX.bandwidth() ]);
const maxY = d3.max(data, d => d3.max(valueKeys, key => d[key]));
y.domain([ 0, maxY ]).nice();
const nested = d3.nest().key(d => d.name).entries(data);
const groups = canvas.append('g')
.selectAll('g')
.data(nested)
.enter()
.append('g');
const bars = groups
.attr('transform', d => `translate(${groupX(d.key)}, 0)`)
.selectAll('rect')
.data(function(d) {
const values = d.values;
const result = [];
for (const item of values) {
for (const v of valueKeys) {
result.push({
config: item.config,
name: item.name,
key: v,
value: item[v],
});
}
}
return result;
})
.enter()
.append('rect');
bars
.attr('x', d => barX(`${d.key}:${d.config}`))
.attr('y', d => y(d.value))
.attr('width', barX.bandwidth())
.attr('height', d => height - y(d.value))
.attr('fill', d => z(d.config));
canvas.append('g')
.attr('class', 'axis')
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom(groupX));
canvas.append('g')
.attr('class', 'axis')
.call(d3.axisLeft(y).ticks(null, 's'))
.append('text')
.attr('x', 2)
.attr('y', y(y.ticks().pop()) + 0.5)
.attr('dy', '0.32em')
.attr('fill', '#000')
.attr('font-weight', 'bold')
.attr('text-anchor', 'start')
.text('Value');
const legend = canvas.append('g')
.attr('font-family', 'sans-serif')
.attr('font-size', 10)
.attr('text-anchor', 'end')
.selectAll('g')
.data(configKeys.slice().reverse())
.enter()
.append('g');
legend
.attr('transform', (d, i) => `translate(0, ${i * 20})`);
legend.append('rect')
.attr('x', width - 19)
.attr('width', 19)
.attr('height', 19)
.attr('fill', z);
legend.append('text')
.attr('x', width - 24)
.attr('y', 9.5)
.attr('dy', '0.32em')
.text(d => d);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment