dc.numberDisplay 显示单个组的计数,而不是组数的计数

dc.numberDisplay showing count for single group, not count of number of groups

我有这样的数据:

var records = [
        {id: '1', cat: 'A'},
        {id: '2', cat: 'A'},
        {id: '3', cat: 'B'},
        {id: '4', cat: 'B'},
        {id: '5', cat: 'B'},
        {id: '6', cat: 'C'}
 ];

我想创建一个 dc.numberDisplay 来显示 count 个唯一类别的数量,在上面的示例数据(A、B 和 C)中为 3 .

这是我目前正在做的事情:

var ndx = crossfilter(data); // init crossfilter
// create dimension based on category
var categoryDimension = ndx.dimension(
  function (d) {
    return d.category;
  }
);
// Group by category
var categoryGroup = categoryDimension.group();

var categoryCount = dc.numberDisplay('#category-count'); // An empty span
categoryCount
  .group(categoryGroup)
  .valueAccessor(
    function (d) { return d.value; }
  );

问题是numberDisplay显示的是2,而不是3。调试的时候发现调用valueAccessor的时候,d是number的count类别 A 的元素数量,而不是类别数量的计数。

我该如何解决这个问题?

更新:感谢 Nathan 的解决方案,这是一个有效的代码片段(ES2016 风格)

const categoryDimension = claims.dimension(
        (d) => {
          return d.cat;
        }
      );

const categoryGroup = categoryDimension.groupAll().reduce(
  (p, v) => { // add element
    const cat = v.cat;
    const count = p.categories.get(cat) ||  0;
    p.categories.set(cat, count + 1);
    return p;
  },

  (p, v) => { // remove element
    const cat = v.cat;
    const count = p.categories.get(cat);
    if (count === 1) {
      p.categories.delete(cat);
    } else {
      p.categories.set(cat, count - 1);
    }
    return p;
  },

  () => { // init
    return {
      categories: new Map()
    };
  });

categoryCount
  .group(categoryGroup)
  .valueAccessor(
    (d) => {
      return d.categories.size;
    }
  );

您将需要使用 groupAll(),因为数字显示仅查看顶部组。然后提供自定义减少功能来跟踪独特的类别。最后,当 DC.js 从顶层组中提取值时(只有一个)——只有 return 类别数(即 p 对象中的键数)。

var categoryGroup = categoryDimension.groupAll().reduce(
  function (p, v) { //add
    if(p[v.cat]) {
      p[v.cat]++;
    } else {
      p[v.cat] = 1;
    }
    return p;
  },
  function (p, v) { //remove
    p[v.cat]--;
    if(p[v.cat] === 0) {
      delete p[v.cat];
    }
    return p;
  },
  function () { //init
    //initial p - only one since using groupAll
    return {};
  }
);

console.debug("groups", categoryGroup.value());

dc.numberDisplay('#category-count')
  .group(categoryGroup)
  .valueAccessor(
    function (d) { return Object.keys(d).length; }
  );