Member 13620781 Ответов: 0

Как удалить предыдущую строку после изменения значения выпадающего списка?


Я попытался создать многострочный график с выпадающим меню. График должен изменяться в соответствии с данными для выбранного значения в выпадающем меню. В настоящее время точка на линейном графике может изменяться в соответствии со значением в выпадающем меню, но предыдущая строка не удаляется после изменения значения выпадающего списка. Когда я изменю выделение, линии будут перекрываться. Кроме того, я не знаю, почему некоторые точки отсутствуют в определенном году, хотя есть данные для этого конкретного года после того, как я изменю выбор. Я очень новичок в d3. Надеюсь, кто - нибудь поможет мне решить эти проблемы. Заранее спасибо.

Вот ссылка на мои данные: https://raw.githubusercontent.com/syakirah98/data_vis/master/sex_country.csv[^]

Вот ссылка на мой график: линейный график — ImgBB[^]

Что я уже пробовал:

Вот мой HTML код:

<!DOCTYPE html>
<meta charset="utf-8">
<style>

    /* set the CSS */
    
    .line {
        fill: none;
        /*stroke: #aaa;
        stroke: #43484c;
        stroke: #405275;
        stroke: rgba(40, 53, 79, .95);
        stroke: #161719;
        stroke: #f99e1a;*/
        stroke: #f89e35;
        stroke-width: 2px;
    }
    
    .line2 {
        fill: none;
        stroke: #aaa;
        stroke-width: 2px;
    }
    
    .line3 {
        fill: none;
        stroke: #405275;
        stroke-width: 2px;
    }
    
    .line3-text {
        fill: #405275;
        stroke: #405275;
    }
    
    .line2-text {
        fill: #aaa;
        stroke: #aaa;
    }
    
    .line-text {
        fill: #f89e35;
        stroke: #f89e35;
    }
    
    div.tooltip {
        position: absolute;
        text-align: center;
        padding: 5px;
        font-size: 12px;
        font-weight: bold;
        background: #f99e1a;
        border: 0px;
        border-radius: 8px;
    }
    
    .tooltip p {
        margin: 0;
        padding: 0;
    }
    
    circle {
        fill: rgba(40, 53, 79, .95);
    }
    
    .chart-title {
        margin-bottom: 0;
    }

</style>

<body>
    <h4 class="chart-title">Suicide Rate by Gender</h4>
    <select id="contBtn"></select>
    <div class="sex"></div>
    <!-- load the d3.js library -->
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script>
        // set the dimensions and margins of the graph
        var margin = {
                top: 50,
                right: 20,
                bottom: 30,
                left: 80
            },
            width = 960 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;

        // set the ranges
        var x = d3.scaleLinear().range([0, width]);
        var y = d3.scaleLinear().range([height, 0]);

        // define the line  
        function basicy() {
            var ret = d3.line()
                .x(function (d) {
                    return x(d.year);
                })
            return ret;
        }
        var valueline = basicy()
            .y(function (d) {
                return y(d.female);
            });
        var valueline2 = basicy()
            .y(function (d) {
                return y(d.male);
            });
        var div = d3.select(".sex").append("div")
            .attr("class", "tooltip")
            .style("opacity", 0);

        // append the svg obgect to the body of the page
        // appends a 'group' element to 'svg'
        // moves the 'group' element to the top left margin
        var svg = d3.select(".sex").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 + ")");

        // Get the data
        var datalist = [];
        d3.csv("https://raw.githubusercontent.com/syakirah98/data_vis/master/sex_country.csv", function (error, data) {
            if (error) throw error;
                    
              var dataGrouper = d3.nest().key(function(d) { return d.country; })
                //.entries(data);
              
              var datas = dataGrouper.entries(data);
                
              datas.forEach(function(d) {
                d.values.forEach(function(d) {
                    d.female = +d.female;
                    d.male = +d.male;
                });
              });
            
            var countriess = d3.map(data, function(d){return(d.country)}).keys()
    
            // add the options to the button
            d3.select("#contBtn")
              .selectAll('myOptions')
                .data(countriess)
              .enter()
                .append('option')
              .text(function (d) { return d; }) // text showed in the menu
              .attr("value", function (d) { return d; }) // corresponding value returned by the button

            // scale the range of the data
            x.domain(d3.extent(data, function (d) {
                return d.year;
            }));
            y.domain([0, d3.max(data, function (d) {
                return Math.max(d.female, d.male);
            })]);

            // add the valueline path.
            var dataArray = [{
                "name": "Female",
                "x": 100,
                "y": 50,
                "class": "line-text",
                "class2": "line",
                "dataline": valueline
            }, {
                "name": "male",
                "x": 100,
                "y": 90,
                "class": "line2-text",
                "class2": "line2",
                "dataline": valueline2
            }]
            var filteredData = data.filter(function(d) {
                return d.country == countriess[0];
            });

            var groupedData = dataGrouper.entries(filteredData);

            for (var i = 0; i < dataArray.length; i++) {
                svg.append("text").text(dataArray[i].name)
                    .attr("x", dataArray[i].x)
                    .attr("y", dataArray[i].y);
                svg.append("rect")
                    .attr("x", dataArray[i].x - 70)
                    .attr("y", dataArray[i].y - 11)
                    .attr("width", 50)
                    .attr('height', 10)
                    .attr('class', dataArray[i].class)
                svg.append("path")
                    .data([groupedData[0].values])
                    .attr("class", dataArray[i].class2)
                    .attr("d", dataArray[i].dataline) 
            }

            // add the dots with tooltips
            var fixeddot = svg.selectAll("dot")
                .data(groupedData[0].values)
                .enter().append("circle")
                .attr("r", 5)
            var fixeddot2 = svg.selectAll("dot")
                .data(groupedData[0].values)
                .enter().append("circle")
                .attr("r", 5)
            

            fixeddot.attr("cx", function (d) {
                    return x(d.year);
                })
                .attr("cy", function (d) {
                    return y(d.female);
                })
                .on("mouseover", function (d) {
                    div.transition()
                        .duration(100)
                        .style("opacity", .9);
                    div.html("<p>Year:" + d.year + "</p> <p>Suicide rate:" + d.female + "</p>")
                        .style("left", (d3.event.pageX) + "px")
                        .style("top", (d3.event.pageY - 28) + "px");
                });

            fixeddot2.attr("cx", function (d) {
                    return x(d.year);
                })
                .attr("cy", function (d) {
                    return y(d.male);
                })
                .on("mouseover", function (d) {
                    div.transition()
                        .duration(100)
                        .style("opacity", .9);
                    div.html("<p>Year:" + d.year + "</p> <p>Suicide rate:" + d.male + "</p>")
                        .style("left", (d3.event.pageX) + "px")
                        .style("top", (d3.event.pageY - 28) + "px");
                });

            // add the X Axis
            svg.append("g")
                .attr("transform", "translate(0," + height + ")")
                .call(d3.axisBottom(x));

            // add the Y Axis
            svg.append("g")
                .call(d3.axisLeft(y));
                
            svg.append("g")
              .attr("class", "y axis")
              .call(y)
              .append('text')
              .attr("y", -50)
              .attr("x", -250)
              .attr("transform", "rotate(-90)")
              .attr("fill", "#000")
              .text("Suicides Rate (/100K)");   

            svg.append("text")
                .attr("class", "x axis")
                .attr("text-anchor", "end")
                .attr("x", 450)
                .attr("y", height + 30)
                .text("Year");
                
            function update(selectedGroup) {

              // Create new data with the selection?
              var filteredData = data.filter(function(d) {
                return d.country == selectedGroup;
              });
                    
              var groupedData = dataGrouper.entries(filteredData);
              
              for (var i = 0; i < dataArray.length; i++) {
                svg.append("text").text(dataArray[i].name)
                    .attr("x", dataArray[i].x)
                    .attr("y", dataArray[i].y);
                svg.append("rect")
                    .attr("x", dataArray[i].x - 70)
                    .attr("y", dataArray[i].y - 11)
                    .attr("width", 50)
                    .attr('height', 10)
                    .attr('class', dataArray[i].class)
                svg.append("path")
                    .data([groupedData[0].values]).transition().duration(1000)
                    .attr("class", dataArray[i].class2)
                    .attr("d", dataArray[i].dataline) 
            }

            // add the dots with tooltips
            fixeddot.data(groupedData[0].values).transition().duration(1000)
                .attr("r", 5)
            fixeddot2.data(groupedData[0].values).transition().duration(1000)
                .attr("r", 5)
            

            fixeddot.attr("cx", function (d) {
                    return x(d.year);
                })
                .attr("cy", function (d) {
                    return y(d.female);
                })
                .on("mouseover", function (d) {
                    div.transition()
                        .duration(200)
                        .style("opacity", .9);
                    div.html("<p>Year:" + d.year + "</p> <p>Suicide rate:" + d.female + "</p>")
                        .style("left", (d3.event.pageX) + "px")
                        .style("top", (d3.event.pageY - 28) + "px");
                });

            fixeddot2.attr("cx", function (d) {
                    return x(d.year);
                })
                .attr("cy", function (d) {
                    return y(d.male);
                })
                .on("mouseover", function (d) {
                    div.transition()
                        .duration(200)
                        .style("opacity", .9);
                    div.html("<p>Year:" + d.year + "</p> <p>Suicide rate:" + d.male + "</p>")
                        .style("left", (d3.event.pageX) + "px")
                        .style("top", (d3.event.pageY - 28) + "px");
                });

        }
        
            // When the button is changed, run the updateChart function
            d3.select("#contBtn").on("change", function(d) {
                // recover the option that has been chosen
                var selectedOption = d3.select(this).property("value");
                // run the updateChart function with this selected option
                update(selectedOption);
            });


        });
    </script>
</body>

0 Ответов