block by jwilber 3a2dd8757714399bd0a5a6aa64547cbb

boxplot

Full Screen

Boxplot example, based on code by Elijah Meeks.

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<html>
<head>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script>
	<script src="//d3js.org/colorbrewer.v1.min.js"></script>
</head>
<body>

	<script src="box.js"></script>
</body>
</html>

box.js

// 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);
		})


}

box_data.csv

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