Skip to content

Instantly share code, notes, and snippets.

@micahstubbs
Last active October 28, 2018 20:52
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save micahstubbs/98d8b4eba987224e3c84 to your computer and use it in GitHub Desktop.
horizontal boxplot
license: Apache-2.0
border: no
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>
<title>horizontal boxplot</title>
<meta charset="utf-8" />
<style>
/* svg {
border: 1px solid gray;
}*/
line {
shape-rendering: crispEdges;
stroke: #000000;
}
line.minor {
stroke: #777777;
stroke-dasharray: 2,2;
}
path.domain {
fill: none;
stroke: black;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js" type="text/JavaScript"></script>
<script src='./index.js'></script>
</body>
</html>
d3.csv('data.csv').then(data => boxplot(data))
function boxplot(data) {
// setup the plot area
const h = 500
const w = 500
const margin = {
top: 20,
bottom: 20,
left: 20,
right: 30
}
d3.select('body')
.append('svg')
.attr('height', h)
.attr('width', w)
//
// map variables in the data to types
//
// categorical variable
const catVariable = 'day'
const catValues = data.map(d => Number(d[catVariable]))
// numeric variable statistics
const minVariable = 'min'
const maxVariable = 'max'
const medianVariable = 'median'
const q1Variable = 'q1'
const q3Variable = 'q3'
// define the scales
xScale = d3
.scaleLinear()
.domain([0, 100]) // 0% to 100%
.range([margin.left, w - margin.right])
yScale = d3
.scaleLinear()
.domain([
Number(d3.max(data, d => d[catVariable])) + 1,
Number(d3.min(data, d => d[catVariable])) - 1
])
.range([h - margin.bottom, margin.top])
console.log(data)
// setup the axes
xAxis = d3
.axisBottom()
.scale(xScale)
.ticks(10)
.tickSize(-470)
d3.select('svg')
.append('g')
.attr('transform', 'translate(0,480)')
.attr('id', 'xAxisG')
.call(xAxis)
yAxis = d3
.axisRight()
.scale(yScale)
.tickSize(-470)
.tickValues(catValues)
d3.select('svg')
.append('g')
.attr('transform', 'translate(470,0)')
.attr('id', 'yAxisG')
.call(yAxis)
d3.select('svg')
.selectAll('g.box')
.data(data)
.enter()
.append('g')
.attr('class', 'box')
.attr(
'transform',
d => `translate(${xScale(d[medianVariable])},${yScale(d[catVariable])})`
)
.each(function(d, i) {
d3.select(this)
.append('line')
.attr('class', 'range')
.attr('x1', xScale(d[maxVariable]) - xScale(d[medianVariable]))
.attr('x2', xScale(d[minVariable]) - xScale(d[medianVariable]))
.attr('y1', 0)
.attr('y2', 0)
.style('stroke', 'black')
.style('stroke-width', '4px')
d3.select(this)
.append('line')
.attr('class', 'max')
.attr('x1', xScale(d[maxVariable]) - xScale(d[medianVariable]))
.attr('x2', xScale(d[maxVariable]) - xScale(d[medianVariable]))
.attr('y1', -10)
.attr('y2', 10)
.style('stroke', 'black')
.style('stroke-width', '4px')
d3.select(this)
.append('line')
.attr('class', 'min')
.attr('x1', xScale(d[minVariable]) - xScale(d[medianVariable]))
.attr('x2', xScale(d[minVariable]) - xScale(d[medianVariable]))
.attr('y1', -10)
.attr('y2', 10)
.style('stroke', 'black')
.style('stroke-width', '4px')
d3.select(this)
.append('rect')
.attr('class', 'range')
.attr('x', xScale(d[q1Variable]) - xScale(d[medianVariable]))
.attr('y', -10)
.attr('height', 20)
.attr('width', xScale(d[q3Variable]) - xScale(d[q1Variable]))
.style('fill', 'white')
.style('stroke', 'black')
.style('stroke-width', '2px')
d3.select(this)
.append('line')
.attr('x1', 0)
.attr('x2', 0)
.attr('y1', -10)
.attr('y2', 10)
.style('stroke', 'darkgray')
.style('stroke-width', '4px')
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment