1

我试图从一个带有数据的大 tsv 中获得很多可视化选项。我正在使用 d3 创建很多很酷的统计数据。

数据结构如下:item,startdate,enddate,value

所以,假设我们在 12 月/1 月有 3 个类似项目的列表:

gasoline,20-12-2009,10-01-2010,400
gasoline,01-01-2010,31-01-2010,1000
gasoline,21-01-2010,31-01-2010,900

如您所见,大多数完全是在 1 月,但第一项是在前一年的 12 月。因此,如果我想要 1 月 400+1000+900 的总数是不正确的。

我可以每天解析数据并单独输入,但这并不能保证未来的发展,而且我可能会遇到令人讨厌的舍入错误。

在加载时我这样做:

data.forEach(function(d) {
    d.startdate = StatsLoader.format.parse(String(d.startdate));
    d.enddate = StatsLoader.format.parse(String(d.enddate));
    d.period = (d.enddate - d.startdate) / StatsLoader.periodSize; // 86400000, 1 day in ms
    d.value = +d.value;
});

所以我有一个很好的对象,它有一个名称、开始和结束日期、一个值,而且我知道以天为单位的时间段。

现在我想得到一个日期范围内的总和,但我不知道从哪里开始。

我正常的“求和”函数看起来像这样(假设有多个项目名称)

var nest = d3.nest()
    .key(function(d) { return d.item; })
    .entries(data);

var piechartData = [];
nest.forEach(function(n) {
    piechartData.push({
    name: n.key,
    value: d3.sum(n.values, function(d) { return d.value; })
    })
})

我觉得我应该以某种方式使用量化?还是域名?

谢谢!

4

1 回答 1

0

假设您有一个由开始日期和结束日期给出的日期范围,计算(部分)总和的代码将是这样的。

function getTotal(range, data) {
  var sum = 0;
  data.forEach(function(d) {
    if(d.startdate <= range.startdate && d.enddate >= range.enddate) {
      var duration = (Math.min(d.enddate, range.enddate) -
                     Math.max(d.startdate, range.startdate)) / StatsLoader.periodSize;
      sum += d.value / d.period * duration;
    }
  });
  return sum;
}

您当然可以优化此代码。这适用于任意范围。

于 2013-10-02T17:09:44.707 回答