Проблема
Вы неправильно используете шкалу диапазона. Полосная шкала не является количественной шкалой и поэтому не имеет верхней и нижней границ. Вместо этого необходимо указать каждое значение домена:
Первый элемент домена будет сопоставлен с первым диапазоном, значение второго домена - со вторым диапазоном и т. Д. Значения домена хранятся внутри в карте от строкового значения до индекса; полученный индекс затем используется для определения диапазона ( docs )
Это объясняет вашу ошибку, вы указали два значения для домена: первый год и последний год . Мы можем видеть, что домен состоит только из этих двух значений несколькими способами, если смотреть на масштаб (ось шкалы полосы по умолчанию включает все отметки, но даже здесь мы видим, что интервал действительно странный, если 1970 и 1976 годы являются началом и концом. значений):
Сообщение об ошибке также помогает найти ошибку: если значение 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