【问题标题】:dc.js - dataTable -- combining data rowsdc.js - dataTable - 组合数据行
【发布时间】:2015-12-21 19:52:22
【问题描述】:

我正在创建一个仪表盘,数据格式是这样的:

var data = [
    {"id": 'CDE', "count": 1, "name": 'ajdkf', "type": 'E', "state": 'A'},
    {"id": 'CDE', "count": 0, "name": 'ajdkf', "type": 'E', "state": 'A'},
    {"id": 'CDE', "count": 0, "name": 'ajdkf', "type": 'E', "state": 'A'},
    {"id": 'CDE', "count": 0, "name": 'ajdkf', "type": 'E', "state": 'A'},
    {"id": 'HFG', "count": 1, "name": 'ajdkf', "type": 'E', "state": 'B'},
    {"id": 'HFG', "count": 0, "name": 'ajdkf', "type": 'E', "state": 'B'},
    {"id": 'HFG', "count": 0, "name": 'ajdkf', "type": 'E', "state": 'B'},
    {"id": 'HFG', "count": 0, "name": 'ajdkf', "type": 'E', "state": 'B'},
    {"id": 'ABF', "count": 1, "name": 'ghedw', "type": 'G', "state": 'A'},
    {"id": 'ABF', "count": 0, "name": 'ghedw', "type": 'G', "state": 'A'},
    {"id": 'ABF', "count": 0, "name": 'ghedw', "type": 'G', "state": 'A'},
    {"id": 'ABF', "count": 0, "name": 'ghedw', "type": 'G', "state": 'A'},
    {"id": 'DEF', "count": 1, "name": 'huiqs', "type": 'E', "state": 'A'},
    {"id": 'DEF', "count": 0, "name": 'huiqs', "type": 'E', "state": 'A'},
    {"id": 'DEF', "count": 0, "name": 'huiqs', "type": 'E', "state": 'A'},
    {"id": 'DEF', "count": 0, "name": 'huiqs', "type": 'E', "state": 'A'},
    ...
    {"id": 'ABC', "count": 1, "name": 'asbsd', "type": 'D', "state": 'B'},
    {"id": 'ABC', "count": 0, "name": 'asbsd', "type": 'D', "state": 'B'},
    {"id": 'ABC', "count": 0, "name": 'asbsd', "type": 'D', "state": 'B'},
    {"id": 'ABC', "count": 0, "name": 'asbsd', "type": 'D', "state": 'B'}
];

我正在尝试创建一个如下所示的表:

Name   State A Count   State B Count
ajdkf  1               1 
ghedw  1               0
huiqs  1               0 
asbsd  0               1

我目前有:

<body>
<div style='clear:both;'>
  <table id="Stats">
    <thead>
        <tr class="header">
            <th> name </th>
            <th> State A Count </th>
            <th> State B Count </th>
        </tr>
    </thead>
  </table>
</div>
</body>

<script>
...
var dataTable = dc.dataTable("#Stats");
var dataTableDim = ndx.dimension(function(d) {return d.name;});
dataTable
    .dimension(dataTableDim)
    .group(function(d) {return d.name})
    .columns([
        function(d) { return d.name; },
        function(d) { if (d.state == 'A') {return +d.count;} else {return 0;} },
        function(d) { if (d.state == 'B') {return +d.count;} else {return 0;} },
    ]);
...
</script>

它给了我一个看起来像这样的表格:

Name   State A Count   State B Count
asbsd
asbsd  0               1
asbsd  0               0
asbsd  0               0
asbsd  0               0
ajdkf
ajdkf  1               0
ajdkf  0               0 
ajdkf  0               0 
ajdkf  0               0
ajdkf  0               1 
ajdkf  0               0 
ajdkf  0               0 
ajdkf  0               0
huiqs 
huiqs  1               0 
huiqs  0               0 
huiqs  0               0 
huiqs  0               0 
ghedw
ghedw  0               0 
ghedw  1               0
ghedw  0               0
ghedw  0               0

我需要做什么才能得到我想要的桌子?我希望在“状态 A”下有 2 个“列”(计数和百分比),状态 B 也一样。类似:

Name        State A              State B
        Count     Percent    Count     Percent

jsfiddle: https://jsfiddle.net/56hgjgsz/14/

我无法读取外部文件,所以我不得不将它们添加到 js.. 抱歉 :( (https://jsfiddle.net/56hgjgsz/29/)

这“有效”但不会减少表中的行并且顺序是向后的 -> 相同的地址但使用 /32/ 而不是 /14/ 或 /29/

【问题讨论】:

  • oof,jsfiddle中的“外部资源”部分是用来指向d3和dc的,不需要包含源代码!
  • 由于某种原因它不起作用:/ 对此感到抱歉
  • 确实拖慢了 fiddle 界面;工作起来一定很痛苦!在下面我更新的答案中也得到了修复。
  • 在您的小提琴中,表格最初只有一个名称,而不是显示所有名称。选择状态 B 时,它也不会更新以包含其他人。我在下面的代码中添加了您的解决方案,并且该表没有删除“空”行。我很困惑为什么它不能正常工作。
  • 我把 && 改成了 ||并修复了它:)

标签: javascript datatable dc.js


【解决方案1】:

在 dc.js 出现几年后,人们发现您实际上可以将 作为 .dimension() 传递给数据表。这就是您想要的,因为您正在执行交叉过滤器缩减以获取状态计数。

Here's an example. (source)

这是noted in the documentation here

减少交叉过滤组中多个值的方法是标准的:

var dataTableGroup = dataTableDim.group().reduce(
  function(p, v) {
    ++p.number;
    p.total  += +v.count;
    p.stateA += (v.state === 'A' ? v.count : 0);
    p.stateB += (v.state === 'B' ? v.count : 0);
    return p;
  },
  function(p, v) {
    --p.number;
    p.total  -= +v.count;
    p.stateA -= (v.state === 'A' ? v.count : 0);
    p.stateB -= (v.state === 'B' ? v.count : 0);
    return p;
  },
  function() {
    return {
      number: 0,
      total:  0,
      stateA: 0,
      stateB: 0
    }
  }
);

然后我们可以为数据表创建一个“假维度”来读取顶部或底部的 N 个值,只保留具有 stateAstateB 值的 bin。请注意,我们必须通过 N,这与假组不同:

function remove_empty_bins_dt(source_group) {
  return {
    top: function(N) {
      return source_group.top(N).filter(function(d) {
        return d.value.stateA !== 0 || d.value.stateB !== 0;
      });
    },
    bottom: function(N) { // hacky but should work 
      return source_group.top(Infinity).filter(function(d) {
        return d.value.stateA !== 0 || d.value.stateB !== 0;
      }).slice(-N).reverse();
    }

  };
}

同样,dc.js 中的数据表是独一无二的,因为它旨在从交叉过滤器维度而非组中读取数据。所以我们需要将这个假维度传递给.dimension() 而不是.group() (which means something completely different sigh)

你的小提琴的工作分支:https://jsfiddle.net/gordonwoodhull/d86foxyq/5/

(如果我理解正确的话)

可以将其概括为查看任意数量的字段,但我今天没时间了。 ?

【讨论】:

  • 如何删除表格中带有零的行?当我单击图表时,我希望表格更新以仅显示表格中的那些行。
  • 您可以use a fake group 跳过空垃圾箱。
  • 当我使用 remove_empty_bins() 创建一个新组用作我的维度时(也当我想对数据进行升序而不是降序排序时),我收到错误:“_chart.dimension (...).top 不是函数”。你知道我为什么会收到这个错误吗?还有,我该如何解决?
  • 哎呀,我忘了数据表使用不同的方法读取数据。我在上面添加了示例代码。如果您正在使用问题中显示的多列进行自定义减少,您可能需要进行调整,但希望这能给出想法。
  • 谢谢!现在我收到“无效的数组长度”错误(crossfilter.js)。为什么是这样?此外,当我将排序从降序更改为升序时,我得到错误“source_group.bottom 不是函数”。 :/ 有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多