Boxplot example, based on code by Elijah Meeks.
Built with blockbuilder.org
license: mit |
Boxplot example, based on code by Elijah Meeks.
Built with blockbuilder.org
// Boxplot code | |
d3.csv("box_data.csv", boxplot); | |
const tickSize = 470; | |
function boxplot(data) { | |
console.log(data); | |
const margin = {top: 25, right: 25, bottom: 25, left: 25}; | |
const height = 500 - margin.top - margin.bottom; | |
const width = 500 - margin.right - margin.left; | |
const svg = d3.select('body') | |
.append('svg') | |
.attr('width', width + margin.right + margin.left) | |
.attr('height', height + margin.top + margin.bottom) | |
.append('g') | |
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); | |
const maxSize = d3.max(data, d => d.number); | |
const xScale = d3.scaleLinear().domain([1, 8]).range([20, width]); | |
const yScale = d3.scaleLinear().domain([0, 100]).range([height, 20]); | |
const colScale = d3.scaleLinear() | |
.domain([0, maxSize]).range(colorbrewer.Blues[7]); | |
// Define axes | |
const yAxis = d3.axisRight().scale(yScale) | |
.ticks(8).tickSize(width); | |
svg.append('g') | |
.attr('id', 'yAxisG') | |
.call(yAxis); | |
const xAxis = d3.axisBottom().scale(xScale) | |
.tickSize(-height) | |
.tickValues([1,2,3,4,5,6,7]); | |
svg.append('g') | |
.attr('transform', 'translate(0,' + height + ')') | |
.attr('id', 'xAxisG') | |
.call(xAxis); | |
d3.select('#xAxisG > path.domain').style('display', 'none'); | |
svg.selectAll('g.box') | |
.data(data).enter() | |
.append('g') | |
.attr('class', 'box') | |
.attr('transform', d => 'translate(' + xScale(d.day) + ',' + yScale(d.median) + ')') | |
.each(function(d,i) { | |
d3.select(this) | |
//line for min/max | |
.append('line') | |
.attr('class', 'range') | |
.attr('x1', 0).attr('x2', 0) | |
.attr('y1', yScale(d.max) - yScale(d.median)) | |
.attr('y2', yScale(d.min) - yScale(d.median)) | |
.style('stroke', 'black') | |
.style('stroke-width', 4); | |
// tick at top of line | |
d3.select(this).append('line') | |
.attr('x1', -5).attr('x2', 5) | |
.attr('y1', yScale(d.max) - yScale(d.median)) | |
.attr('y2', yScale(d.max) - yScale(d.median)) | |
.style('stroke', 'black') | |
.style('stroke-width', 4) | |
d3.select(this).append('line') | |
.attr('x1', -5).attr('x2', 5) | |
.attr('y1', yScale(d.min) - yScale(d.median)) | |
.attr('y2', yScale(d.min) - yScale(d.median)) | |
.style('stroke', 'black') | |
.style('stroke-width', 4) | |
d3.select(this).append('rect') | |
.attr('x', -20) | |
.attr('y', yScale(d.q3) - yScale(d.median)) | |
.attr('width', 40) | |
.attr('height', yScale(d.q1) - yScale(d.q3)) | |
.attr('fill', colScale(d.number)) | |
.attr('stroke', 'black') | |
// add median line | |
d3.select(this).append('line') | |
.attr('x1', -20).attr('x2', 20) | |
.attr('y1', 0) | |
.attr('y2', 0) | |
.style('stroke', 'grey') | |
.style('stroke-width', 3); | |
}) | |
} |
day | min | max | median | q1 | q3 | number | |
---|---|---|---|---|---|---|---|
1 | 14 | 65 | 33 | 20 | 35 | 22 | |
2 | 25 | 73 | 25 | 25 | 30 | 170 | |
3 | 15 | 40 | 25 | 17 | 28 | 185 | |
4 | 18 | 55 | 33 | 28 | 42 | 135 | |
5 | 14 | 66 | 35 | 22 | 45 | 150 | |
6 | 22 | 70 | 34 | 28 | 42 | 170 | |
7 | 14 | 65 | 33 | 30 | 50 | 28 |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script> | |
<script src="http://d3js.org/colorbrewer.v1.min.js"></script> | |
</head> | |
<body> | |
<script src="box.js"></script> | |
</body> | |
</html> |