无法使用 dc.js 和多个 X 键过滤单个堆栈

Unable to filter individual stacks using dc.js with multiple X keys

堆叠条形图无法在单击任何堆叠时进行过滤

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

我用 link

创建了一个 fiddle

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();
    });
});

谁能给我指出正确的方向。

感谢您的光临。

您通常不想在 X 轴上使用多个键,除非您有 非常非常 充分的理由。这只会让事情变得困难

在这里,过滤器堆栈示例已经使用了多个键,您的数据也有多个键。如果您想在此示例中使用您的数据,我建议将这两个键一起处理,因为看起来您真的是将这两个键一起用作序号键。我们将在下面看到一种方法。

您还尝试结合两种不同的技术来堆叠条形图,stack_second() 和您自己的自定义减速器。我不认为您的自定义 reducer 与堆栈过滤兼容,所以我将把它放在这个答案中。

你必须使用 multikey() 功能,并同时按下你的两个 X 键:

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

混乱,因为这将创建看起来像 0,0xRejected 的密钥......不是那么人类可读,但过滤器堆栈 hack 依赖于能够将密钥分成两部分,这将使它做到了。

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

var barGrp = barDim.group();

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

首先,您的数据没有每个 X 值的每个堆栈。所以我向 stack_second() 添加了一个参数,包括所有 "needed" 堆栈:

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 class 在 pretransition 处理程序中修复它,以便我们的自定义点击处理程序和 stack-deselected class 可以做他们的工作:

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

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

这里是a working fork of your fiddle.