dc.js - 图表不呈现(单行条形图 - 水平行),图例、轴和刻度线除外 marks/values(呈现)

dc.js - Chart not rendering (single row bar chart - horizontal row), with the exception of legend, axes and tick marks/values (which do render)

场景

我想查看我的 dc.js 水平行堆叠条形图(单行图),但没有显示任何图表,除了带有名称的图例、带有刻度线的轴确实出现了。

截图

下面代码段中的数据集

问题

如何使用 dc.js / d3.js 渲染确保图表渲染成功?

代码段

$scope.avgCycleTime = function(){


    var data = [ 
                    {"Project":"Expedition","Stage": "Created", "Days":12},
                    {"Project":"Expedition","Stage": "Active", "Days":14},
                    {"Project":"Expedition","Stage": "Closure", "Days":2}
    ];
    var ndx = crossfilter(data);

    data.forEach(function(x) {
      x.Days = 0;
    });

    var ndx = crossfilter(data)

    var xdim = ndx.dimension(function (d) {return d.Days;}); 

    function root_function(dim,stack_names) {
        return dim.group().reduce(
      function(p, v) {
        stack_names.forEach(stack_name => {
          if(v[stack_name] !== undefined)
              p[stack_name] = (p[v[stack_name]] || 0) + v[stack_name]
        });
        return p;}, 
      function(p, v) {
        stack_names.forEach(stack_name => {
          if(v[stack_name] !== undefined)
              p[stack_name] = (p[v[stack_name]] || 0) + v[stack_name]
        });
        return p;}, 
      function() {
        return {};
      });}

    var stages = ['Created', 'Active', 'Closure'];
    var ygroup = root_function(xdim,stages)

    function sel_stack(i) {
    return function(d) {
      return d.value[i];
    };}

    cycleChart = new dc.barChart("#risk-cycle-chart");


    var chart = document.getElementById('risk-cycle-chart'); 


    heightStatusChart =  200;
    widthStatusChart = Math.floor(parseFloat(window.getComputedStyle(chart, null).width))
     - 2*parseInt(window.getComputedStyle(chart, null).getPropertyValue('padding-top'));    


    cycleChart
      .x(d3.scaleLinear().domain([0,7,14,21,28]))
      .dimension(xdim)
      .group(ygroup, data[0].Project, sel_stack(data[0].Project))
      .xUnits(dc.units.ordinal)
      .margins({left:75, top: 0, right: 0, bottom: 20})
      .width(widthStatusChart) 
      .height(heightStatusChart)
      .legend(dc.legend());


    for(var i = 1; i<stages.length; ++i)
      cycleChart.stack(ygroup, stages[i], sel_stack(stages[i]));

}

唉,我想 dc.js 和 crossfilter 的学习曲线很陡。这里没有任何 "interesting" 问题,只有一些小故障:

  1. dc.barChart 不是构造函数。使用 new dc.BarChart(...)dc.barChart(...)
  2. 您正在清零 d.Days,这是您的维度使用的字段,因此将只有一个 bin。
  3. 您的 x 比例应该与您的 xUnits 匹配,所以 d3.scaleOrdinal 而不是 d3.scaleLinear
  4. 您已将数据从 CreatedActiveClosure 的单独字段更改为一个名为 Stage 的字段。使用这种格式的数据,您的减速器可能看起来像

    function root_function(dim, stack_field, stack_names) {
      return dim.group().reduce(
        function(p, v) {
          p[v[stack_field]] = p[v[stack_field]] + 1; // 2
          return p;},
        function(p, v) {
          p[v[stack_field]] = p[v[stack_field]] - 1; // 3
          return p;}, 
        function() {
          return Object.fromEntries(stack_names.map(sn => [sn,0])); // 1
        });}
    
    1. 用值为 0
    2. 的每个 stack_names 的字段初始化每个 bin
    3. 将行添加到数据桶时,使用 stack_field 确定它影响哪个字段;增加该字段
    4. 从 bin 中删除一行时,以相同的方式递减
  5. 您正在请求 [0,7,14,21,28] 的 x 域,但 Days 的 none 正好符合这些值。如果你想向下舍入,你可以这样做

    var xdim = ndx.dimension(function (d) {return Math.floor(d.Days/7)*7;}); 
    
  6. .group(ygroup, data[0].Project, sel_stack(data[0].Project)) 没有意义,因为您是按 Stage 堆叠,而不是 Project;这应该是 .group(ygroup, stages[0], sel_stack(stages[0]))

通过上述更改,我们得到一个图表,前三个箱子各有一个堆栈:

Demo fiddle.

我没有为这个网格部分使用像 d3/dc 这样的矢量图形生成器,而是像这样创建了一个 table。

 $scope.avgCycleTime = function(){


    var data = [ 
                    {"Project":"Expedition","Stage": "Created", "Days":12, "Color": "rgb(166, 206, 227)"},
                    {"Project":"Expedition","Stage": "Active", "Days":14, "Color": "rgb(253, 180, 98)"},
                    {"Project":"Expedition","Stage": "Closure", "Days":2, "Color": "rgb(179, 222, 105)"}
    ];


    var tbl = document.createElement("table");
    var tblBody = document.createElement("tbody");

    // table row creation
    var row = document.createElement("tr");

    for (var i = 0; i <= 2; i++) {
      // create element <td> and text node 
      //Make text node the contents of <td> element
      // put <td> at end of the table row
      var cell = document.createElement("td");
      cell.setAttribute('style', 'width: ' + data[i].Days * 100 + "px; background-color: " + data[i].Color);
      var cellText = document.createTextNode(data[i].Stage + " " + data[i].Days);

      cell.appendChild(cellText);
      row.appendChild(cell);
    }

    //row added to end of table body
    tblBody.appendChild(row);

      // append the <tbody> inside the <table>
      tbl.appendChild(tblBody);
      // put <table> in the <body>
      document.querySelector("#risk-cycle-chart").appendChild(tbl);



}