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
D3.js Cannot read property 'length' of undefined
提问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 文件来绘制折线图,但出现了一些我无法真正修复的错误:
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.csv
makes 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(...)]
, data
doesn'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.csv
should 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 render
is a function that d3 will call to draw your graph when the data has finished loading.
whererender
是一个函数,当数据完成加载时,d3 将调用它来绘制图形。
I created a render
function 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 plot
function. I also replaced this.selectAll
with svg.selectAll
, and remove the use of plot.call
. The render
function I wrote ended up as follows:
我创建了一个render
函数,其中包含从行var w = 800;
到行开头的代码内容var y = ...
,然后是plot
函数的内容。我也替换this.selectAll
为svg.selectAll
,并删除了使用plot.call
。render
我写的函数最终如下:
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.
进行这些更改后,我能够看到您的图表正常工作。