chart = {
const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, noSplitHeight + margin.top + margin.bottom]);
const wrapper = svg
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);
wrapper.append("g").call(xAxis);
const yAxisContainer = wrapper
.append("g")
.attr("transform", `translate(-10,0)`);
const circles = wrapper
.append("g")
.attr("className", "circles")
.selectAll("circle")
.data(games)
.join("circle")
.attr("r", (d) => r(d.runs))
.attr("fill", (d) => color(d.win_loss))
.attr("x", (d) => x(d.runs))
.attr("y", (d) => y(d.year) + y.bandwidth() / 2);
force.on("tick", () => {
circles
.transition()
.ease(d3.easeLinear)
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y);
});
invalidation.then(() => force.stop());
return Object.assign(svg.node(), {
update(split) {
let height = split ? splitHeight : noSplitHeight;
let years = [...yearGroups.keys()].sort();
const t = d3.transition().duration(750);
svg.transition(t).attr("viewBox", [0, 0, width, height]);
y.domain(split ? years : ["All"]);
y.range(
split
? [splitHeight - margin.top - margin.bottom, 0]
: [noSplitHeight - margin.top - margin.bottom, 0]
);
yAxisContainer
.call(yAxis, y, split ? years : ["All"])
.call((g) => g.select(".domain").remove())
.call((g) => g.selectAll(".tick line").remove());
force.force(
"y",
split
? d3.forceY((d) => y(d.year) + y.bandwidth() / 2)
: d3.forceY((noSplitHeight - margin.top - margin.bottom) / 2)
);
force.alpha(1).restart();
}
});
}