使用D3.js解析时间系列数据 [英] Parsing Time Series Data using D3.js

查看:1633
本文介绍了使用D3.js解析时间系列数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我的StackOverflow朋友:



现在是时候请求帮助。我一直在研究D3.js几个星期,我刚开始觉得我理解它的10%(ha,ha,ha)。我试图生成一个非常简单的线图。我可以做到这一点,只要数据非常简单,但我的原始数据源有UTC时间戳,真实/十进制数,保持崩溃的任何东西简单。



原始数据源如下所示:

 

{
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
} $ b b

使用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}
];

这是我的代码:

 

//〜填充'dataset':
var dataset = [];
$ .get(url,function(data){
var itemCount = data.Items.length;
var commaCount = itemCount - 1;
for(i = 0; 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 ){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 ,+ 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 height +))
.call(xAxis);

svg.append(g)
.attr(class,y axis)
.call(yAxis)
.append )
.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 ,line);
});

// ~~~格式日期:
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()'函数,它是未捕获TypeError:Can not读取属性'length'of undefined 。我的努力来解析这些数据源于发生在代码中的'svg.append(path)点的另一个错误,即错误:< path>属性d: ,MNaN,NaNLNaN,NaNL ...



Uggghhhh!观众请帮助我识别我做错了什么和如何解决它。¡Muchas Gracias!



// =============已附加01 ======================



我可以使用了!



我将在下面发布修改后的工作代码,但对于这篇文章的任何人,我想解释一下,我发现了什么。



在链接的帖子标记(在为D3.js转换数据时使用forEeach()循环的替代方法)建议更改dataset.push()以删除所有的引号。



这是修改后的代码:

 

//〜填充'dataset':
var dataset = [];
$ .get(url,function(data){
var itemCount = data.Items.length;
var commaCount = itemCount - 1;
for(i = 0; 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()
。范围([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 height +))
.call(xAxis);

svg.append(g)
.attr(class,y axis)
.call(yAxis)
.append )
.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 ,line);
});

// ~~~格式日期:
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;
};


解决方案

问题是你传递的日期格式为: / p>

'2016/07/12 15:58:40'



和您解析的解析函数它是(注意日期中没有连字符):

  var parseDate = d3.time.format(%Y- %m-%d%H:%M:%S)。 

它应该是

  var parseDate = d3.time.format(%Y /%m /%d%H:%M:%S)。 



下一个错误是,您正在传递数据以获取扩展,但未在任何位置定义:

  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;
}));

工作代码此处


Hello my StackOverflow friends:

It is time to ask for help. I have been studying D3.js for weeks and am just beginning to feel like I understand 10% of it (ha, ha, ha). I am trying to generate a very simple line graph. I am able to do this as long as the data is very simple, but my raw data source has UTC timestamps, and real/decimal numbers that keeps crashing anything beyond simple.

The raw data source looks like this:


    {
      "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"
    }

Using jQuery and a javascript time formatting function I am able to assemble the following simplified dataset:


    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}
    ];

Here is my code:


    //~ 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;
        };

The first error occurs at the 'dataset.forEach()' function, which is "Uncaught TypeError: Cannot read property 'length' of undefined". My effort there to parse that data stems from another error that occurs at the 'svg.append("path")' point in the code, which is "Error: <path> attribute d: Expected number, "MNaN,NaNLNaN,NaNL…".

Uggghhhh! (:-C). If there are any D3.js mentors in the audience please help me identify what I am doing wrong and how to fix it. ¡Muchas Gracias!

// ============= APPENDED 01 ========================

I got it working!! Yeee Haaaw!

I will post the revised working code below. But for anyone following this post I wanted to explain, what I found.

Mark at the linked post (Alternatives for using forEeach() loop while converting data for D3.js) suggested altering the dataset.push() to drop all the quotes. This gave me objects instead of strings. After some troubleshooting it finally displayed as expected (totally psyched!), and thanks Mark, your suggestions did the trick.

Here is the revised code:


    //~ 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;
      };

解决方案

The problem is the date you are passing is in this format:

'2016/07/12 15:58:40'

and the parsedate function you have made to parse it is(Note there is no hyphen in the date):

var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;

it should have been

 var parseDate = d3.time.format("%Y/%m/%d %H:%M:%S").parse;

Next bug is, you are passing data for getting the extent, but its not defined anywhere:

 x.domain(d3.extent(data, function(d) { return d.theTime; }));
 y.domain(d3.extent(data, function(d) { return d.theValue;}));

It should have been:

x.domain(d3.extent(dataset, function(d) {
  return d.theTime;
}));
y.domain(d3.extent(dataset, function(d) {
  return d.theValue;
}));

working code here

这篇关于使用D3.js解析时间系列数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆