function semiCircles (data, {
f = d3.format(','),
margin = {top: 10, right: 50, bottom: 30, left: 50},
labelKey = 'label',
valueKey = 'value',
width = 900,
height = 350,
bgdColour= '#ffffff',
stroke = '#a36aa5',
fill = '#66629c',
textFill = ['#66629c', '#a36aa5'],
opacity = 0.9,
circleSizeMax = height/2
} = {}) {
const w = width - margin.left - margin.right
const h = height - margin.top - margin.bottom
const max = d3.max(data, d => d[valueKey]);
const center = height / 4;
const svg = DOM.svg(width, height);
const sel = d3.select(svg)
const g = sel.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const sqrtScale = d3.scaleSqrt()
.domain([0, max])
.range([0, circleSizeMax])
const linearScale = d3.scaleLinear()
.domain([0, data.length])
.range([(circleSizeMax/2), w]);
const groups = g.selectAll('g.g-sc')
.data(data)
.join('g')
.attr('class', 'g-sc')
.attr('transform', (d, i) => `translate(${linearScale(i)},${center})`);
groups.append('circle')
.attr('class', 'c-100')
.attr('r', d => sqrtScale(d[valueKey]))
.attr('fill', fill)
.attr('stroke', bgdColour)
.style('opacity', opacity)
.attr('stroke-width', 2);
g.append('rect')
.attr('x', margin.left * -1)
.attr('y', margin.top * -1)
.attr('height', center + margin.top)
.attr('width', width)
.attr('fill', bgdColour)
g.append('line')
.attr('x1', margin.left * -1 + 5)
.attr('x2', w - margin.right)
.attr('y1', center)
.attr('y2', center)
.attr('stroke', stroke)
.attr('stroke-linecap', 'round')
.attr('stroke-width', 4);
const groupsText = g.selectAll('g.g-text')
.data(data)
.join('g')
.attr('class', 'g-text')
.attr('transform', (d, i) => `translate(${linearScale(i)},${center})`);
groupsText.append('text')
.attr('x', 0)
.attr('dy', -30)
.style('fill', textFill[0])
.style('text-anchor', 'middle')
.text(d => d[labelKey]).raise()
groupsText.append('text')
.attr('x', 0)
.attr('dy', -10)
.style('fill', textFill[1])
.style('text-anchor', 'middle')
.style('font-weight', '600')
.text(d => f(d[valueKey]))
return svg;
}