javascript D3.js 无法读取未定义的属性“长度”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34107705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 17:15:37  来源:igfitidea点击:

D3.js Cannot read property 'length' of undefined

javascriptcsvd3.js

提问by basedian

I'm pretty new to d3.js and to web too. I wanted to ue a csv file to plot a line graph but I got some errors I can't really fix:

我对 d3.js 和网络也很陌生。我想使用 csv 文件来绘制折线图,​​但出现了一些我无法真正修复的错误:

enter image description here

在此处输入图片说明

Here is the code:

这是代码:

body,html{
 margin: 0;
 padding: 0;
 font-family: "Arial", sans-serif;
 font-size: 0.95em;
 text-align: center;
}
#chart{
 background-color: #F5F2EB;
 border: 1px solid #CCC;
}
.bar{
 fill: purple;
 shape-rendering: crispEdges;
}
.bar-label{
 fill: black;
 text-anchor: middle;
 font-size: 18px;
}
.axis path,
.axis line{
 fill: none;
 stroke: #000;
 shape-rendering: crispEdges;
}
.gridline path,
.gridline line{
 fill: none;
 stroke: #ccc;
 shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Learning D3</title>
 <link rel="stylesheet" href="main.css">
 <script  type="text/javascript" src="d3.min.js"></script>
</head>
<body>
<!--Place all DOM elements here -->
<script>

var data= [
 d3.csv("refugee_data.csv", function(d) {
  return {
    /*year: new Date(+d.Year, 0, 1), // convert "Year" column to Date
    make: d.Make,
    model: d.Model,
    length: +d.Length // convert "Length" column to number*/
  date: d.Year + "/" +d.Month,
  origin: d.Origin,
  asylum: d.Asylum,
  value: +d.Value
  };
}, function(error, rows) {
  console.log(rows);
})
];

var w = 800;
var h = 450;
var margin = {
 top: 58,
 bottom: 100,
 left: 80,
 right: 40
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;

var svg = d3.select("body").append("svg")
   .attr("id", "chart")
   .attr("width", w)
   .attr("height", h);
var dateParser = d3.time.format("%Y/%B").parse;
var x = d3.time.scale()
   .domain(d3.extent(data, function(d){
   var date = dateParser(d.date);
   return date;
  }))
  .range([0,width]);

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

function plot(params){
  //enter()
  this.selectAll(".point")
    .data(params.data)
    .enter()
     .append("circle")
     .classed("point", true)
     .attr("r", 2);
  //Update
  this.selectAll(".point")
  .attr("cx", function(d){
   var date = dateParser(d.date);
   return x(date);
  })
  .attr("cy", function(d){
   return y(d.value);
  })

  //Exit()
  this.selectAll(".point")
  .data(params.data)
  .exit()
  .remove();
}
plot.call(chart, {
 data: data
})
</script>
</body>
</html>

And this ist my a part of my csv, pretty basic so I don't get why it does not work.

这是我的 csv 的一部分,非常基本,所以我不明白为什么它不起作用。

Asylum,Origin,Year,Month,Value

庇护,来源,年,月,价值

Germany,Afghanistan,2014,January,981 Germany,Afghanistan,2014,February,781 Germany,Afghanistan,2014,March,675 Germany,Afghanistan,2014,April,673 Germany,Afghanistan,2014,May,523 Germany,Afghanistan,2014,June,621 Germany,Afghanistan,2014,July,752 Germany,Afghanistan,2014,August,743 Germany,Afghanistan,2014,September,922

德国,阿富汗,2014,一月,981 德国,阿富汗,2014,二月,781 德国,阿富汗,2014,三月,675 德国,阿富汗,2014,四月,673 德国,阿富汗,2014 年,五月,2014,德国,June,621 Germany,Afghanistan,2014,July,752 Germany,Afghanistan,2014,August,743 Germany,Afghanistan,2014,September,922

I assume it is a really stupid mistake can you please help me out?

我认为这是一个非常愚蠢的错误,你能帮我吗?

采纳答案by Luke Woodward

Your mistake is assuming that calling d3.csv(...)returns your CSV data.

您的错误是假设调用d3.csv(...)返回您的 CSV 数据。

d3.csvmakes an AJAX call to load your data and then calls a callback function when that data has been loaded. Your code continues running while the data loads in the background. When you write var data = [d3.csv(...)], datadoesn't contain the data loaded from your CSV file, it contains only a d3 object, and you cannot plot that.

d3.csv进行 AJAX 调用以加载数据,然后在加载数据后调用回调函数。当数据在后台加载时,您的代码会继续运行。当您编写var data = [d3.csv(...)],data不包含从您的 CSV 文件加载的数据时,它只包含一个 d3 对象,您无法绘制它。

Instead, your call to d3.csvshould look something like the following:

相反,您的调用d3.csv应如下所示:

d3.csv("refugee_data.csv", function(d) {
  return {
        date: d.Year + "/" +d.Month,
        origin: d.Origin,
        asylum: d.Asylum,
        value: +d.Value
  };
}, function(error, rows) {
  console.log(rows);
  render(rows);
});

where renderis a function that d3 will call to draw your graph when the data has finished loading.

whererender是一个函数,当数据完成加载时,d3 将调用它来绘制图形。

I created a renderfunction that contained the contents of your code from the line var w = 800;to the lines beginning var y = ..., followed by the contents of the plotfunction. I also replaced this.selectAllwith svg.selectAll, and remove the use of plot.call. The renderfunction I wrote ended up as follows:

我创建了一个render函数,其中包含从行var w = 800;到行开头的代码内容var y = ...,然后是plot函数的内容。我也替换this.selectAllsvg.selectAll,并删除了使用plot.callrender我写的函数最终如下:

function render(data) {
    var w = 800;
    var h = 450;
    var margin = {
        top: 58,
        bottom: 100,
        left: 80,
        right: 40
    };
    var width = w - margin.left - margin.right;
    var height = h - margin.top - margin.bottom;

    var svg = d3.select("body").append("svg")
                .attr("id", "chart")
                .attr("width", w)
                .attr("height", h);
    var dateParser = d3.time.format("%Y/%B").parse;
    var x = d3.time.scale()
             .domain(d3.extent(data, function(d){
                var date = dateParser(d.date);
                return date;
            }))
            .range([0,width]);

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

        //enter()
        svg.selectAll(".point")
                .data(data)
                .enter()
                    .append("circle")
                    .classed("point", true)
                    .attr("r", 2);
        //Update
        svg.selectAll(".point")
        .attr("cx", function(d){
            var date = dateParser(d.date);
            return x(date);
        })
        .attr("cy", function(d){
            return y(d.value);
        })

        //Exit()
        svg.selectAll(".point")
        .data(data)
        .exit()
        .remove();
}

After making these changes I was able to see your graph working.

进行这些更改后,我能够看到您的图表正常工作。