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 - 70)
.attr("y", d => groups[d].y)
.text(d => groups[d].fullname)
.attr("font-family", "Noto Sans KR")
.style("font-weight", "bold")
// .attr("font-size", width*0.02);
.attr("font-size", "1em");
// .attr("stroke", "#FFF")
// .attr("stroke-width", width*0.0005);
// Group counts
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 - 20)
.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");
// Forces
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);
// Adjust position (and color) of circles.
simulation.on("tick", () => {
circle
.attr("cx", d => d.x)
.attr("cy", d => d.y);
// .attr("fill", d => groups[d.group].color);
});
// Make time pass. Adjust node stage as necessary.
function timer() {
nodes.forEach(function (o, i) {
o.timeleft -= 1;
if (o.timeleft == 0 && o.istage < o.stages.length - 1) {
// Decrease count for previous group.
groups[o.group].cnt -= 1;
// Update current node to new group.
o.istage += 1;
o.group = o.stages[o.istage].grp; // grp FROM CSV?
o.timeleft = o.stages[o.istage].duration; // HERE IS DURATION
// Increment count for new group.
groups[o.group].cnt += 1;
}
});
// Increment time.
time_so_far += 1;
d3.select("#timecount .cnt").text(time_so_far);
// Update counters.
svg.selectAll('.grpcnt').text(d => d3.format(".1f")(groups[d].cnt)/10);
// svg.selectAll('.grpcnt').text(d => groups[d].cnt);
// Do it again.
// d3.timeout(timer, 500);
d3.timeout(timer, 100);
} // @end timer()
// Start things off after a few seconds.
d3.timeout(timer, 1000);
return svg.node()
}