D3js: How to interpolate datasets with irregular time intervals before stacking them?

寵の児 提交于 2019-12-06 04:22:51

I ran into the same problem once before. With a little bit of delicacy you can add in the missing values so that every series has the same set of x-coordinates (timestamps). I added a few lines to you jsfiddle to massage the data before you send it into the stack layout.

To start with I needed the super-set of times:

var times = [];
myData.forEach(function(d) {
  if(times.indexOf(d.date.getTime()) === -1) {
    times.push(d.date.getTime());
  }
});
times.sort();

This results in the array (from your data):

0:00, 4:00, 4:30, 4:45, 8:08, 12:08, 13:08, 16:08, 20:08

Note that at the end I sort it because this will really simplify finding the missing values in the station data series. I intend to do a kind of sorted list merge to fill in no-change data values into the series. This is what your series look like straight from the data (time value pairs):

Initial series
Station_1 0:00 37, 4:30 36, 8:08 18, 12:08 10, 16:08 32, 20:08 35
Station_2 0:00 32, 4:00 29, 8:08 6,  12:08 12, 16:08 29, 20:08 32
Station_3 0:00 36, 4:45 30, 8:08 10, 13:08 13, 16:08 32, 20:08 36
Station_4 0:00 31, 4:00 28, 8:08 12, 12:08 14, 16:08 28, 20:08 31

So for each series, walk through the time array and insert missing values, there may well be a more efficient way to do this:

myNestedData.forEach(function(stationData) {
  stationData.values.sort(function(a,b) {
      return d3.ascending(a.date.getTime(), b.date.getTime());
    });
  var j = 0;
  var lastStationValue = 0;
  for(var i = 0; i < times.length; i++) {
    // If the station series is too short I should not equal any 
    // value from the times array
    stationTime = j <= stationData.values.length ?
        stationData.values[j].date.getTime() : 0;

    if(times[i] !== stationTime) {
      // Missing values need to be spliced in.
      stationData.values.splice(j, 0, { 
          date: new Date(times[i]),
          inventory: lastStationValue,
          station_id: stationData.key
      });
      j++;
    }
    else {
      // We have a value for this time, move along.
      lastStationValue = stationData.values[j].inventory;
      j++;
    }
  }                       
});

And now the series should all line up!

Station_1 0:00 37, 4:00 37, 4:30 36, 4:45 36, 8:08 18, 12:08 10, 13:08 10, 16:08 32, 20:08 35
Station_2 0:00 32, 4:00 29, 4:30 29, 4:45 29, 8:08 6,  12:08 12, 13:08 12, 16:08 29, 20:08 32
Station_3 0:00 36, 4:00 36, 4:30 36, 4:45 30, 8:08 10, 12:08 10, 13:08 13, 16:08 32, 20:08 36
Station_4 0:00 31, 4:00 28, 4:30 28, 4:45 28, 8:08 12, 12:08 14, 13:08 14, 16:08 28, 20:08 31 

You can check out the updated fiddle here

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!