比较D3.js中的两个时间对象

wvyml7n5  于 2023-11-19  发布在  其他
关注(0)|答案(3)|浏览(101)

在D3.js中,我目前正在尝试根据数据数组是否包含时间来填充一个空数组(数组只包含每5分钟后的时间戳)。如果数据数组包含时间,它应该复制值,否则为null。但是当我尝试比较两个时间对象时,它无法正常工作。
以下是代码(当前代码不是复制值,而是打印以使调试更容易):

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-02T00:00:00.000Z", "value": 80},
{"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
];

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

data.forEach(function(d) {
          d.mytime = parseDate(d.mytime);
 });

var act_data = [];

  var x_extent = d3.extent(data, function(d){
      return d['mytime']});

  time_arr = d3.time.minute.range(x_extent[0],x_extent[1],5);
  for(var key in time_arr){
  var temp;
  temp = contains(data,time_arr[key],'mytime');
}

function contains(data,value,variable)
{
  var i =data.length;
  while(i--){

   if (data[i][variable] === value)
   {
    console.log('found');
    return i;
   } 
  }
  return false;
}

字符串
输出应为:

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

qeeaahzv

qeeaahzv1#

你可以这样做:

var extent = d3.extent(data, function(d){ return d.mydate});//get the max min limit
var data1 = []; make an empty array
for (var i =0; i < data.length -1; i++){
    var diff = data[i + 1].mytime.getTime() - data[i].mytime.getTime();
    if (diff <= 300000){ //less than equal to 5 minutes
        data1.push(data[i])
    } else { //greater than 5 minutes
      var t1 = new Date(data[i].mytime.getTime() + 300000)
        var t2 = new Date(data[i +1].mytime.getTime() - 300000)
        data1.push({"mytime": t1, "value": null})
        data1.push({"mytime": t2, "value": null})
    }
}
data1.push(data[data.length -1]); //take the last value as it was not processed
data = data1

字符串
工作代码here

kninwzqo

kninwzqo2#

随着ES6的出现,有更多的选项可以解决这个问题。根据需要支持的浏览器版本,下面的代码可能是一个可行的方法。我已经在Chrome 49和FF 45上成功测试了这个方法。
该解决方案将自定义generator function添加到data数组中,该数组将返回符合新iteration protocolsGenerator对象。这将覆盖data数组并填充它检测到的任何间隙,沿着将value属性设置为null的对象。
代码片段进一步使用spread operator创建一个新数组,并通过隐式调用迭代器填充它。

data[Symbol.iterator] = function*() {
  var i = 0,
      t = this[0],
      nextStep;
  while (i < this.length) {
    nextStep = t.mytime.getTime() + FIVE_MINUTES_IN_MS;
    yield t = nextStep < this[i].mytime.getTime()
      ? {"mytime": new Date(nextStep), "value": null}
      : this[i++];
  }
};

// use the spread operator to create a new array which will implicitly call
// the iterator
data = [...data];

字符串
看看下面的代码片段,看看在Chrome 49和FF 45中运行的演示:

"use strict";

///////////////////////////////////////////////////////////////////////////
// Setup
///////////////////////////////////////////////////////////////////////////

const FIVE_MINUTES_IN_MS = 5 * 60 * 1000;

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-02T00:00:00.000Z", "value": 80},
{"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
];

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

data.forEach(function(d) {
  d.mytime = parse(d.mytime);
});

///////////////////////////////////////////////////////////////////////////
// Implement iterator to fill in gaps in data array
///////////////////////////////////////////////////////////////////////////

data[Symbol.iterator] = function*() {
  var i = 0,
      t = this[0],
      nextStep;
  while (i < this.length) {
    nextStep = t.mytime.getTime() + FIVE_MINUTES_IN_MS;
    yield t = nextStep < this[i].mytime.getTime()
      ? {"mytime": new Date(nextStep), "value": null}
      : this[i++];
  }
};

// use the spread operator to create a new array which will implicitly call the iterator
data = [...data];

///////////////////////////////////////////////////////////////////////////
// Just output below.
///////////////////////////////////////////////////////////////////////////

//console.dir(data);

d3.select("body").append("div")
	.style({
    "font-family": "monospace",
    "white-space": "pre"
  })
  .text(JSON.stringify(data, null, 2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

的数据
或者,你可以提供一个迭代器协议的显式实现。这写起来有点冗长,但不会改变整体概念:

data[Symbol.iterator] = function() {
  var self = this;
  return {
    i: 0,
    t: self[0],
    next() {
      if (this.i < self.length) {
        var nextStep = this.t.mytime.getTime() + FIVE_MINUTES_IN_MS;
        this.t = nextStep < self[this.i].mytime.getTime()
          ? { "mytime": new Date(nextStep), "value": null }
          : self[this.i++];
        return {
          value: this.t,
          done:  false
        }
      } else {
        return {
          done: true
        }
      } 
    }
  }
};


下面的代码片段演示了这一点:

"use strict";

///////////////////////////////////////////////////////////////////////////
// Setup
///////////////////////////////////////////////////////////////////////////

const FIVE_MINUTES_IN_MS = 5 * 60 * 1000;

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-02T00:00:00.000Z", "value": 80},
{"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
];

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

data.forEach(function(d) {
  d.mytime = parse(d.mytime);
});

///////////////////////////////////////////////////////////////////////////
// Implement iterator to fill in gaps in data array
///////////////////////////////////////////////////////////////////////////

data[Symbol.iterator] = function() {
  var self = this;
  return {
    i: 0,
    t: self[0],
    next() {
      if (this.i < self.length) {
        var nextStep = this.t.mytime.getTime() + FIVE_MINUTES_IN_MS;
        this.t = nextStep < self[this.i].mytime.getTime()
          ? { "mytime": new Date(nextStep), "value": null }
          : self[this.i++];
        return {
          value: this.t,
          done:  false
        }
      } else {
        return {
          done: true
        }
      } 
    }
  }
};

// use the spread operator to create a new array which will implicitly call the iterator
data = [...data];

///////////////////////////////////////////////////////////////////////////
// Just output below.
///////////////////////////////////////////////////////////////////////////

//console.dir(data);

d3.select("body").append("div")
	.style({
    "font-family": "monospace",
    "white-space": "pre"
  })
  .text(JSON.stringify(data, null, 2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
gopyfrb3

gopyfrb33#

您可以使用(D3 3.x API

  • d3.time.format解析和格式化日期
  • d3.extent来确定时间戳的边界
  • d3.time.scale以生成要输出的分笔成交点
  • d3.map对输入进行散列并确定值是否存在

这给了我们

var data = [...];

// for parsing and formatting
var timeformat = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ");

// range to operate on
var extent = d3.extent(data, function(d){ 
    return timeformat.parse(d.mytime); 
});

// scale representing the time stamps
var scale = d3.time.scale()
    .domain(extent) // the boundaries
    .ticks(d3.time.minute, 5); // 5 minutes intervals

// easier to determine if a value exists
var hashed = d3.map(data, function(d) { return d.mytime; });

// or if your version < 3.5
/*
var hashed = d3.map();
data.forEach(function(d) { 
    hashed.set(d.mytime, d);
});
*/

// transforms the scale into the desired output
var res = scale.map(function(t) {
    var ft = timeformat(t);
    return {
        mytime: ft,
        value: (hashed.has(ft)) ? hashed.get(ft).value : null
    };
});

字符串
以及一个http://jsfiddle.net/nikoshr/qxcLry8z/演示

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-02T00:00:00.000Z", "value": 80},
{"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
];

var timeformat = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ");

var extent = d3.extent(data, function(d){ 
    return timeformat.parse(d.mytime); 
});

var scale = d3.time.scale()
    .domain(extent)
    .ticks(d3.time.minute, 5);
  
var hashed = d3.map();
data.forEach(function(d) { 
    hashed.set(d.mytime, d);
});
  
var res = scale.map(function(t) {
    var ft = timeformat(t);
    return {
        mytime: ft,
        value: (hashed.has(ft)) ? hashed.get(ft).value : null
    };
});

var $table = $('<table></table>'); 
res.forEach(function(d) {
    $table.append('<tr><td>'+d.mytime+'</td><td>'+d.value+'</td></tr>')
});
$('body').append($table);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

的数据

相关问题