boxplot = (g) => {
g.append("line")
.attr("class", "guide")
.attr("x1", bandwidth / 2)
.attr("y1", (d) => y(d.min))
.attr("x2", bandwidth / 2)
.attr("y2", (d) => y(d.max))
.attr("stroke", "steelblue");
g.append("line")
.attr("class", "whisker")
.attr("x1", bandwidth / 2)
.attr("y1", (d) => y(d.range[1]))
.attr("x2", bandwidth / 2)
.attr("y2", (d) => y(d.range[0]))
.attr("stroke", "green");
g.append("line")
.attr("class", "range-bot")
.attr("x1", 0)
.attr("y1", (d) => y(d.range[0]))
.attr("x2", bandwidth)
.attr("y2", (d) => y(d.range[0]))
.attr("stroke", "steelblue");
g.append("line")
.attr("class", "range-bot")
.attr("x1", 0)
.attr("y1", (d) => y(d.range[1]))
.attr("x2", bandwidth)
.attr("y2", (d) => y(d.range[1]))
.attr("stroke", "steelblue");
g.append("path")
.attr("class", "quartile")
.attr("d", (d) => `M0,${ y(d.quartiles[2]) }h${ bandwidth }V${ y(d.quartiles[0]) }H0Z`)
.attr("data-tooltip", (d) => quartileTooltip(d))
.attr("data-pid", (d) => d.pid)
.on("mouseover", onMouseOverQuartile)
.on("mousemove", onMouseMoveQuartile)
.on("mouseout", onMouseOutQuartile);
g.append("line")
.attr("class", "median")
.attr("x1", 0)
.attr("y1", (d) => y(d.quartiles[1]))
.attr("x2", bandwidth)
.attr("y2", (d) => y(d.quartiles[1]));
g.selectAll('.outlier')
.data(d => d.outliers)
.enter()
.append('circle')
.attr('class', 'outlier')
.attr('r', 3)
.attr('cx', (d, i) => {
return (bandwidth/2) + offsets[i%6];
})
.attr('cy', (d) => y(d['usd_goal_real']))
.attr("data-tooltip", (d) => title(d))
.attr("data-pid", (d) => d['ID'])
.on("mouseover", onMouseOverOutlier)
.on("mousemove", onMouseMoveOutlier)
.on("mouseout", onMouseOutOutlier);
}