d c. js - диаграмма не отображается (столбчатая диаграмма с одной строкой - горизонтальная строка), за исключением легенды, осей и отметок / значений галочек (которые отображают) - PullRequest
1 голос
/ 17 февраля 2020

Сценарий

Я хочу видеть мою столбчатую диаграмму с горизонтальными строками d c. js (однострочный график), но диаграмма не появляется, за исключением легенды с именами , оси с отметками, которые появляются.

Снимок экрана

enter image description here

Данные приведены ниже во фрагменте кода

Вопрос

Как успешно выполнить рендеринг для обеспечения диаграммы с использованием d c. 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]));

}

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Вздох, я думаю, у d c. js и кроссфильтр крутая кривая обучения. Здесь нет никаких «интересных» проблем, просто куча мелких глюков:

  1. dc.barChart не является конструктором. Используйте new dc.BarChart(...) или dc.barChart(...)
  2. Вы обнуляете d.Days, это поле, используемое вашим измерением, поэтому будет только один бин.
  3. Ваша шкала x должна соответствовать ваш xUnits, поэтому d3.scaleOrdinal не d3.scaleLinear.
  4. Вы изменили свои данные, чтобы иметь отдельные поля для Created, Active, Closure на одно поле с именем 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. Инициализируйте каждый контейнер с полем для каждого из stack_names со значением 0
    2. При добавлении строки в корзина, определить, на какое поле она влияет, используя stack_field; увеличивать это поле
    3. При удалении строки из ячейки уменьшать аналогичным образом
  5. Вы запрашиваете домен x [0,7,14,21,28], но ни один из ваших Days попадают именно на эти значения. Если вы хотите округлить, вы можете сделать

    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]))

С учетом вышеуказанных изменений мы получаем диаграмму с одним стеком в каждом из первых трех бинов:

screenshot of working chart

Демонстрационная скрипка .

0 голосов
/ 18 февраля 2020

Я не использовал генератор векторной графики, такой как d3 / d c, для этой части сетки и вместо этого создал таблицу, подобную этой.

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



}
...