viewof chart = {
const svg = d3.select(DOM.svg(width, height));
svg.append('rect')
.attr('class', 'bg')
.attr('width', width)
.attr('height', height)
.attr('fill', '#999');
const minValue = Math.min(...config.sections.map(d => d.from));
const maxValue = Math.max(...config.sections.map(d => d.to));
const scale = d3.scaleLinear()
.domain([minValue, maxValue])
.range([
config.panel.startAngle,
config.panel.endAngle
]);
const radius = Math.floor(Math.max(width, height) / 2) - 2;
const arc = d3.arc()
.outerRadius(radius)
.innerRadius(radius - config.panel.width);
const inner = svg
.append('g')
.attr('transform', `translate(${width/2},${height/2})`);
const needle = inner
.append('g')
.attr('class', 'needle')
.attr('fill', '#fff')
.call(s => s
.append('circle')
.attr('r', 9)
)
.call(s => s
.append('rect')
.attr('x', -2)
.attr('y', -height * .35)
.attr('width', 4)
.attr('height', height * .35)
)
.attr('transform', `rotate(scale(0))`)
.transition()
.ease(d3.easeElastic.amplitude(.25).period(1))
.duration(1000)
.attr('transform', `rotate(${scale(Math.random() * maxValue)})`);
inner
.selectAll('path.arc')
.data(config.sections)
.join('path')
.attr('class', 'arc')
.attr('d', d => arc({
startAngle: deg2rad(scale(d.from)),
endAngle: deg2rad(scale(d.to))
}))
.attr('fill', d => d.color)
.attr('stroke', '#fff')
.attr('stroke-width', '2px');
return svg.node();
}