function pctCircles (data, {
threshold = 0,
circleCol = ['#96bfe6', '#000831'],
textCol = ['#000', '#fff'],
width = 600,
domain = [d3.min(data, d => d.value), d3.max(data, d => d.value)],
radius = 40,
lineCol = '#688e70',
height = 200,
margin = {top: 5, right: radius * 2, bottom: 5, left: radius * 2}
} = {}) {
const w = width - margin.left - margin.right
const h = height - margin.top - margin.bottom
const xScale = d3.scaleLinear()
.domain(domain)
.range([0, w])
const svg = DOM.svg(width, height);
const sel = d3.select(svg)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
sel.append('line')
.attr('x1', 0)
.attr('y1', h / 2 )
.attr('x2', w)
.attr('y2', h / 2)
.attr('stroke', lineCol)
.attr('stroke-dasharray', 2);
const circle = sel.selectAll('g.pct')
.data(data)
.join('g')
.attr('class', 'pct')
.attr('transform', d => `translate(${xScale(d.value)},${h / 2})`);
circle.append('circle')
.attr('fill', d => (d.value >= threshold) ? circleCol[1] : circleCol[0] )
.attr('r', radius)
.attr('stroke', '#fff')
.style('opacity', 0.9);
circle.append('text')
.attr('dx', 3)
.attr('y', `${radius * 0.2}`)
.attr('font-size', `${radius * 0.7}px`)
.attr('text-anchor', 'middle')
.attr('fill', d => (d.value >= threshold) ? textCol[1] : textCol[1] )
.text(d => `${d.value}%`)
circle.append('text')
.attr('dx', 3)
.attr('y', `${radius * 1.8}`)
.attr('font-size', '11px')
.style('letter-spacing', '4px')
.attr('text-anchor', 'middle')
.attr('fill', '#ccc' )
.text(d => `${d.label}`)
return svg;
}