我仍然在努力解决这个错误,如earlier post on StackOverflow.com所示 . 我已经隔离了问题的原因,这是在我的D3.js代码中,它无法遍历'object' . 我的原始数据源是RESTful web api . 使用jQuery和JavaScript函数,我可以将值加载到名为'dataset'的变量中 . 当我输出'dataset'的内容作为警报,或使用jQuery将其写入html元素时,所有数据都在那里 . 太多D3.js示例使用硬编码的数据文件 . 因此,重要的是要注意当我使用相同数据的硬编码版本时,一切正常,但我只能使用这个动态的虚拟数据变量 .
当我运行代码时,它会在此函数崩溃:
dataset.forEach(function(d) {
d.theTime = parseDate(d.theTime);
d.theValue = +d.theValue;
});
错误消息是 Uncaught TypeError: Cannot read property 'length' of undefined
.
当我在此函数之前使用 console.log(typeof(dataset))
时,我得到'object' . 如果有任何D3.js导师在阅读此信息,我可以选择转换这些数据吗?我已经探索了几个没有成功 .
// =============附上01 ========================
因为这里要求的是'dataset',可以在上面的帖子链接(Parsing Time Series Data using D3.js)上面查看:
var dataset = [
{'theTime': '2016/07/12 15:58:40', 'theValue': 1123.07275390625},
{'theTime': '2016/07/12 16:21:10', 'theValue': 1055.6793212890625},
{'theTime': '2016/07/12 16:45:40', 'theValue': 962.4850463867188},
{'theTime': '2016/07/12 17:14:40', 'theValue': 831.2259521484375},
{'theTime': '2016/07/12 17:55:10', 'theValue': 625.3046875}
];
// =============附录02 ========================
在参考Gerardo的问题时,“数据集”变量是“加载”(我认为),因为代码位于'$ .get'函数内,该函数汇总了'dataset'变量,如下所示:
//~ Populate the 'dataset':
var dataset = [];
$.get(url, function(data){
var itemCount = data.Items.length;
var commaCount = itemCount - 1;
for(i=0; i<itemCount; i++){
if(i == commaCount){
dataset.push("{'theTime': '" + formattedDateTime(data.Items[i].Timestamp) + "', 'theValue': " + data.Items[i].Value + "}");
}
else {
dataset.push("{'theTime': '" + formattedDateTime(data.Items[i].Timestamp) + "', 'theValue': " + data.Items[i].Value + "},");
}
}
//~ ALL THE D3 CODE IS INSIDE THIS '$.get' FUNCTION
});
// =============附录03 ========================
我搞定了!
我将在下面发布修订后的工作代码 . 但对于关注这篇文章的人,我想解释一下,我发现了什么 .
马克建议改变 dataset.push()
以删除所有报价 . 这给了我对象而不是字符串 . 经过一些故障排除后,它最终按预期显示(完全令人兴奋!),谢谢马克,你的建议就行了 .
这是修改后的代码:
//~ Populate the 'dataset':
var dataset = [];
$.get(url, function(data){
var itemCount = data.Items.length;
var commaCount = itemCount - 1;
for(i=0; i<itemCount; i++){
dataset.push({theTime: formattedDateTime(data.Items[i].Timestamp), theValue: data.Items[i].Value});
}
var margin = {top: 20, right: 20, bottom: 30, left: 50};
var width = 960 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y/%m/%d %H:%M:%S").parse;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.x(function(d) { return x(d.theTime); })
.y(function(d) { return y(d.theValue); });
var svg = d3.select("#myChart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
dataset.forEach(function(d) {
d.theTime = parseDate(d.theTime);
d.theValue = parseFloat(d.theValue);
});
x.domain(d3.extent(dataset, function(d) { return d.theTime; }));
y.domain(d3.extent(dataset, function(d) { return d.theValue;}));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("M³/hr");
svg.append("path")
.datum(dataset)
.attr("class", "line")
.attr("d", line);
});
//~~~ Format The Date:
function formattedDateTime(dateAndTime) {
var d = new Date(dateAndTime);
var numDate = d.getDate();
var numMonth = d.getMonth() + 1;
var numYear = d.getFullYear();
var numHours = d.getHours();
var numMinutes = d.getMinutes();
var numSeconds = d.getSeconds();
numDate = (numDate < 10) ? "0" + numDate : numDate;
numMonth = (numMonth < 10) ? "0" + numMonth : numMonth;
numHours = (numHours < 10) ? "0" + numHours : numHours;
numMinutes = (numMinutes < 10) ? "0" + numMinutes : numMinutes;
numSeconds = (numSeconds < 10) ? "0" + numSeconds : numSeconds;
return numYear + "/" + numMonth + "/" + numDate + " " + numHours + ":" + numMinutes + ":" + numSeconds;
};
2 回答
基于错误消息,
Cannot read property 'length' of undefined
错误不是来自dataset.forEach
,它来自某个你正在查找.length
的东西 .(注意:在Chrome开发工具中,您可以检查/扩展控制台中的错误,并查看它来自哪个文件和行号) .
如果它来自您共享的任何代码,那么这是违规行:
如果
data.Items
恰好未定义,则会出现此错误 . 因此,在错误行之前的行上插入console.log(data)
,检查输出,查找data.Items
,这可能不存在 . 您的诊断应指向您修复它的方向 .如果你're not sure whether you'将获得'array of objects'或'objects with key/values',那么我将在库中使用_.forEach 'lodash'将迭代对象数组或对象的键/值 .