{
const barHeight = 75
const render = _.map([
{color: 'orange', data: _.values(rejectedData), height: barHeight},
{color: 'orange', data: _.sortBy(_.values(otherData), d => -d.sum), height: barHeight},
{color: 'green', data: _.values(totalData).reverse(), height: barHeight},
], ({color, height, data}) => {
let x = margin.left
return _.map(data, ({label, sum}) => {
return {
x1: x, x2: x += widthScale(sum),
color, height,
text: `${label} ${d3.format(',')(sum)}`,
}
})
})
const svg = d3.select(DOM.svg(width, height))
const patterns = _.reduce(_.keys(colors), (obj, color) => {
obj[color] = textures
.lines()
.heavier()
.stroke(colors[color])
svg.call(obj[color])
return obj
}, {})
const parts = svg.selectAll('g')
.data(render).join('g')
.attr('transform', (d, i) => `translate(0, ${i * 1.5 * barHeight + margin.top})`)
const bars = parts.selectAll('g')
.data(d => d).join('g')
.attr('transform', d => `translate(${d.x1}, 0)`)
bars.append('rect')
.attr('width', d => d.x2 - d.x1)
.attr('height', d => d.height)
.attr('fill', d => patterns[d.color].url())
.attr('stroke', '#fff')
.attr('stroke-width', 3)
bars.append('text')
.attr('y', d => d.height / 2)
.text(d => d.text)
return svg.node()
}