Public
Edited
Mar 8, 2023
Insert cell
Insert cell
pctCircles(data, {
width: width,
threshold: threshold,
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function pctCircles (data, {
threshold = 0, // if zero will take circleCol[1] & textCol[1]
circleCol = ['#96bfe6', '#000831'], // colour of circle: [below, above] threshold
textCol = ['#000', '#fff'], // colour of circle text as above
width = 600, // width of svg without margins
domain = [d3.min(data, d => d.value), d3.max(data, d => d.value)], // domain e.g. [0, 100]
radius = 40, // radius of circle
lineCol = '#688e70', // background line colour connecting circles
height = 200, // svg height (without margins)
margin = {top: 5, right: radius * 2, bottom: 5, left: radius * 2} // svg margins/padding
} = {}) {

// set the dimensions and margins of the graph
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})`);
// have line for values
sel.append('line')
.attr('x1', 0)
.attr('y1', h / 2 )
.attr('x2', w)
.attr('y2', h / 2)
.attr('stroke', lineCol)
.attr('stroke-dasharray', 2);

// data join
const circle = sel.selectAll('g.pct')
.data(data)
.join('g')
.attr('class', 'pct')
.attr('transform', d => `translate(${xScale(d.value)},${h / 2})`);
// add circles
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}%`)

// for testing / ref
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;

}
Insert cell
Insert cell
Insert cell
<hr>
<link href="https://fonts.googleapis.com/css?family=Space+Mono" rel="stylesheet">
<style>
text {
font-family:'Space Mono',monospace;
}
</style>
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more