{
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.style("background-color", svgBackgroundColor),
arcsContainer = svg.append("g")
.attr("transform", "translate(" + (width/2) + "," + (height/2) + ")"),
data = d3.range(numArcs).map(function(i) {
return {
id: i,
startAngle: Math.random() * tau,
endAngle: Math.random() * tau
};
});
function update(arcsData){
const t = d3.transition()
.duration(1050);
let arcs = arcsContainer.selectAll("path")
.data(arcsData, d => d.id);
arcs
.join(
enter => enter.append("path")
.style("opacity", 0)
.call(e => e.transition(t)
.attr("d", concentricArc)
.attr("stroke", d => arcColor)
.attr("stroke-width", (d,i) => randomInteger(3,concentricScale.bandwidth(), d.id))
.style("opacity", (d,i) => 1)
.attr("fill", arcColor)
),
update => update
.call(e => {e.transition(t)
.attrTween("d", d => {
let oldStartAngle = d.startAngle;
let oldEndAngle = d.endAngle;
let randomNewStart = Math.random() * tau;
let randomNewEnd = Math.random() * tau;
let i = d3.interpolate(oldStartAngle, randomNewStart);
let u = d3.interpolate(oldEndAngle,randomNewEnd);
return t => {
d.endAngle = u(t);
d.startAngle = i(t);
return concentricArc(d);
};
}
)
.attr("stroke-width", (d,i) => randomInteger(1,concentricScale.bandwidth(), d.id))
.style("opacity", (d,i) => randomInteger(5,9, d.id)/10)
}
)
)
}
yield svg.node();
update(data);
d3.interval(function() {
update(data)
}, 1200);
}