【问题标题】:Unable to filter individual stacks using dc.js with multiple X keys无法使用具有多个 X 键的 dc.js 过滤单个堆栈
【发布时间】:2019-11-27 07:51:30
【问题描述】:

堆积条形图无法在点击任何堆栈时进行过滤

单击任何堆栈时,我需要过滤所有图表,这几天都没有发生和挣扎。

我用链接创建了一个小提琴

http://jsfiddle.net/praveenNbd/09t5fd7v/13/

我觉得我搞砸了 gordonwoodhull 建议的密钥创建。

function stack_second(group) {
    return {
        all: function () {
            var all = group.all(),
            m = {};
            // build matrix from multikey/value pairs
            all.forEach(function (kv) {
                var ks = kv.key;
                m[ks] = kv.value;
            });
            // then produce multivalue key/value pairs
            return Object.keys(m).map(function (k) {
                return {
                    key: k,
                    value: m[k]
                };
            });
        }
    };
}

我试着按照这个例子https://dc-js.github.io/dc.js/examples/filter-stacks.html

无法弄清楚下面的代码是如何工作的:

barChart.on('pretransition', function (chart) {
    chart.selectAll('rect.bar')
    .classed('stack-deselected', function (d) {
        // display stack faded if the chart has filters AND
        // the current stack is not one of them
        var key = multikey(d.x, d.layer);
        //var key = [d.x, d.layer];
        return chart.filter() && chart.filters().indexOf(key) === -1;
    })
    .on('click', function (d) {
        chart.filter(multikey(d.x, d.layer));
        dc.redrawAll();
    });
});

谁能指出我正确的方向。

感谢您的光临。

【问题讨论】:

  • 我很困惑,因为您的小提琴没有任何过滤器堆栈代码。它没有正确过滤的原因是表达式 d.value.count || d.value - 这没有意义,因为当计数为 0 时,您想要显示 0,而不是 d.value,它是一个对象。 dc.js 想要一个数字而不是一个对象。
  • 也许你可以编辑你的问题和小提琴并添加过滤器堆栈的东西。没有看到您的代码,任何人都很难猜出它为什么不起作用。
  • 仅使用 d.value.count 解决了全柱过滤问题。
  • 我已经编辑了小提琴并添加了过滤器堆栈的东西,但是 splitkey 功能引起了问题,因为 x 轴有 2 个键。

标签: dc.js crossfilter


【解决方案1】:

您通常不希望在 X 轴上使用多个键,除非您有一个非常非常很好的理由。这只会让事情变得困难

这里,filter-stacks 示例已经使用了多个键,并且您的数据也有多个键。如果您想在此示例中使用您的数据,我建议将这两个键一起处理,因为看起来您确实将这两个键一起用作序数键。我们将在下面看到一种方法。

您还尝试结合两种不同的技术来堆叠钢筋,stack_second() 和您自己的自定义减速器。我不认为您的自定义减速器将与堆栈过滤兼容,因此我将在此答案中删除它。

您必须使用 multikey() 函数,然后将两个 X 键合在一起:

dim = ndx.dimension(function (d) {
    return multikey(d[0] + ',' + d[1], d[2]);
});

混乱,因为这将创建看起来像 0,0xRejected... 的键不那么人类可读,但 filter-stacks hack 依赖于能够将键分成两部分,这将让它做到这一点。

我没有看到任何对行图使用自定义缩减的充分理由,所以我只使用了 reduceCount:

var barGrp = barDim.group();

我在处理这个问题时发现了几个新问题。

首先,您的数据并不包含每个 X 值的每个堆栈。所以我在stack_second() 中添加了一个参数,包括所有“需要”的堆栈:

function stack_second(group, needed) {
  return {
    all: function() {
      var all = group.all(),
          m = {};
      // build matrix from multikey/value pairs
      all.forEach(function(kv) {
        var ks = splitkey(kv.key);
        m[ks[0]] = m[ks[0]] || Object.fromEntries(needed.map(n => [n,0]));
        m[ks[0]][ks[1]] = kv.value;
      });
      // then produce multivalue key/value pairs
      return Object.entries(m).map(([key,value]) => ({key,value}));
    }
  };
}

可能该示例应该包含此更改,尽管它使用的数据不需要它。

其次,我发现序数 X 比例尺存在干扰,因为无法禁用带有序数比例尺的条形图的选择变灰行为。 (也许.brushOn(false) 完全被忽略了?我不确定。)

我通过显式删除内置的deselected 类在pretransition 处理程序中修复了它,以便我们的自定义点击处理程序和stack-deselected 类可以完成它们的工作:

chart.selectAll('rect.bar')
  .classed('deselected', false)

总而言之,我认为这太复杂了,我建议不要在 X 轴上使用多个键。但是,一如既往,有办法让它发挥作用。

这里是a working fork of your fiddle

【讨论】:

  • 非常感谢您的帮助,否则至少需要一周时间才能使逻辑正确。我需要 x 轴上的多个键,因为我通过调整条形之间的空间来模仿具有自定义逻辑的分组堆叠条形图。
  • 啊!哇,这变得越来越复杂。我同意 - 即使 dc.js 中包含 Grouped Stacked 功能,您的输入数据也需要每个键三个部分。希望我能尽快找到合并该功能的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 2015-05-09
相关资源
最近更新 更多