calcPoints = (data) => {
const perRow = 3
const numRows = Math.ceil(currentData.houseRep / perRow)
const perWidth = 100
const xScale = d3.scaleBand().domain([0, 1, 2]).range([0, perWidth])
const yScale = d3.scalePoint().domain(_.range(numRows))
.range([height - margin.bottom, height - margin.bottom - xScale.bandwidth() * numRows])
return _.chain(data)
.groupBy(d => `${d.legislature}, ${d.favored}`)
.sortBy(([{legislature, favored}]) => 2 * (legislature === 'HD') + (favored === 'R'))
.map((seats, offset) => {
const points = _.chain(seats)
.sortBy(({confidence}) => confidenceOrder.indexOf(confidence))
.map(({confidence, favored}, i) => {
confidence = confidenceMap[confidence]
const color = favored === 'D' ? 'blue' : 'red'
let fill, stroke, pattern
if (confidence === 'Closed') {
fill = colors[color]
pattern = false
} else if (confidence === 'Safe') {
fill = chroma(colors[color]).alpha(0.25).css(),
stroke = colors.gray
pattern = false
} else if (confidence === 'Likely') {
fill = color
stroke = colors.gray
pattern = 'thicker'
} else if (confidence === 'Lean') {
fill = color
stroke = colors.gray
pattern = 'thinner'
} else if (confidence === 'Toss-Up') {
fill = 'gray'
stroke = colors.gray
pattern = 'thinner'
}
return {
fill, stroke, pattern,
x: xScale(i % perRow),
y: yScale(Math.floor(i / perRow)),
radius: Math.floor(xScale.bandwidth() * 0.7),
}
}).value()
return {
x: margin.left + offset * perWidth,
points,
}
}).value()
}