D3 v5: многострочная диаграмма, невозможно нарисовать несколько линий - PullRequest
1 голос
/ 05 мая 2020

Спасибо за любую помощь, которую вы можете предложить заранее, я новичок в D3 и с трудом следую примерам многострочных диаграмм, которые я видел в Интернете. У меня есть данные, которые выглядят так:

country,year,average
United States,1970,51
United States,1971,50
United States,1972,54
United States,1973,56
United States,1974,53
United States,1975,57
United States,1976,60
Brazil,1970,23
Brazil,1971,25
Brazil,1972,24
Brazil,1973,21
Brazil,1974,25
Brazil,1975,26
Brazil,1976,24

для нескольких стран, и я хотел бы сделать строку для каждой из них.

var margin = {top: 10, right: 40, bottom: 150, left: 70},
width = 760 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom; 

 var w = width + margin.left + margin.right;
 var h = height + margin.top + margin.bottom;

 var svg = d3.select("body").append("svg") // this appends a new SVG element to body
    .attr("width", w) // set the width 
    .attr("height", h) // set the height
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// x scale will handle time
 var xScale = d3.scaleBand().range([0, width]).padding(0.1);

// y scale will handle energy consumption values
 var yScale = d3.scaleLinear().range([height,0]);

// Define X and Y AXIS
 var yAxis = d3.axisLeft(yScale).ticks(5);
 var xAxis = d3.axisBottom(xScale); 

 function rowConverter(data) {
      return {
           country : data.country, 
           year : +data.year,
           average : +data.average // the + operator parses strings into numbers
      };
}

// line generator function
 var line = d3.line()
    .curve(d3.curveBasis)
    .x(function(d) { return xScale(d.year); })
    .y(function(d) { return yScale(d.average); })

d3.csv("EvenMore.csv", rowConverter).then(function(data) {

     var countries = d3.nest()
        .key(function (d) { return d.country; })
        .entries(data); 

     console.log(countries);

     yScale.domain([0,d3.max(data, function(d) {return d.average; } )]); 
     xScale.domain(d3.extent(data, function(d) { return d.year; } )); 

    // Draw xAxis
     svg.append("g") // add a new svg group element
        .attr("class", "x axis")
        .attr("transform", "translate(0, " + height + ")")
        .call(xAxis)
        .selectAll("text")
        .attr("dx", "-.8em")
        .attr("dy", ".25em")
        .attr("text-anchor", "end");

    // Draw yAxis
     svg.append("g")
        .attr("class", "y axis")
        .call(yAxis)
        .selectAll("text")
        .attr("dx", "-.8em")
        .attr("dy", ".25em")
        .attr("text-anchor", "end");


    svg.selectAll("path")
         .data(countries)
        .enter()
        .append("path")
        .attr("class", "line")
        .attr("d", function(d) { 
             return line(d.values); 
        });

}); 

Я не знаю, что означают эти ошибки, Ошибка: атрибут d: Ожидаемое число, «… .33333333333334LNaN, 114.27777777…»:

imageattribute d: Expected number, "….33333333333334LNaN,114.27777777…"">

1 Ответ

2 голосов
/ 05 мая 2020

Проблема

Вы неправильно используете шкалу диапазона. Полосная шкала не является количественной шкалой и поэтому не имеет верхней и нижней границ. Вместо этого необходимо указать каждое значение домена:

Первый элемент домена будет сопоставлен с первым диапазоном, значение второго домена - со вторым диапазоном и т. Д. Значения домена хранятся внутри в карте от строкового значения до индекса; полученный индекс затем используется для определения диапазона ( docs )

Это объясняет вашу ошибку, вы указали два значения для домена: первый год и последний год . Мы можем видеть, что домен состоит только из этих двух значений несколькими способами, если смотреть на масштаб (ось шкалы полосы по умолчанию включает все отметки, но даже здесь мы видим, что интервал действительно странный, если 1970 и 1976 годы являются началом и концом. значений):

enter image description here

Сообщение об ошибке также помогает найти ошибку: если значение x первой координаты было NaN, сообщение будет читать "Expected Number, "MNan,1234...", когда исследуя атрибут path d (особенно без применения кривой), мы можем увидеть значение x каждой координаты, кроме первой и последней, равных NaN.

Решение

Вам необходимо указать все значения в домене на шкале. Мы можем получить все значения с помощью:

xScale.domain(data.map(function(d) { return d.year; }))

Масштаб будет отсеивать дубликаты при установке домена.

var margin = {top: 10, right: 40, bottom: 150, left: 70},
width = 760 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom; 

 var w = width + margin.left + margin.right;
 var h = height + margin.top + margin.bottom;

 var svg = d3.select("body").append("svg") // this appends a new SVG element to body
    .attr("width", w) // set the width 
    .attr("height", h) // set the height
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// x scale will handle time
 var xScale = d3.scaleBand().range([0, width]).padding(0.1);

// y scale will handle energy consumption values
 var yScale = d3.scaleLinear().range([height,0]);

// Define X and Y AXIS
 var yAxis = d3.axisLeft(yScale).ticks(5);
 var xAxis = d3.axisBottom(xScale); 

 function rowConverter(data) {
      return {
           country : data.country, 
           year : +data.year,
           average : +data.average // the + operator parses strings into numbers
      };
}

// line generator function
 var line = d3.line()
    .curve(d3.curveBasis)
    .x(function(d) { return xScale(d.year); })
    .y(function(d) { return yScale(d.average); })

var data = d3.csvParse(d3.select("pre").remove().text())


    data = data.map(rowConverter);

     var countries = d3.nest()
        .key(function (d) { return d.country; })
        .entries(data); 

     yScale.domain([0,d3.max(data, function(d) {return d.average; } )]); 
     xScale.domain(countries[0].values.map(function(d) { return d.year; })); 

    // Draw xAxis
     svg.append("g") // add a new svg group element
        .attr("class", "x axis")
        .attr("transform", "translate(0, " + height + ")")
        .call(xAxis)
        .selectAll("text")
        .attr("dx", "-.8em")
        .attr("dy", ".25em")
        .attr("text-anchor", "end");

    // Draw yAxis
     svg.append("g")
        .attr("class", "y axis")
        .call(yAxis)
        .selectAll("text")
        .attr("dx", "-.8em")
        .attr("dy", ".25em")
        .attr("text-anchor", "end");


    svg.selectAll(null)
        .data(countries)
        .enter()
        .append("path")
        .attr("class", "line")
        .attr("d", function(d) {
             return line(d.values); 
        });
.line {
    stroke-width: 2px;
    fill: none;
    stroke:black;
}

country,year,average
United States,1970,51
United States,1971,50
United States,1972,54
United States,1973,56
United States,1974,53
United States,1975,57
United States,1976,60
Brazil,1970,23
Brazil,1971,25
Brazil,1972,24
Brazil,1973,21
Brazil,1974,25
Brazil,1975,26
Brazil,1976,24
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...