function flowCircles (data, {
f = d3.format(','),
margin = {top: 10, right: 100, bottom: 30, left: 80},
labelKey = 'label',
valueKey = 'value',
width = 900,
height = 300,
stroke = '#454545',
fill = '#fff',
textFill = 'tomato',
circleSizeMax = 80
} = {}) {
const w = width - margin.left - margin.right
const h = height - margin.top - margin.bottom
const max = d3.max(data, d => d[valueKey]);
const center = (h + margin.top) / 2;
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, max])
.range([0, circleSizeMax])
const linearScale = d3.scaleLinear()
.domain([0, data.length])
.range([(circleSizeMax/2), width]);
sel.append('line')
.attr('x1', margin.left)
.attr('x2', w - 100)
.attr('y1', center)
.attr('y2', center)
.attr('stroke', stroke)
.style('stroke-dasharray', 2);
const groups = sel.selectAll('g.g-fc')
.data(data)
.join('g')
.attr('class', 'g-fc')
.attr('transform', (d, i) => `translate(${linearScale(i)},${(h + margin.top) / 2})`);
groups.append('circle')
.attr('class', 'c-100')
.attr('r', d => sqrtScale(d[valueKey]))
.attr('fill', fill)
.attr('stroke', stroke)
.style('stroke-dasharray', 2)
.attr('stroke-width', 2);
groups.append('text')
.attr('x', 0)
.attr('dy', 5)
.style('fill', textFill)
.style('text-anchor', 'middle')
.text(d => d[labelKey])
groups.append('text')
.attr('x', 0)
.attr('y', d => sqrtScale(d[valueKey]))
.attr('dy', 15)
.style('text-anchor', 'middle')
.text(d => f(d[valueKey]))
return svg;
}