chart = {
let time_so_far = 300;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
const title = svg.append('g');
title.append('g')
.call(addTitle, '민주당 대통령 후보 경선 결과 종합');
const circle = svg.append("g")
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("fill", d => d.color);
circle
.transition()
.delay((d, i) => i)
.duration(0.1)
.attrTween("r", d => {
const i = d3.interpolate(0, d.r);
return t => d.r = i(t);
});
svg.selectAll('.grp')
.data(d3.keys(groups))
.join("text")
.attr("class", "grp")
.attr("text-anchor", "middle")
.attr("x", d => groups[d].x)
.attr("y", d => groups[d].y)
.text(d => groups[d].fullname)
.attr("font-family", "Noto Sans KR")
.style("font-weight", "bold")
.attr("font-size", "1em");
svg.selectAll('.grpcnt')
.data(d3.keys(groups))
.join("text")
.attr("class", "grpcnt")
.attr("text-anchor", "middle")
.attr("x", d => groups[d].x)
.attr("y", d => groups[d].y+15)
.text(d => d3.format(".1f")((groups[d].cnt)/10))
.style("font-weight", "bold")
.attr("font-size", "0.9em");
const simulation = d3.forceSimulation(nodes)
.force("x", d => d3.forceX(d.x))
.force("y", d => d3.forceY(d.y))
.force("cluster", forceCluster())
.force("collide", forceCollide())
.alpha(.09)
.alphaDecay(0);
simulation.on("tick", () => {
circle
.attr("cx", d => d.x)
.attr("cy", d => d.y);
});
function timer() {
nodes.forEach(function (o, i) {
o.timeleft -= 1;
if (o.timeleft == 0 && o.istage < o.stages.length - 1) {
groups[o.group].cnt -= 1;
o.istage += 1;
o.group = o.stages[o.istage].grp;
o.timeleft = o.stages[o.istage].duration;
groups[o.group].cnt += 1;
}
});
time_so_far += 1;
d3.select("#timecount .cnt").text(time_so_far);
svg.selectAll('.grpcnt').text(d => d3.format(".1f")(groups[d].cnt)/10);
d3.timeout(timer, 100);
}
d3.timeout(timer, 1000);
return svg.node()
}