dc.js lineChart - 显示零,其中没有数据

时间:2018-05-11 16:48:51

标签: dc.js linechart

我有一个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?

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

谢谢!

1 个答案:

答案 0 :(得分:1)

您使用ensure_group_bins走在正确的轨道上,但不是事先知道所需的一组箱子,在这种情况下我们需要计算它们。

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

然后我们需要将该集合与原始组中的bin进行合并排序。也许我稍微过度设计了这个,但这是一个功能:

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。

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