function concentricPctLines (datum, {
bind = null,
margin = {top: 10, right: 10, bottom: 30, left: 10},
circleSize = 100,
width = (circleSize * 2) + (margin.left + margin.right),
height = circleSize * 1.8 + (margin.top + margin.bottom),
modulus = 5,
col = {
active: '#1b3644',
passive: '#ffa6d9'
},
strokeWidth = 1,
domain = [0, 100],
range = [0, circleSize],
scaleSqrt = true
} = {}) {
const w = width - margin.left - margin.right
const h = height - margin.top - margin.bottom
bind.selectAll('svg').remove();
const sel = bind.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const scale = (scaleSqrt)? d3.scaleSqrt() : d3.scaleLinear();
scale.domain(domain).range(range);
const r = scale(circleSize);
const translate = `translate(${width / 2},${(height - margin.bottom) / 2 })`;
const passive = sel.append('g')
.attr('class', 'g-passive-wrap')
.attr('transform', translate);
const active = sel.append('g')
.attr('class', 'g-active-wrap')
.attr('transform', translate);
passive.selectAll('circle')
.data(d3.range(domain[1]))
.join('circle')
.attr('r', d => {
if ((d % modulus) == 0){
return scale(d + 1)
} else {
return 0
}
})
.attr('fill', 'transparent')
.attr('stroke', col.passive)
.style('opacity', 0.4)
.attr('stroke-width', strokeWidth);
active.selectAll('circle')
.data(d3.range(datum))
.join('circle')
.attr('r', d => {
if ((d % modulus) == 0){
return scale(d + 1)
} else {
return 0
}
})
.attr('fill', 'transparent')
.attr('stroke', col.active)
.attr('stroke-width', strokeWidth);
active.append('text')
.attr('class', 'percent-label')
.attr('y', r)
.attr('dy', 15)
.style('text-anchor', 'middle')
.text(datum + '%');
return sel;
}