我仍然在努力解决此错误,如earlier post on StackOverflow.com所示。我已经找出了问题的原因,在我的D3.js代码中,它无法遍历'对象'。我的原始数据源是RESTful web api。使用jQuery和JavaScript函数,我可以将值加载到名为' 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))
时,我得到了对象'。如果有任何D3.js导师在阅读这篇文章,我可以选择转换这些数据吗?我已经探索了几个没有成功。
// ============= APPENDED 01 ========================
因为这里已经请求了数据集',可以在上面的帖子链接(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'组合数据集的函数'变量如下所示:
//~ 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 ========================
我开始工作了!
我将在下面发布修订后的工作代码。但对于关注这篇文章的人,我想解释一下,我发现了什么。
Mark建议更改dataset.push()
以删除所有引号。这给了我对象而不是字符串。经过一些故障排除后,它最终按预期显示(完全令人兴奋!),感谢Mark,你的建议就行了。
以下是修订后的代码:
//~ 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; };
答案 0 :(得分:0)
如果您不确定自己是否会获得一系列对象&#39;或具有键/值的&#39;,那么我会使用库中的_.forEach 'lodash'将遍历一个对象数组或一个对象的键/值。
答案 1 :(得分:0)
根据错误消息,Cannot read property 'length' of undefined
错误不是来自dataset.forEach
,而是来自您正在查找.length
内容的某个地方。
(注意:在Chrome开发工具中,您可以检查/扩展控制台中的错误,并查看它来自哪个文件和行号。)
如果它来自您分享的任何代码,那么这就是违规行:
var itemCount = data.Items.length;
如果data.Items
恰好未定义,则会出现此错误。因此,在错误行之前的行上插入console.log(data)
,检查输出,查找data.Items
,这可能不存在。您的诊断应该指明您修复它的方向。