dc.js lineChart-填写缺少的日期并在没有数据的地方显示零 [英] dc.js lineChart - fill missing dates and show zero where no data

查看:60
本文介绍了dc.js lineChart-填写缺少的日期并在没有数据的地方显示零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a dc.js lineChart that is showing the number of events per hour. I would like rather than joining the line between two known values the value should be shown as zero.

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

So for the data below I would like to have the line drop to zero for 10AM

{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中尝试的示例

I've had a look at defined but don't think that is right, I think I need to add the zero value into the data for each hour that has no data? However I'm not sure how to go about it and I can't seem to find an example of what I'm trying within dc.js

这个其他问题确实回答了这个问题,但是对于d3.js,我不确定如何翻译-

This other question does answer this but for d3.js and I'm unsure how to translate that - d3 linechart - Show 0 on the y-axis without passing in all points?

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

Can anyone point me in the right direction?

谢谢!

推荐答案

您使用 ensure_group_bins 处在正确的轨道上,但是在这种情况下,我们无需预先知道所需的垃圾箱集合,而是需要计算他们.

You are on the right track with ensure_group_bins but instead of knowing the required set of bins beforehand, in this case we need to calculate them.

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

Luckily d3 provides interval.range which returns an array of dates for every interval boundary between two dates.

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

Then we need to merge-sort that set with the bins from the original group. Perhaps I have over-engineered this slightly, but here is a function to do that:

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;
    }
  }
}

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

Basically we iterate over both the original bins and the target bins, and take whichever is lower. If they are the same, then we increment both counters; otherwise we just increment the lower one.

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

Finally, when either array has run out, we append all remaining results from the other array.

这是一个基于您的代码的小提琴示例.

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

It's written in D3v4 but you should only have to change d3.timeHour in two places to d3.time.hour to use it with D3v3.

我将此功能添加到FAQ中!

I'll add this function to the FAQ!

这篇关于dc.js lineChart-填写缺少的日期并在没有数据的地方显示零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆