demo = {
const root = d3.select(DOM.svg(W, H))
root
.append('g')
.attr('class', 'plots')
const rand = d3.randomNormal()
const dataset = d3.range(8).map(function(n) {
return d3.range(30).map(_ => parseInt(rand() * 100) / 100 + n * 0.1).sort(d3.ascending)
})
const stats = dataset.map(function(d) {return d3.boxplotStats(d);})
const vertical = options.indexOf('vertical') !== -1
const colors = d3.schemeCategory10
const scale = d3.scaleLinear()
.domain([-4, +4])
.range(vertical ? [H - M.T - M.B, M.T] : [M.L, W - M.L - M.R])
const band = d3.scaleBand()
.domain(d3.range(stats.length))
.range(vertical ? [M.L, W - M.L - M.R] : [M.T, H - M.T - M.B])
.paddingInner(options.includes('minimalStyle') ? 0 : 0.3)
.paddingOuter(options.includes('minimalStyle') ? 2 : 0.2)
const plot = d3.boxplot()
.scale(scale)
.jitter(jitter)
.opacity(opacity)
.showInnerDots(options.includes('showInnerDots'))
.symbol(options.includes('useSymbolTick') ? d3.boxplotSymbolTick : d3.boxplotSymbolDot)
.bandwidth(band.bandwidth())
.boxwidth(options.includes('minimalStyle') ? 6 : band.bandwidth())
.vertical(vertical)
.key(d => d)
root.select('g.plots')
.attr('transform', 'translate(' + [M.L, M.T] + ')')
.selectAll('.plot').data(stats)
.join('g')
.attr('class', 'plot')
.attr('transform', (_, i) => `translate(${vertical ? [band(i), 0] : [0, band(i)]})`)
.attr('color', (_, i) => options.includes('color') ? colors[i / 2|0] : '#000')
.call(plot)
return root.node()
}