Member 13620781 Ответов: 1

Почему на линейном графике так много линий?


Я пытаюсь воспроизвести эту линейную диаграмму в соответствии с моими данными, но линейная диаграмма производит много линий вместо одной линии.

вот ссылка на линейный график, который я пытался воспроизвести:
Группа фильтров in d3.js линейный график[^]

вот ссылка на вывод моей линейной диаграммы в качестве вашей ссылки: линейный график — imgbb.com[^]

заранее благодарю вас!

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

вот мой HTML код:
<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Initialize a select button -->
<select id="selectButton"></select>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>

<!-- Color Scale -->
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>

<script>

// set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 30, left: 60},
    width = 1100 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
  .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 + ")");

//Read the data
d3.csv("https://raw.githubusercontent.com/syakirah98/data_vis/master/suicide_rate.csv", function(data) {

    // List of groups (here I have one group per column)
    var allGroup = d3.map(data, function(d){return(d.sex)}).keys()

    // add the options to the button
    d3.select("#selectButton")
      .selectAll('myOptions')
     	.data(allGroup)
      .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

    // A color scale: one color for each group
    var myColor = d3.scaleOrdinal()
      .domain(allGroup)
      .range(d3.schemeSet2);

    // Add X axis --> it is a date format
    var x = d3.scaleLinear()
      .domain(d3.extent(data, function(d) { return d.year; }))
      .range([ 0, width ]);
    svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x).ticks(31));

    // Add Y axis
    var y = d3.scaleLinear()
      .domain([0, d3.max(data, function(d) { return +d.suicides_rate; })])
      .range([ height, 0 ]);
    svg.append("g")
      .call(d3.axisLeft(y));

    // Initialize line with first group of the list
    var line = svg
      .append('g')
      .append("path")
        .datum(data.filter(function(d){return d.sex==allGroup[0]}))
        .attr("d", d3.line()
          .x(function(d) { return x(d.year) })
          .y(function(d) { return y(+d.suicides_rate) })
        )
        .attr("stroke", function(d){ return myColor("valueA") })
        .style("stroke-width", 4)
        .style("fill", "none")

    // A function that update the chart
    function update(selectedGroup) {

      // Create new data with the selection?
      var dataFilter = data.filter(function(d){return d.sex==selectedGroup})

      // Give these new data to update line
      line
          .datum(dataFilter)
          .transition()
          .duration(1000)
          .attr("d", d3.line()
            .x(function(d) { return x(d.year) })
            .y(function(d) { return y(+d.suicides_rate) })
          )
          .attr("stroke", function(d){ return myColor(selectedGroup) })
    }

    // When the button is changed, run the updateChart function
    d3.select("#selectButton").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>

ниже приведен пример моих данных:
country,year,sex,age,suicides_no,population,suicides_rate,country-year,HDI for year, gdp_for_year ($) ,gdp_per_capita ($),generation
Albania,1987,male,15-24 years,21,312900,6.71,Albania1987,,"2,156,624,900",796,Generation X
Albania,1987,male,35-54 years,16,308000,5.19,Albania1987,,"2,156,624,900",796,Silent
Albania,1987,female,15-24 years,14,289700,4.83,Albania1987,,"2,156,624,900",796,Generation X
Albania,1987,male,75+ years,1,21800,4.59,Albania1987,,"2,156,624,900",796,G.I. Generation
Albania,1987,male,25-34 years,9,274300,3.28,Albania1987,,"2,156,624,900",796,Boomers
Albania,1987,female,75+ years,1,35600,2.81,Albania1987,,"2,156,624,900",796,G.I. Generation
Albania,1987,female,35-54 years,6,278800,2.15,Albania1987,,"2,156,624,900",796,Silent
Albania,1987,female,25-34 years,4,257200,1.56,Albania1987,,"2,156,624,900",796,Boomers
Albania,1987,male,55-74 years,1,137500,0.73,Albania1987,,"2,156,624,900",796,G.I. Generation
Albania,1987,female,5-14 years,0,311000,0,Albania1987,,"2,156,624,900",796,Generation X
Albania,1987,female,55-74 years,0,144600,0,Albania1987,,"2,156,624,900",796,G.I. Generation
Albania,1987,male,5-14 years,0,338200,0,Albania1987,,"2,156,624,900",796,Generation X
Albania,1988,female,75+ years,2,36400,5.49,Albania1988,,"2,126,000,000",769,G.I. Generation
Albania,1988,male,15-24 years,17,319200,5.33,Albania1988,,"2,126,000,000",769,Generation X
Albania,1988,male,75+ years,1,22300,4.48,Albania1988,,"2,126,000,000",769,G.I. Generation
Albania,1988,male,35-54 years,14,314100,4.46,Albania1988,,"2,126,000,000",769,Silent
Albania,1988,male,55-74 years,4,140200,2.85,Albania1988,,"2,126,000,000",769,G.I. Generation
Albania,1988,female,15-24 years,8,295600,2.71,Albania1988,,"2,126,000,000",769,Generation X
Albania,1988,female,55-74 years,3,147500,2.03,Albania1988,,"2,126,000,000",769,G.I. Generation
Albania,1988,female,25-34 years,5,262400,1.91,Albania1988,,"2,126,000,000",769,Boomers
Albania,1988,male,25-34 years,5,279900,1.79,Albania1988,,"2,126,000,000",769,Boomers
Albania,1988,female,35-54 years,4,284500,1.41,Albania1988,,"2,126,000,000",769,Silent
Albania,1988,female,5-14 years,0,317200,0,Albania1988,,"2,126,000,000",769,Generation X
Albania,1988,male,5-14 years,0,345000,0,Albania1988,,"2,126,000,000",769,Generation X
Albania,1989,male,75+ years,2,22500,8.89,Albania1989,,"2,335,124,988",833,G.I. Generation
Albania,1989,male,25-34 years,18,283600,6.35,Albania1989,,"2,335,124,988",833,Boomers
Albania,1989,male,35-54 years,15,318400,4.71,Albania1989,,"2,335,124,988",833,Silent
Albania,1989,male,55-74 years,6,142100,4.22,Albania1989,,"2,335,124,988",833,G.I. Generation
Albania,1989,male,15-24 years,12,323500,3.71,Albania1989,,"2,335,124,988",833,Generation X
Albania,1989,female,35-54 years,7,288600,2.43,Albania1989,,"2,335,124,988",833,Silent
Демо - JSFiddle[^]

1 Ответов

Рейтинг:
9

Richard Deeming

Проблема в том, что образец фильтруется по имени. В отфильтрованных данных есть только одна запись в год.

В вашей выборке данных вы фильтруете по полу. Отфильтрованные данные содержат несколько записей за каждый год.

Вам нужно суммировать отфильтрованные данные по годам, используя гнездо[^] функция. Вам также нужно будет изменить диапазон вашей оси y, чтобы учесть общие значения, которые будут намного выше, чем отдельные записи.

var dataGrouper = d3.nest()
    .key(function(d) { return d.year; }).sortKeys(d3.ascending)
    .rollup(function(g) { return d3.sum(g, function(d) { return +d.suicides_rate; }) });

...

var y = d3.scaleLinear()
    .domain([0, d3.max(dataGrouper.entries(data), function(d) { return d.value; })])
    .range([height, 0]);

...

var filteredData = data.filter(function(d) { return d.sex == allGroup[0]; });
var groupedData = dataGrouper.entries(filteredData);

var line = svg
    .append('g')
    .append("path")
    .datum(groupedData)
    .attr("d", d3.line()
        .x(function(d) { return x(d.key); })
        .y(function(d) { return y(d.value); })
    )
    .attr("stroke", function(d) {
        return myColor("valueA")
    })
    .style("stroke-width", 4)
    .style("fill", "none");

...

function update(selectedGroup) {
    // Create new data with the selection
    var filteredData = data.filter(function(d) { return d.sex == selectedGroup; });
    var groupedData = dataGrouper.entries(filteredData);

    // Give these new data to update line
    line
        .datum(groupedData)
        .transition()
        .duration(1000)
        .attr("d", d3.line()
            .x(function(d) { return x(d.key); })
            .y(function(d) { return y(d.value); })
        )
        .attr("stroke", function(d) {
            return myColor(selectedGroup)
        });
}
Демо - JSFiddle[^]


Member 13620781

Спасибо!