Failed to make an animated scatter plot with dropdown to select group

Viewed 37

I was making an animated scatter plot with dropdown to select group. The dataset I’m using is Biden’s 2022 satisfaction rate. However, I couldn’t make it works properly, as the video shows. I tried for a long time but still failed to figure the reasons out. My codes are below. Great appreciation if someone could help me. Thank you!

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>D3 Assignment</title>
        <script src="https://d3js.org/d3.v7.min.js"></script>

        <select id="selectButton"></select>

        <div id="BidenSatisfaction"></div>

    </head>

    <script>

        const margin = {top: 10, right: 100, bottom: 30, left: 30},
            width = 1500 - margin.left - margin.right,
            height = 600 - margin.top - margin.bottom;

        const svg = d3.select("#BidenSatisfaction")
                        .append("svg")
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom)
                        .append("g")
                        .attr("transform",`translate(${margin.left},${margin.top})`);

        d3.csv("approval_topline.csv").then(function(data){

            const allGroup = ["Approve", "Disapprove"]

            d3.select("#selectButton")
                .selectAll('myOptions')
                    .data(allGroup)
                .enter()
                    .append('option')
                .text(d => d)
                .attr("value", d => d)

            const x = d3.scaleTime()
                        .domain(d3.extent(data, function(d) { 
                            return new Date(d.Date); 
                        }))
                        .range([15, width]);
                        svg.append("g")
                        .attr("transform", `translate(0, ${height})`)
                        .call(d3.axisBottom(x));

            const y = d3.scaleLinear()
                        .domain( [30,60])
                        .range([ height, 20 ]);
                        svg.append("g")
                        .call(d3.axisLeft(y));

            const line = svg.append('g')
                            .append("path")
                                .datum(data)
                                .attr("d", d3.line()
                                .x(d => x(+new Date(d.Date)))
                                .y(d => y(+d.Approve))
                                )
                                .attr("stroke", "grey")
                                .style("stroke-width", 3)
                                .style("fill", "none")


            const dot = svg.selectAll('circle')
                            .data(data)
                            .join('circle')
                                .attr("cx", d => x(+new Date(d.Date)))
                                .attr("cy", d => y(+d.Approve))
                                .attr("r", 5)
                                .style("fill", "#69b3a2")


            function update(selectedGroup){
                const dataFilter = data.map(function(d){return {date:Date(d.Date), value:d[selectedGroup]} })
            
                line.datum(dataFilter)
                    .transition()
                    .duration(1000)
                    .attr("d", d3.line()
                        .x(d => x(+new Date(d.Date)))
                        .y(d => y(+d.value))
                    )                                
                dot.data(dataFilter)
                    .transition()
                    .duration(1000)
                    .attr("cx", d => x(+new Date(d.Date)))
                    .attr("cy", d => y(+d.value))

            }

            d3.select("#selectButton").on("change", function(event, d) {
                let selectedOption = d3.select(this).property("value")
                update(selectedOption)})

        })

    </script>

</html>
0 Answers
Related