function concentricPair (data, {
f = d3.format('.1f'),
margin = {top: 10, right: 100, bottom: 30, left: 80},
label = null,
groupOne = 'g1',
groupTwo = 'g2',
circleSize = 60,
width = (circleSize * 2) * data.length + (margin.left + margin.right),
height = circleSize * 2.5 + (margin.top + margin.bottom),
groupOnePrefix = 'G1:',
groupTwoPrefix = 'G2:',
col = {
g1: '#0024cc',
g2: '#fa9442'
}
} = {}) {
const w = width - margin.left - margin.right
const h = height - margin.top - margin.bottom
const svg = DOM.svg(width, height);
const sel = d3.select(svg)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const sqrtScale = d3.scaleSqrt()
.domain([0, 100])
.range([0, circleSize])
const linearScale = d3.scaleLinear()
.domain([0, data.length])
.range([0, width]);
const r = sqrtScale(100);
const groups = sel.selectAll('g.g-cc')
.data(data)
.join('g')
.attr('class', 'g-cc')
.attr('transform', (d, i) => `translate(${linearScale(i)},${height / 2})`);
// base circle(s)
groups.append('circle')
.attr('class', 'c-100')
.attr('r', d => sqrtScale(100))
.attr('fill', 'transparent')
.attr('stroke', '#ccc')
.style('stroke-dasharray', 4)
.attr('stroke-width', 2);
// group one circles
groups.append('circle')
.attr('class', 'c-male')
.attr('r', d => sqrtScale(d[groupOne]))
.attr('fill', 'transparent')
.attr('stroke', col.g1)
.attr('stroke-width', 4);
// group two circle(s)
groups.append('circle')
.attr('class', 'c-female')
.attr('r', d => sqrtScale(d[groupTwo]))
.attr('fill', 'transparent')
.attr('stroke', col.g2)
.attr('stroke-width', 4);
if (label !== null) {
// render group labels
groups.append('text')
.attr('class', 'area-label')
.attr('dy', 5)
.style('text-anchor', 'middle')
.text(d => d[label]);
}
// render group figures
groups.append('text')
.attr('class', 'percent-label')
.attr('y', (r + 25) * -1)
// .attr('dy', 5)
.style('text-anchor', 'end')
.style('fill', '#ccc')
.text(d => {
return `${groupTwoPrefix} ${f(d[groupTwo])}%`
});
groups.append('text')
.attr('class', 'percent-label')
.attr('y', (r + 15) * -1)
.attr('dy', 5)
.style('text-anchor', 'end')
.style('fill', '#ccc')
.text(d => {
return `${groupOnePrefix} ${f(d[groupOne])}%`
});
// show diff
groups.append('text')
.attr('class', 'percent-label')
.attr('y', r + 15)
.attr('dy', 5)
.style('text-anchor', 'end')
.style('fill', d => {
if (d[groupOne] > d[groupTwo]) {
return col.g2
} else {
return '#454545'
}
})
.text(d => {
const one = d[groupOne]
const two = d[groupTwo]
if (one > two) {
return `Diff: ${f(one - two)}%`
} else {
return `Diff: ${f(two - one)}%`
}
});
return svg;
}