chartGSAPTween = {
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto; height: intrinsic;")
svg.append("g")
.attr("id", "chart-container")
.attr("stroke", "none")
.attr("stroke-width", 2)
.selectAll("circle")
.data(data.filter(d => d.Year == 1950))
.join("circle")
.attr("class", "animated_circles")
.attr("cx", d => xScale(d.female))
.attr("cy", d => yScale(d.male))
.attr("opacity", 0.5)
.attr("r", 10)
.attr("fill", d => d.female > 60 && d.male > 60 ? "#B3806D": "#FCCE7C")
const yAxis = d3.axisLeft(yScale).ticks(height / 50)
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(yAxis)
.call(g => g.select(".domain").remove())
.call(g => g.selectAll(".tick line").clone()
.attr("x2", width - marginLeft - marginRight)
.attr("stroke-opacity", 0.1))
.call(g => g.append("text")
.attr("x", -marginLeft)
.attr("y", 10)
.attr("fill", "currentColor")
.attr("text-anchor", "start"))
const timeline = gsap.timeline()
timeline
.to(svg.node().querySelectorAll('circle.animated_circles'),{
cx: (i, target) => {
return 2 * i + 1 <= 406 ? xScale(data[i * 2 + 1].female):null
},
cy: (i) => 2 * i + 1 <= 406 ? yScale(data[i * 2 + 1].male):null,
fill: (i) => data[i * 2 + 1].female > 60 && data[i * 2 + 1].male > 60 ? "#B3806D": "#FCCE7C",
duration: 2,
yoyo: true,
repeat: -1
})
return svg.node()
}