снижение перекрестного фильтра падает - PullRequest
1 голос
/ 05 февраля 2020

Мне не удается отобразить объявление c. js столбчатая диаграмма с накоплением успешно, и я получаю консольную ошибку

, не могу прочитать свойство 'Total' из неопределенного

Я новичок в библиотеке и подозреваю, что моя группа или редирект не заданы успешно.

Как мне решить эту проблему?

 $scope.riskStatusByMonth = function(){

    var data = [ 
                    {"Month":"Jan","High":12},{"Month":"Jan","Med":14},{"Month":"Jan","Low":2},{"Month":"Jan","Closed":8},
                    {"Month":"Feb","High":12},{"Month":"Feb","Med":14},{"Month":"Feb","Low":2},{"Month":"Feb","Closed":8},
                    {"Month":"Mar","High":12},{"Month":"Mar","Med":14},{"Month":"Mar","Low":2},{"Month":"Mar","Closed":8},
                    {"Month":"Apr","High":12},{"Month":"Apr","Med":14},{"Month":"Apr","Low":2},{"Month":"Apr","Closed":8},
                    {"Month":"May","High":12},{"Month":"May","Med":14},{"Month":"May","Low":2},{"Month":"May","Closed":8},
                    {"Month":"Jun","High":12},{"Month":"Jun","Med":14},{"Month":"Jun","Low":2},{"Month":"Jun","Closed":8},
                    {"Month":"Jul","High":12},{"Month":"Jul","Med":14},{"Month":"Jul","Low":2},{"Month":"Jul","Closed":8},
                    {"Month":"Aug","High":12},{"Month":"Aug","Med":14},{"Month":"Aug","Low":2},{"Month":"Aug","Closed":8},
                    {"Month":"Sep","High":12},{"Month":"Sep","Med":14},{"Month":"Sep","Low":2},{"Month":"Sep","Closed":8},
                    {"Month":"Oct","High":12},{"Month":"Oct","Med":14},{"Month":"Oct","Low":2},{"Month":"Oct","Closed":8},
                    {"Month":"Nov","High":12},{"Month":"Nov","Med":14},{"Month":"Nov","Low":2},{"Month":"Nov","Closed":8},
                    {"Month":"Dec","High":8},{"Month":"Dec","Med":6},{"Month":"Dec","Low":13},{"Month":"Dec","Closed":8},
               ]

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

    var ndx = crossfilter(data)

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

    function root_function(dim,stack_name) {
        return dim.group().reduce(
      function(p, v) {
        p[v[stack_name]] = (p[v[stack_name]] || 0) + v.High;
        return p;},
        function(p, v) {
        p[v[stack_name]] = (p[v[stack_name]] || 0) + v.Med;
        return p;},
        function(p, v) {
        p[v[stack_name]] = (p[v[stack_name]] || 0) + v.Low;     <-------------------here is where error occurs
        return p;},
        function(p, v) {
        p[v[stack_name]] = (p[v[stack_name]] || 0) + v.Closed;
        return p;}, 
      function() {
        return {};
      });}

    var ydim = root_function(xdim,'Total')

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

    $scope.monthlyRiskStatus = dc.barChart("#risk-status-by-month");

    $scope.monthlyRiskStatus
      .x(d3.scaleLinear().domain(xdim))
      .dimension(xdim)
      .group(ydim, '1', sel_stack("Jan"))
      .xUnits(dc.units.ordinal);


    month = [null,'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    for(var i = 2; i<=12; ++i)
      $scope.monthlyRiskStatus.stack(ydim, ''+i, sel_stack(month[i]));

    $scope.monthlyRiskStatus.render();
}

1 Ответ

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

group.reduce () принимает три аргумента: добавить, удалить, инициализировать.

Вы передаете 5.

Похоже, он пытается вызвать третий один в качестве инициализатора, без аргументов, поэтому v не определено.

как складывать по уровням

Похоже, что вы действительно пытаетесь сделать, это группировать по месяцам ( Ось X), а затем складывается по состоянию или уровню. Вот один из способов сделать это.

Во-первых, вы находитесь на правильном пути с функцией, которая принимает имя стека, но мы хотим, чтобы она принимала все имена стеков:

function root_function(dim,stack_names) {
    return dim.group().reduce(
  function(p, v) {
    stack_names.forEach(stack_name => { // 1
      if(v[stack_name] !== undefined) // 2
          p[stack_name] = (p[v[stack_name]] || 0) + v[stack_name] // 3
    });
    return p;}, 
  function(p, v) {
    stack_names.forEach(stack_name => { // 1
      if(v[stack_name] !== undefined) // 2
          p[stack_name] = (p[v[stack_name]] || 0) + v[stack_name] // 3
    });
    return p;}, 
  function() {
    return {};
  });}
  1. В функциях добавления и сокращения мы будем l oop по всем именам стека
  2. Имена стека - это поля, которые могут существовать или не существовать в каждой строке. Если имя стека существует в текущей строке ...
  3. Мы добавим или вычтем поле строки stack_name из поля с тем же именем в текущей ячейке.

Мы определим массивы levels и months. levels будет использоваться для суммирования, а months будет использоваться для порядкового домена X:

var levels = ['High', 'Med', 'Low', 'Closed']
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

Когда мы определим группу, мы передадим levels в root_function():

var ygroup = root_function(xdim,levels)

Я вижу, у вас была некоторая путаница между английским / математическим определением "измерения" и измерением перекрестного фильтра. Да, в Engli sh «Y» будет измерением, но в перекрестном фильтре и d c. js «измерения» - это то, на чем вы агрегируете, а группы - это агрегации, которые часто go в Y. (Назвать вещи сложно.)

Мы будем использовать порядковую шкалу (у вас была полуординарная полулинейная, которая не будет работать):

$scope.monthlyRiskStatus
  .x(d3.scaleOrdinal().domain(months))
  .dimension(xdim)
  .group(ygroup, levels[0], sel_stack(levels[0]))
  .xUnits(dc.units.ordinal);

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

Обратите внимание, что мы стекируем по уровню, а не по месяцам. Также здесь:

for(var i = 1; i<levels.length; ++i)
  $scope.monthlyRiskStatus.stack(ygroup, levels[i], sel_stack(levels[i]));

Давайте также добавим легенду, чтобы мы знали, на что мы смотрим:

  .margins({left:75, top: 0, right: 0, bottom: 20})
  .legend(dc.legend())

screenshot stacked by level

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

...