D3.js D3 v5:多行图表,无法绘制多行

D3.js D3 v5:多行图表,无法绘制多行,d3.js,D3.js,感谢您提前提供的任何帮助,我是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

感谢您提前提供的任何帮助,我是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:预期数字,“…3333 4LNAN,114.27777777…”


问题

你没有正确使用波段刻度。波段标度不是定量标度,因此没有上限和下限。相反,需要指定域的每个值:

域中的第一个元素将映射到第一个频带,即 将第二个域值转换为第二个频带,依此类推。域值是 内部存储在从字符串化值到索引的映射中;这个 然后使用生成的索引确定波段()

这就解释了您的错误,您为域指定了两个值,第一年和最后一年。在查看比例时,我们可以从几个方面看到域仅为这两个值(默认情况下,波段比例的轴包括所有刻度,但即使在这里,如果1970和1976是起始值和结束值,我们也会看到间距非常奇怪):

错误消息还有助于查找错误:如果第一个坐标的x值为NaN,则在检查路径
d
属性时(尤其是在没有应用任何曲线的情况下),消息将显示
“预期数字”,MNan,1234…”
,我们可以看到每个坐标的x值,但第一个和最后一个是NaN

解决方案

您需要提供范围内的所有值。我们可以通过以下方式获取所有值:

xScale.domain(data.map(function(d) { return d.year; }))
设置域时,缩放将清除重复项

var margin={top:10,right:40,bottom:150,left:70},
宽度=760-边距.左-边距.右,
高度=500-margin.top-margin.bottom;
var w=宽度+边距.left+边距.right;
var h=高度+边距.top+边距.bottom;
var svg=d3.select(“body”).append(“svg”)//这将向body追加一个新的svg元素
.attr(“宽度”,w)//设置宽度
.attr(“高度”,h)//设置高度
.附加(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
//x刻度将处理时间
var xScale=d3.scaleBand().range([0,width]).padding(0.1);
//y刻度将处理能耗值
var yScale=d3.scaleLinear().range([height,0]);
//定义X和Y轴
var yAxis=d3.axisLeft(yScale).ticks(5);
var xAxis=d3.axisBottom(xScale);
函数行转换器(数据){
返回{
国家:data.country,
年份:+data.year,
average:+data.average//+运算符将字符串解析为数字
};
}
//线路发生器功能
var line=d3.line()
.曲线(d3.曲线基)
.x(函数(d){return xScale(d.year);})
.y(函数(d){返回yScale(d.平均值);})
var data=d3.csvParse(d3.select(“pre”).remove().text())
data=data.map(行转换器);
var countries=d3.nest()
.key(函数(d){返回d.country;})
.条目(数据);
域([0,d3.max(数据,函数(d){返回d.average;})];
域(国家[0].values.map(函数(d){return d.year;}));
//画X轴
append(“g”)//添加新的svg组元素
.attr(“类”、“x轴”)
.attr(“变换”、“平移(0)”、“高度+”)
.呼叫(xAxis)
.selectAll(“文本”)
.attr(“dx”,“-.8em”)
.attr(“dy”,“.25em”)
.attr(“文本锚定”、“结束”);
//画雅克西斯
svg.append(“g”)
.attr(“类”、“y轴”)
.呼叫(yAxis)
.selectAll(“文本”)
.attr(“dx”,“-.8em”)
.attr(“dy”,“.25em”)
.attr(“文本锚定”、“结束”);
svg.selectAll(空)
.数据(国家)
.输入()
.append(“路径”)
.attr(“类”、“行”)
.attr(“d”,函数(d){
返回线(d值);
});
.line{
笔画宽度:2px;
填充:无;
笔画:黑色;
}

国家、年份、平均数
美国,1970年,51
美国,1971年,50
美国,1972年,54
美国,1973年,56
美国,1974年,53
美国,1975年,57
美国,1976年,60
巴西,1970年,23
巴西,1971年,25
巴西,1972年,24
巴西,1973年,21
巴西,1974年,25
巴西,1975年,26

巴西,1976年,24
哇!谢谢你,这真的很有帮助,现在正在画线(耶!!)但有趣的是,只有4条线被绘制出来,但实际上我有6个国家的数据。下面是现在的输出结果:。对此有什么想法吗?我非常感谢你的帮助是的,这是预期的行为。你使用
selectAll(“路径”)
创建行,但轴中已经存在两条路径-因此前两个系列的数据绑定到这些行,其余的则被输入(enter创建一个元素,其中数据数组中的每个项都不存在一个元素)。您可以更改select all语句,使其创建一个空选择:
selectAll(null)
或者由于您对行进行了分类并可能希望更新它们:
selectAll(“.line”)
。我在上面的代码片段中选择了第一个选项(以及从HTML元素解析CSV所需的一些其他更改)