{
const svgBackgroundColor = "#163C3C",
fontFamily = 'helvetica',
svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.style("background-color", svgBackgroundColor),
bigContainer = svg.append("g")
.attr("transform", `translate(${width/2},${height/2})`),
container = bigContainer.append("g"),
circlesContainer = bigContainer.append("g");
function update(data,concentricData,count){
const t = d3.transition()
.duration(1500);
let labels = container
.selectAll("g")
.data(data, d=>d.bar);
labels.join(
enter => {
let root = enter.append("g");
root.append("path")
.attr("class", "textPath")
.attr('id', d => `arc${d.bar}`)
.attr('d', labelArc)
.attr("stroke", "transparent")
.attr("fill", "none"),
root.append("text")
.attr("dy", 6)
.append("textPath")
.attr("xlink:href", d => `#arc${d.bar}`)
.style("fill", "red")
.style("text-anchor", "middle")
.attr("startOffset", "15%")
.attr("class", "labelText")
.attr("font-size", ".5em")
.attr("font-weight", "bold")
.attr("font-family", fontFamily)
.text(d => d.bar)
},
update => {
update.call(e => {
e.select("path").transition(t)
.attrTween("d", d => {
let oldEndAngle = d.labelEndAngle;
let oldStartAngle = d.labelStartAngle;
let i = d3.interpolate(oldStartAngle, (x(d.bar)) );
let u = d3.interpolate(oldEndAngle,(x(d.bar) + x.bandwidth()));
return t => {
d.labelEndAngle = u(t);
d.labelStartAngle = i(t);
return labelArc(d)};
}
)
}
)
},
exit => exit.remove()
)//end join
let bars = container
.selectAll(".barPath")
.data(data, d=>d.bar);
bars.join(
enter =>
enter.append("path")
.attr("class", "barPath")
.attr("fill", "#69b3a2")
.attr("opacity", 0.3)
.attr("d", arc)
,
update => update
.call(e => e.transition(t)
.attrTween("d", d => {
let oldEndAngle = d.endAngle;
let oldStartAngle = d.startAngle;
let i = d3.interpolate(oldStartAngle, x(d.bar));
let u = d3.interpolate(oldEndAngle,
x(d.bar) + x.bandwidth());
return t => {
d.endAngle = u(t);
d.startAngle = i(t);
return arc(d)
};
}
)
),
exit => exit.remove()
)
let circles = circlesContainer
.selectAll("circle")
.data(concentricData, d => d.id);
circles
.join(
enter => enter.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", d => d.radius)
.attr("stroke", "red")
.attr("stroke-width", 2)
.attr("fill", "none"),
update => update.call(e => e.transition(t)
.attr("stroke-width", (d,i) => sineScaleLineWidth(Math.sin(count*d.id) *concentricScale.bandwidth()))//randomInteger(2,concentricScale.bandwidth(), d.id))
.style("opacity", (d,i) => sineScale(Math.sin(count * d.id)))//randomInteger(2,9, d.id)/10)
)
)
}
update(data,concentricCircleData);
yield svg.node();
let count = 0;
d3.interval(() => {
//alternate between sorting and shuffling the data
count % 2 == 0 ? d3.shuffle(data) : data.sort((a,b) => a.bar - b.bar)
//update the order of the data in the scale for correct bar + label placement
let newDomain = data.map(d => d.bar);
x.domain(newDomain);
update(data,concentricCircleData,count);
count ++
}, 1500);
}