chart = {
const svg = d3.select(DOM.svg(width, height))
.attr("viewBox", "0 0 " + (width) + " " + (height))
.attr("preserveAspectRatio", "xMidYMid meet");
const wrapper = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ") rotate(75)");
let matrix = updateMatrix();
let chord = chordGenerator(matrix);
reorderChord(chord);
const grads = svg.append("defs")
.selectAll("linearGradient")
.data(chord)
.enter()
.append("linearGradient")
.attr("id", getGradID)
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", function(d, i){ return innerRadius * Math.cos((d.source.endAngle-d.source.startAngle) / 2 + d.source.startAngle - Math.PI/2); })
.attr("y1", function(d, i){ return innerRadius * Math.sin((d.source.endAngle-d.source.startAngle) / 2 + d.source.startAngle - Math.PI/2); })
.attr("x2", function(d,i){ return innerRadius * Math.cos((d.target.endAngle-d.target.startAngle) / 2 + d.target.startAngle - Math.PI/2); })
.attr("y2", function(d,i){ return innerRadius * Math.sin((d.target.endAngle-d.target.startAngle) / 2 + d.target.startAngle - Math.PI/2); });
grads.append("stop")
.attr("offset", "0%")
.attr("stop-color", function(d){ return color(d.source.index)});
grads.append("stop")
.attr("offset", "100%")
.attr("stop-color", function(d){ return color(d.target.index)});
const chords = wrapper.selectAll("path")
.data(chord)
.enter()
.append("path")
.attr("class", function(d) {
return "chord chord-" + d.source.index + " chord-" + d.target.index
})
.style("fill", function(d){ return "url(#" + getGradID(d) + ")"; })
.transition()
.duration(2000)
.attr("d", ribbon);
// make arcs
const g = wrapper.selectAll("g")
.data(chord.groups)
.enter()
.append("g")
.attr("class", "group");
g.append("path")
.style("fill", function(d){ return color(d.index)})
.attr("class", "arc")
.style("opacity", 1)
.transition()
.duration(2000)
.attr("d", arcs);
while (true) {
matrix = updateMatrix();
chord = chordGenerator(matrix);
reorderChord(chord);
svg.selectAll("linearGradient")
.data(chord)
.transition()
.duration(2000)
.attr("x1", function(d, i){ return innerRadius * Math.cos((d.source.endAngle-d.source.startAngle) / 2 + d.source.startAngle - Math.PI/2); })
.attr("y1", function(d, i){ return innerRadius * Math.sin((d.source.endAngle-d.source.startAngle) / 2 + d.source.startAngle - Math.PI/2); })
.attr("x2", function(d,i){ return innerRadius * Math.cos((d.target.endAngle-d.target.startAngle) / 2 + d.target.startAngle - Math.PI/2); })
.attr("y2", function(d,i){ return innerRadius * Math.sin((d.target.endAngle-d.target.startAngle) / 2 + d.target.startAngle - Math.PI/2); });
svg.selectAll(".chord")
.data(chord)
.transition()
.duration(2000)
.attr("d", ribbon);
svg.selectAll(".arc")
.data(chord.groups)
.transition()
.duration(2000)
.attr("d", arcs);
yield svg.node();
await Promises.tick(2000);
}
}