使用dc.js的日期堆积面积图

时间:2018-02-06 14:52:48

标签: javascript d3.js charts dc.js crossfilter

我正在尝试使用 dc.js 创建日期堆积区域图表。该图表应该:

  1. 按字段“event”显示不同的区域
  2. 计算每天的活动数量
  3. 这是我的代码:

    var data = [{
      "event": "Panic",
      "date": "2018-01-02"
    }, {
      "event": "Speed limit exceeded",
      "date": "2018-01-01"
    }, {
      "event": "Door opened",
      "date": "2018-01-03"
    }];
    
    var chart = dc.lineChart("#areaChart");
    var dtgFormat = d3.time.format("%Y-%m-%d");
    
    data.forEach(function(d) {
      d.dtg = dtgFormat.parse(d.date);
    });
    
    var ndx = crossfilter(data);
    var areaDim = ndx.dimension(function(d) {
      return d.dtg;
    });
    var areaGroup = areaDim.group().reduce(
      function(p, v) {
        p[v.event] = (p[v.event] || 0) + 1;
        return p;
      },
      function(p, v) {
        p[v.event] = (p[v.event] || 0) - 1;
        return p;
      },
      function() {
        return {};
      });
    
    // Get distinct
    var eventsArray = data.map(a => a.event).filter(function onlyUnique(value, index, self) {
      return self.indexOf(value) === index;
    });
    
    function sel_stack(i) {
      return function(d) {
        return d.value[i];
      };
    }
    
    chart.width(960)
      .height(150)
      .transitionDuration(500)
      .dimension(areaDim)
      .group(areaGroup, eventsArray[0], sel_stack(eventsArray[0]))
      .renderArea(true)
      .elasticY(true)
      .x(d3.time.scale().domain(d3.extent(data, function(d) {
        return d.dtg;
      })))
      .xAxis().ticks(4);
    
    for (var i = 1; i < eventsArray.length; i++)
      chart.stack(areaGroup, eventsArray[i], sel_stack(eventsArray[i]));
    
    dc.renderAll();
    

    但图表仅绘制两个轴。我错过了什么?

    这是我的jsfiddle:http://jsfiddle.net/n08e32n6/12/

1 个答案:

答案 0 :(得分:0)

dc.js的堆栈功能要求每个堆栈的每个X值都有一个值。由于某些目前为undefined,您最终会使用NaN s,然后dc.js将这些区域完全清理出来。

您需要做的就是使用所有可用键初始化reduce对象,而不是从空白对象开始。因此,您可以先计算不同的事件类型,然后使用use Array.reduce为每个事件类型创建一个零对象:

var eventsArray = data.map(a => a.event).filter(function onlyUnique(value, index, self) {
  return self.indexOf(value) === index;
});

var areaGroup = areaDim.group().reduce(
  function(p, v) {
    p[v.event] = (p[v.event] || 0) + 1;
    return p;
  },
  function(p, v) {
    p[v.event] = (p[v.event] || 0) - 1;
    return p;
  },
  function() {
    return eventsArray.reduce(function(p, v) {
      p[v] = 0;
      return p;
    }, {});
  });

working stacks

Fork of your fiddle.