【问题标题】:Efficient way to plot area normalized bar chart using crossfilter / dc.js?使用 crossfilter / dc.js 绘制面积标准化条形图的有效方法?
【发布时间】:2017-02-16 05:19:42
【问题描述】:

我希望在 dc.js 的多维数据集中绘制几个与连续变量相关的直方图。虽然使用dc.barChart 组件很容易实现这一点,但我希望将这些直方图区域归一化。在我的情况下,bin 宽度是统一的,因此这减少了将每个 bin/组中的总计数除以 (binWidth * totCounts) 的问题。

我能够为这些直方图绘制一个初始视图,该直方图使用以下几行进行面积标准化:

var cf = crossfilter(data);
var totCounts = cf.groupAll().value();
var histDimension = cf.dimension(function(d) {
  return Math.floor(d.fieldOfInterest / binWidth) * binWidth;
});
var histGroup = histDimension.group().reduceSum(function(d) {
  return 1 / (binWidth * totCounts);
});

将此方法与 dc.js 结合使用确实会生成面积标准化条形图。但是,当我开始过滤数据时,过滤后的数据不会重新标准化。相反,视图总是通过未过滤数据集上的原始区域归一化的镜头呈现数据。

虽然我理解为什么会这样 - crossfilter 中的 reducer 函数仍在使用初始规范化......我真的不明白是否有任何合理且高效的方式来实现我正在寻找的东西......即,始终根据过滤后的数据集重新规范化 dc.js 绘图视图。在我看来,由于任何单个 bin/组的规范化需要来自所有组 (totCounts) 的信息,因此没有增量/高性能的方法来定义有效交叉过滤的归约函数。

我是否错过了一些明显的方法来实现我想要做的事情,或者这是我应该放弃能够在 crossfilter/dc.js 中实现的希望吗?如果有任何意见可以为我指明正确的方向,我将不胜感激。

【问题讨论】:

  • 不要放弃希望!总有办法!

标签: dc.js crossfilter


【解决方案1】:

这里我们需要做的是将totCounts 排除在reduce 计算之外,以便它能够适应不断变化的总数。由于 crossfilter 以增量方式计算减少量,因此它无法在变化时重新应用总数。

幸运的是,条形图的valueAccessor 非常适合此操作。事实上,对于任何涉及除法的归约而言,它几乎总是一个更好的选择,因为在读取值(一次)时进行除法比在聚合和归约发生时(多次)进行除法效率更高。

这里我们只需要一种动态计算总数的方法,这就是groupAll 的优势所在。在这种情况下,我们可能需要dimension.groupAll(),因为它不观察当前维度的过滤器。我们不希望对当前图表进行过滤以使其总和不为 1。

把这些放在一起:

var cf = crossfilter(data);
var histDimension = cf.dimension(function(d) {
  return Math.floor(d.fieldOfInterest / binWidth) * binWidth;
});
var totCounter = histDimension.groupAll();
var histGroup = histDimension.group(); // default reduceCount

barChart
    .valueAccessor(function(kv) {
        var total = totCounter.value();
        return total && (kv.value / (binWidth * total));
    })

【讨论】:

  • 戈登,非常感谢!这是完美的。我从来没有想过我可以以这种方式使用valueAccessor 方法,但是现在它当然很有意义。再次感谢您对 dc.js 所做的不懈努力。由于出色的文档以及您自己和其他一些常规社区成员对所有 SO 问题的良好回答,拿起 dc.js 是一次非常有趣的体验。希望一旦我更习惯了代码库,我可以做出贡献。干杯
  • 只是想补充一点,我必须进行这个小编辑:return kv.value / (binWidth * (totCounter.value() + 0.01));。否则,在空选择时,直方图过渡动画会飞起来飞走,因为我假设返回值是Inf,而不是0,原因是被零除。
  • 好点,我已经用我喜欢的方式进行了编辑,如果发生被零除,则返回 0。
  • 不错!这是一种不那么骇人听闻的方式。谢谢
猜你喜欢
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多