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

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

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

  1. var data = [{"mytime": "2015-12-01T23:10:00.000Z", "value": 64},
  2. {"mytime": "2015-12-01T23:15:00.000Z", "value": 67},
  3. {"mytime": "2015-12-01T23:20:00.000Z", "value": 70},
  4. {"mytime": "2015-12-01T23:25:00.000Z", "value": 64},
  5. {"mytime": "2015-12-01T23:30:00.000Z", "value": 72},
  6. {"mytime": "2015-12-01T23:35:00.000Z", "value": 75},
  7. {"mytime": "2015-12-01T23:40:00.000Z", "value": 71},
  8. {"mytime": "2015-12-01T23:45:00.000Z", "value": 80},
  9. {"mytime": "2015-12-02T00:00:00.000Z", "value": 80},
  10. {"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
  11. ];
  12. var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ").parse;
  13. data.forEach(function(d) {
  14. d.mytime = parseDate(d.mytime);
  15. });
  16. var act_data = [];
  17. var x_extent = d3.extent(data, function(d){
  18. return d['mytime']});
  19. time_arr = d3.time.minute.range(x_extent[0],x_extent[1],5);
  20. for(var key in time_arr){
  21. var temp;
  22. temp = contains(data,time_arr[key],'mytime');
  23. }
  24. function contains(data,value,variable)
  25. {
  26. var i =data.length;
  27. while(i--){
  28. if (data[i][variable] === value)
  29. {
  30. console.log('found');
  31. return i;
  32. }
  33. }
  34. return false;
  35. }

字符串
输出应为:

  1. data = [{"mytime": "2015-12-01T23:10:00.000Z", "value": 64},
  2. {"mytime": "2015-12-01T23:15:00.000Z", "value": 67},
  3. {"mytime": "2015-12-01T23:20:00.000Z", "value": 70},
  4. {"mytime": "2015-12-01T23:25:00.000Z", "value": 64},
  5. {"mytime": "2015-12-01T23:30:00.000Z", "value": 72},
  6. {"mytime": "2015-12-01T23:35:00.000Z", "value": 75},
  7. {"mytime": "2015-12-01T23:40:00.000Z", "value": 71},
  8. {"mytime": "2015-12-01T23:45:00.000Z", "value": 80},
  9. {"mytime": "2015-12-01T23:50:00.000Z", "value": null},
  10. {"mytime": "2015-12-01T23:55:00.000Z", "value": null},
  11. {"mytime": "2015-12-02T00:00:00.000Z", "value": 80},
  12. {"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
  13. ];

qeeaahzv

qeeaahzv1#

你可以这样做:

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

字符串
工作代码here

展开查看全部
kninwzqo

kninwzqo2#

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

  1. data[Symbol.iterator] = function*() {
  2. var i = 0,
  3. t = this[0],
  4. nextStep;
  5. while (i < this.length) {
  6. nextStep = t.mytime.getTime() + FIVE_MINUTES_IN_MS;
  7. yield t = nextStep < this[i].mytime.getTime()
  8. ? {"mytime": new Date(nextStep), "value": null}
  9. : this[i++];
  10. }
  11. };
  12. // use the spread operator to create a new array which will implicitly call
  13. // the iterator
  14. data = [...data];

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

  1. "use strict";
  2. ///////////////////////////////////////////////////////////////////////////
  3. // Setup
  4. ///////////////////////////////////////////////////////////////////////////
  5. const FIVE_MINUTES_IN_MS = 5 * 60 * 1000;
  6. var data = [
  7. {"mytime": "2015-12-01T23:10:00.000Z", "value": 64},
  8. {"mytime": "2015-12-01T23:15:00.000Z", "value": 67},
  9. {"mytime": "2015-12-01T23:20:00.000Z", "value": 70},
  10. {"mytime": "2015-12-01T23:25:00.000Z", "value": 64},
  11. {"mytime": "2015-12-01T23:30:00.000Z", "value": 72},
  12. {"mytime": "2015-12-01T23:35:00.000Z", "value": 75},
  13. {"mytime": "2015-12-01T23:40:00.000Z", "value": 71},
  14. {"mytime": "2015-12-01T23:45:00.000Z", "value": 80},
  15. {"mytime": "2015-12-02T00:00:00.000Z", "value": 80},
  16. {"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
  17. ];
  18. var parse = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ").parse;
  19. data.forEach(function(d) {
  20. d.mytime = parse(d.mytime);
  21. });
  22. ///////////////////////////////////////////////////////////////////////////
  23. // Implement iterator to fill in gaps in data array
  24. ///////////////////////////////////////////////////////////////////////////
  25. data[Symbol.iterator] = function*() {
  26. var i = 0,
  27. t = this[0],
  28. nextStep;
  29. while (i < this.length) {
  30. nextStep = t.mytime.getTime() + FIVE_MINUTES_IN_MS;
  31. yield t = nextStep < this[i].mytime.getTime()
  32. ? {"mytime": new Date(nextStep), "value": null}
  33. : this[i++];
  34. }
  35. };
  36. // use the spread operator to create a new array which will implicitly call the iterator
  37. data = [...data];
  38. ///////////////////////////////////////////////////////////////////////////
  39. // Just output below.
  40. ///////////////////////////////////////////////////////////////////////////
  41. //console.dir(data);
  42. d3.select("body").append("div")
  43. .style({
  44. "font-family": "monospace",
  45. "white-space": "pre"
  46. })
  47. .text(JSON.stringify(data, null, 2));
  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

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

  1. data[Symbol.iterator] = function() {
  2. var self = this;
  3. return {
  4. i: 0,
  5. t: self[0],
  6. next() {
  7. if (this.i < self.length) {
  8. var nextStep = this.t.mytime.getTime() + FIVE_MINUTES_IN_MS;
  9. this.t = nextStep < self[this.i].mytime.getTime()
  10. ? { "mytime": new Date(nextStep), "value": null }
  11. : self[this.i++];
  12. return {
  13. value: this.t,
  14. done: false
  15. }
  16. } else {
  17. return {
  18. done: true
  19. }
  20. }
  21. }
  22. }
  23. };


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

  1. "use strict";
  2. ///////////////////////////////////////////////////////////////////////////
  3. // Setup
  4. ///////////////////////////////////////////////////////////////////////////
  5. const FIVE_MINUTES_IN_MS = 5 * 60 * 1000;
  6. var data = [
  7. {"mytime": "2015-12-01T23:10:00.000Z", "value": 64},
  8. {"mytime": "2015-12-01T23:15:00.000Z", "value": 67},
  9. {"mytime": "2015-12-01T23:20:00.000Z", "value": 70},
  10. {"mytime": "2015-12-01T23:25:00.000Z", "value": 64},
  11. {"mytime": "2015-12-01T23:30:00.000Z", "value": 72},
  12. {"mytime": "2015-12-01T23:35:00.000Z", "value": 75},
  13. {"mytime": "2015-12-01T23:40:00.000Z", "value": 71},
  14. {"mytime": "2015-12-01T23:45:00.000Z", "value": 80},
  15. {"mytime": "2015-12-02T00:00:00.000Z", "value": 80},
  16. {"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
  17. ];
  18. var parse = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ").parse;
  19. data.forEach(function(d) {
  20. d.mytime = parse(d.mytime);
  21. });
  22. ///////////////////////////////////////////////////////////////////////////
  23. // Implement iterator to fill in gaps in data array
  24. ///////////////////////////////////////////////////////////////////////////
  25. data[Symbol.iterator] = function() {
  26. var self = this;
  27. return {
  28. i: 0,
  29. t: self[0],
  30. next() {
  31. if (this.i < self.length) {
  32. var nextStep = this.t.mytime.getTime() + FIVE_MINUTES_IN_MS;
  33. this.t = nextStep < self[this.i].mytime.getTime()
  34. ? { "mytime": new Date(nextStep), "value": null }
  35. : self[this.i++];
  36. return {
  37. value: this.t,
  38. done: false
  39. }
  40. } else {
  41. return {
  42. done: true
  43. }
  44. }
  45. }
  46. }
  47. };
  48. // use the spread operator to create a new array which will implicitly call the iterator
  49. data = [...data];
  50. ///////////////////////////////////////////////////////////////////////////
  51. // Just output below.
  52. ///////////////////////////////////////////////////////////////////////////
  53. //console.dir(data);
  54. d3.select("body").append("div")
  55. .style({
  56. "font-family": "monospace",
  57. "white-space": "pre"
  58. })
  59. .text(JSON.stringify(data, null, 2));
  1. <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对输入进行散列并确定值是否存在

这给了我们

  1. var data = [...];
  2. // for parsing and formatting
  3. var timeformat = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ");
  4. // range to operate on
  5. var extent = d3.extent(data, function(d){
  6. return timeformat.parse(d.mytime);
  7. });
  8. // scale representing the time stamps
  9. var scale = d3.time.scale()
  10. .domain(extent) // the boundaries
  11. .ticks(d3.time.minute, 5); // 5 minutes intervals
  12. // easier to determine if a value exists
  13. var hashed = d3.map(data, function(d) { return d.mytime; });
  14. // or if your version < 3.5
  15. /*
  16. var hashed = d3.map();
  17. data.forEach(function(d) {
  18. hashed.set(d.mytime, d);
  19. });
  20. */
  21. // transforms the scale into the desired output
  22. var res = scale.map(function(t) {
  23. var ft = timeformat(t);
  24. return {
  25. mytime: ft,
  26. value: (hashed.has(ft)) ? hashed.get(ft).value : null
  27. };
  28. });

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

  1. var data = [
  2. {"mytime": "2015-12-01T23:10:00.000Z", "value": 64},
  3. {"mytime": "2015-12-01T23:15:00.000Z", "value": 67},
  4. {"mytime": "2015-12-01T23:20:00.000Z", "value": 70},
  5. {"mytime": "2015-12-01T23:25:00.000Z", "value": 64},
  6. {"mytime": "2015-12-01T23:30:00.000Z", "value": 72},
  7. {"mytime": "2015-12-01T23:35:00.000Z", "value": 75},
  8. {"mytime": "2015-12-01T23:40:00.000Z", "value": 71},
  9. {"mytime": "2015-12-01T23:45:00.000Z", "value": 80},
  10. {"mytime": "2015-12-02T00:00:00.000Z", "value": 80},
  11. {"mytime": "2015-12-02T00:05:00.000Z", "value": 85}
  12. ];
  13. var timeformat = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ");
  14. var extent = d3.extent(data, function(d){
  15. return timeformat.parse(d.mytime);
  16. });
  17. var scale = d3.time.scale()
  18. .domain(extent)
  19. .ticks(d3.time.minute, 5);
  20. var hashed = d3.map();
  21. data.forEach(function(d) {
  22. hashed.set(d.mytime, d);
  23. });
  24. var res = scale.map(function(t) {
  25. var ft = timeformat(t);
  26. return {
  27. mytime: ft,
  28. value: (hashed.has(ft)) ? hashed.get(ft).value : null
  29. };
  30. });
  31. var $table = $('<table></table>');
  32. res.forEach(function(d) {
  33. $table.append('<tr><td>'+d.mytime+'</td><td>'+d.value+'</td></tr>')
  34. });
  35. $('body').append($table);
  1. <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  2. <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

的数据

展开查看全部

相关问题