Как удалить предыдущую строку после изменения значения выпадающего списка?
Я попытался создать многострочный график с выпадающим меню. График должен изменяться в соответствии с данными для выбранного значения в выпадающем меню. В настоящее время точка на линейном графике может изменяться в соответствии со значением в выпадающем меню, но предыдущая строка не удаляется после изменения значения выпадающего списка. Когда я изменю выделение, линии будут перекрываться. Кроме того, я не знаю, почему некоторые точки отсутствуют в определенном году, хотя есть данные для этого конкретного года после того, как я изменю выбор. Я очень новичок в 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>