D3JS:在时间序列数据中插补缺失时间值为null [英] D3JS: Interpolating missing time value as null in time series data

查看:196
本文介绍了D3JS:在时间序列数据中插补缺失时间值为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图绘制一个时间序列数据使用D3,并遇到与丢失时间戳和宽度调整的问题。数据通常每5分钟后发生,但由于某些原因,有时您可能没有时间戳。 (例如,在下午11:45之后,下一时间戳将是23:45)。我想在中间有一个缺口,而不是连接他们在那段时间的线。我想我必须在一个新的数组中每隔5分钟一个空值,并使用它来绘制图表。



解决方案

我已经做了类似的事情,基于一些固定的时间跨度组合数据,我想在你的情况下,将是15分钟。类似这样:

 函数group_data_missing(arr){
//将数据分组到桶中,正确处理
var timespan;
//这给出15分钟(毫秒)
timespan = 15 * 60 * 1000;
var dg = [];
var group = [arr [0]];
for(var i = 1; i if(arr [i] .date.getTime() - arr [i-1] .date.getTime ; timespan){
dg.push(group);
group = [];
} else {
group.push(arr [i]);
}
}
dg.push(group);
return dg;
}



这将创建一个数组数组,每个数组都是一个线段连续15分钟。然后分别绘制每个。



或者,如果您有一些连续的日期范围,并且某些实际值为null,则可以使用 .defined b $ b

I am trying to plot a time series data using D3 and running into issues with missing timestamps and width adjustment in it. The data usually comes after every 5 minutes but for some reason sometimes you can have no timestamp. (Ex. after 11:45 AM next time stamp would be 23:45). I want to have a gap in the middle instead of a line connecting them for that time period. I think i have to place a null value after every 5 minutes in a new array and use it to plot the graph. Please let me know how to go about it as i am new to d3 and java script in general

Working jsfiddle to illustrate the issue

Code:

var data = [
{"mytime": "2015-12-01T11:10:00.000Z", "value": 64},
{"mytime": "2015-12-01T11:15:00.000Z", "value": 67},
{"mytime": "2015-12-01T11:20:00.000Z", "value": 70},
{"mytime": "2015-12-01T11:25:00.000Z", "value": 64},
{"mytime": "2015-12-01T11:30:00.000Z", "value": 72},
{"mytime": "2015-12-01T11:35:00.000Z", "value": 75},
{"mytime": "2015-12-01T11:40:00.000Z", "value": 71},
{"mytime": "2015-12-01T11:45:00.000Z", "value": 80},
{"mytime": "2015-12-01T11:45:00.000Z", "value": 80},
{"mytime": "2015-12-02T11:45:00.000Z", "value": 80},
{"mytime": "2015-12-02T11:45:00.000Z", "value": 80}
];
var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ").parse;

data.forEach(function(d) {
          d.mytime = parseDate(d.mytime);
        });
//var margin = { top: 30, right: 30, bottom: 40, left:50 },
var margin = { top: 30, right: 30, bottom: 40, left:50 },
height = 200,
width = 800;
var color =  "green";
var xaxis_param = "mytime";
var yaxis_param = "value"
var params1 =  {margin:margin,height:height,width:width, color: color, xaxis_param:xaxis_param, yaxis_param :yaxis_param};
draw_graph(data,params1);




function  draw_graph(data,params){


    //Get the margin 
    var xaxis_param = params.xaxis_param;
    var yaxis_param = params.yaxis_param;
    var color_code = params.color;
    var margin = params.margin;
    var height = params.height - margin.top - margin.bottom,
        width = params.width - margin.left - margin.right;

    console.log("1")

    var x_extent = d3.extent(data, function(d){
        return d[xaxis_param]});
    console.log("2")
    var y_extent = d3.extent(data, function(d){
        return d[yaxis_param]});

    var x_scale = d3.time.scale()
        .domain(x_extent)
        .range([0,width]);

    console.log("3")

    var y_scale = d3.scale.linear()
        .domain([0,y_extent[1]])
        .range([height,0]);



    //Line
    var lineGen = d3.svg.line()
        .x(function (d) {
            return x_scale(d[xaxis_param]);
        })
        .y(function (d) {
            return y_scale(d[yaxis_param]);
        });
    var myChart = d3.select('body').append('svg')
                    .style('background', '#E7E0CB')
                    .attr('width', width + margin.left + margin.right)
                    .attr('height', height + margin.top + margin.bottom)
                    .append('g')
                    .attr('transform', 'translate('+ margin.left +', '+ margin.top +')');
            myChart
                    .append('svg:path')
                    .datum(data)
                    .attr('class', 'line')
                    .attr("d",lineGen)
                    .attr('stroke', color_code)
                    .attr('stroke-width', 1)
                    .attr('fill', 'none');


    var legend = myChart.append("g")
          .attr("class", "legend")
          .attr("transform", "translate(" + 5 + "," + (height - 25) + ")")

        legend.append("rect")
          .style("fill", color_code)
          .attr("width", 20)
          .attr("height", 20);

        legend.append("text")
          .text(yaxis_param)
          .attr("x", 25)
          .attr("y", 12);

    var vGuideScale = d3.scale.linear()
        .domain([0,y_extent[1]])
        .range([height, 0])

    var vAxis = d3.svg.axis()
        .scale(vGuideScale)
        .orient('left')
        .ticks(5)


    var hAxis = d3.svg.axis()
        .scale(x_scale)
        .orient('bottom')
        .ticks(d3.time.minute, 5);

  myChart.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(hAxis);

  myChart.append("g")
      .attr("class", "y axis")
      .call(vAxis)


}

Edit: Below is the image for data set (As you can see when i have null value the graph is discontinuous but in actual data i wont have the timestamps for those null values it would go from 23:45 to 00:00)

var data = [{"mytime": "2015-12-01T23:10:00.000Z", "value": 64},
{"mytime": "2015-12-01T23:15:00.000Z", "value": 67},
{"mytime": "2015-12-01T23:20:00.000Z", "value": 70},
{"mytime": "2015-12-01T23:25:00.000Z", "value": 64},
{"mytime": "2015-12-01T23:30:00.000Z", "value": 72},
{"mytime": "2015-12-01T23:35:00.000Z", "value": 75},
{"mytime": "2015-12-01T23:40:00.000Z", "value": 71},
{"mytime": "2015-12-01T23:45:00.000Z", "value": 80},
{"mytime": "2015-12-01T23:50:00.000Z", "value": null},
{"mytime": "2015-12-01T23:55:00.000Z", "value": null},
{"mytime": "2015-12-02T00:00:00.000Z", "value": 80},
{"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
];

解决方案

I've done something similar by grouping the data together based on some fixed timespan, I think in your case it would be 15 minutes. Something like this:

function group_data_missing (arr) {
    // Group the data into buckets so that missing data is handled properly
    var timespan;
    //this gives 15 minutes in milliseconds
    timespan = 15 * 60 * 1000;
    var dg = [];
    var group = [arr[0]];
    for (var i=1; i<arr.length; i++) {
      if (arr[i].date.getTime() - arr[i-1].date.getTime() > timespan) {
        dg.push(group);
        group = [];
      } else { 
        group.push(arr[i]);
      }
    }
    dg.push(group);
    return dg;
  }

This will create an array of arrays, each one being a line segment that is continuous up to 15 minutes. Then just plot each one separately.

Alternatively, if you have a continuous range of dates with some of the actual values that are null, you can use the .defined method on the line definition.

这篇关于D3JS:在时间序列数据中插补缺失时间值为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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