dc.js lineChart-填写缺少的日期,在没有数据的地方显示零

问题描述 投票:1回答:1

我有一个dc.js lineChart,它显示每小时的事件数。我希望与其将两个已知值之间的线连接起来,不应该将其显示为零。

因此,对于下面的数据,我希望在上午10点将行降为零

{datetime: "2018-05-01 09:10:00", event: 1}
{datetime: "2018-05-01 11:30:00", event: 1}
{datetime: "2018-05-01 11:45:00", event: 1}
{datetime: "2018-05-01 12:15:00", event: 1}

var eventsByDay = facts.dimension(function(d) { return d3.time.hour(d.datetime);});
var eventsByDayGroup = eventsByDay.group().reduceCount(function(d) { return d.datetime; });  

我看过定义的内容,但认为这是不对的,我想我需要为没有数据的每小时增加零值到数据中吗?但是,我不确定该如何处理,而且似乎找不到在dc.js中尝试的示例]

另一个问题的确回答了这个问题,但对于d3.js,我不确定如何翻译-d3 linechart - Show 0 on the y-axis without passing in all points?

有人能指出我正确的方向吗?

谢谢!

dc.js linechart
1个回答
1
投票

您使用ensure_group_bins处在正确的轨道上,但是在这种情况下,我们无需计算所需的一组bin,在这种情况下,我们需要对其进行计算。

幸运的是,d3提供了interval.range,它为两个日期之间的每个时间间隔边界返回一个日期数组。

然后,我们需要与原始组中的垃圾箱进行合并排序。也许我对此做了一些过度设计,但是这里有一个函数可以做到这一点:

function fill_intervals(group, interval) {
  return {
    all: function() {
      var orig = group.all().map(kv => ({key: new Date(kv.key), value: kv.value}));
      var target = interval.range(orig[0].key, orig[orig.length-1].key);
      var result = [];
      for(var oi = 0, ti = 0; oi < orig.length && ti < target.length;) {
        if(orig[oi].key <= target[ti]) {
          result.push(orig[oi]);
          if(orig[oi++].key.valueOf() === target[ti].valueOf())
            ++ti;
        } else {
          result.push({key: target[ti], value: 0});
          ++ti;
        }
      }
      if(oi<orig.length)
        Array.prototype.push.apply(result, orig.slice(oi));
      if(ti<target.length)
        Array.prototype.push.apply(result, target.slice(ti).map(t => ({key: t, value: 0})));
      return result;
    }
  }
}

[基本上,我们迭代原始垃圾箱和目标垃圾箱,并取其中较低的那个。如果它们相同,则我们增加两个计数器;否则我们只增加下一个。

最后,当任一数组用完时,我们将附加来自另一个数组的所有剩余结果。

Here is an example fiddle based on your code.

[它是用D3v4编写的,但您只需要将d3.timeHour在两个地方更改为d3.time.hour即可与D3v3一起使用。

我将此功能添加到常见问题解答!

© www.soinside.com 2019 - 2024. All rights reserved.