使用D3.js解析时间序列数据
是寻求帮助的时候了。我已经学习D3.js好几个星期了,我刚开始觉得我理解了其中的10%(哈,哈,哈)。我试图生成一个非常简单的线图。只要数据非常简单,我就能够做到这一点,但我的原始数据源有UTC时间戳和实/十进制数字,这些数字会不断破坏简单以外的任何东西 原始数据源如下所示:使用D3.js解析时间序列数据,d3.js,svg,time-series,timeserieschart,D3.js,Svg,Time Series,Timeserieschart,是寻求帮助的时候了。我已经学习D3.js好几个星期了,我刚开始觉得我理解了其中的10%(哈,哈,哈)。我试图生成一个非常简单的线图。只要数据非常简单,我就能够做到这一点,但我的原始数据源有UTC时间戳和实/十进制数字,这些数字会不断破坏简单以外的任何东西 原始数据源如下所示: { "Links": {}, "Items": [ { "Timestamp": "2016-07-12T22:21:10Z
{
"Links": {},
"Items": [
{
"Timestamp": "2016-07-12T22:21:10Z",
"Value": 1055.6793212890625,
"UnitsAbbreviation": "m3/h",
"Good": true,
"Questionable": false,
"Substituted": false
},
{
"Timestamp": "2016-07-12T22:39:10Z",
"Value": 989.00830078125,
"UnitsAbbreviation": "m3/h",
"Good": true,
"Questionable": false,
"Substituted": false
}
],
"UnitsAbbreviation": "m3/h"
}
使用jQuery和javascript时间格式化函数,我能够组装以下简化数据集:
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}
];
这是我的密码:
//~ 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 + "},");
}
}
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 = +d.theValue;
});
x.domain(d3.extent(data, function(d) { return d.theTime; }));
y.domain(d3.extent(data, 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("return time(ms)");
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;
};
第一个错误出现在“dataset.forEach()”函数中,即“
uncaughttypeerror:无法读取未定义的属性“length”
”。我在那里解析该数据的努力源于代码中“svg.append(“path”)”点处发生的另一个错误,即“错误:属性d:预期数字,”MNaN,NaNLNaN,NaNL…
”问题是您传递的日期采用以下格式:
“2016/07/12 15:58:40”
您用来解析它的parsedate函数是(注意日期中没有连字符):
应该是的
var parseDate = d3.time.format("%Y/%m/%d %H:%M:%S").parse;
下一个错误是,您正在传递数据以获取数据块,但它没有在任何地方定义:
x.domain(d3.extent(data, function(d) { return d.theTime; }));
y.domain(d3.extent(data, function(d) { return d.theValue;}));
应该是:
x.domain(d3.extent(dataset, function(d) {
return d.theTime;
}));
y.domain(d3.extent(dataset, function(d) {
return d.theValue;
}));
工作代码Hi@WebFixItMan,你能分享数据对象“数据集吗“在顶部执行for循环后。我相信这两个错误的主要原因都来自
formattedDateTime
函数的输出。D3的哪个版本?嗨,Alex和Gerardo!我相信西里尔的回答回答了亚历克斯的问题。对于杰拉尔多,我正在使用CDN链接:
嗨,西里尔:你的建议几乎扫清了通往成功的道路。它给了我解决这个问题的方向。我仍然得到未捕获类型错误:无法读取未定义的属性“length”
。当我硬编码变量“dataset”时,我的显示也起作用,就像您在JSFIDLE上的示例一样。但是,在我的版本中,我仅限于使用动态“dataset”变量。我在'dataset.forEach'函数之前执行了一个警报(typeof(dataset))
,它将其报告为一个'object'。我将开始研究如何克服这个问题,但如果你有洞察力,我非常感谢你的反馈。
x.domain(d3.extent(dataset, function(d) {
return d.theTime;
}));
y.domain(d3.extent(dataset, function(d) {
return d.theValue;
}));