dc.js 气泡图分组从错误的组中删除

dc.js Grouping for Bubble Chart Removing from wrong groups

我正在尝试使用 dc.js 创建一个气泡图,每个数据行都有一个气泡,并将被同一页面上的其他图表过滤。初始气泡图创建正确,但当项目从另一个图表中过滤并从组中添加或删除时,它们看起来像是被应用到错误的组。我不确定我在分组或维度上搞砸了什么。我创建了一个 example fiddle here

filterColumn 上有一个简单的饼图,一个使用 identifer1 唯一字段作为维度的气泡图和 xValyValrVal显示数据,dataTable显示当前记录。

我试过其他自定义群组功能,但切换到 FAQ 中的示例仍然有问题。

var
    filterPieChart=dc.pieChart("#filterPieChart"),
    bubbleChart = dc.bubbleChart('#bubbleChart'),
    dataTable = dc.dataTable('#data-table');

var
  bubbleChartDim=ndx.dimension(dc.pluck("identifier1")),
  filterPieChartDim=ndx.dimension(dc.pluck("filterColumn")),
  allDim = ndx.dimension(function(d) {return d;});

var filterPieChartGroup=filterPieChartDim.group().reduceCount();

function reduceFieldsAdd(fields) {
    return function(p, v) {
        fields.forEach(function(f) {
            p[f] += 1*v[f];
        });
        return p;
    };
}

function reduceFieldsRemove(fields) {
    return function(p, v) {
        fields.forEach(function(f) {
            p[f] -= 1*v[f];
        });
        return p;
    };
}
function reduceFieldsInitial(fields) {
    return function() {
        var ret = {};
        fields.forEach(function(f) {
            ret[f] = 0;
        });
        return ret;
    };
}

var fieldsToReduce=['xVal', 'yVal', 'rVal'];
var bubbleChartGroup = bubbleChartDim.group().reduce(
    reduceFieldsAdd(fieldsToReduce), 
    reduceFieldsRemove(fieldsToReduce),
    reduceFieldsInitial(fieldsToReduce)
);


filterPieChart
    .dimension(filterPieChartDim)
    .group(filterPieChartGroup)

... ;

bubbleChart
    .dimension(bubbleChartDim)
    .group(bubbleChartGroup)
    .keyAccessor(function (p) { return p.value.xVal; })
    .valueAccessor(function (p) { return p.value.yVal; })
    .radiusValueAccessor(function (p) { return p.value.rVal; })

... ;

这是一个令人沮丧的调试。您的分组和缩减都很好,这是为每一行绘制一个气泡的最佳方式,使用这样的唯一标识符。

[很烦人的是你必须指定一个复杂的归约,当值要么是原始值要么是 0,但备选方案也好不了多少。]

降价快要疯了。绝对不仅仅是原始值和零,有些会变成其他值,更大或负数,有时单击饼图切片两次甚至 return 到原始状态。

我在 reduce 函数中放置了断点,并注意到,就像您所做的那样,值被从错误的组中删除。这怎么可能?最后,通过在饼图的 filtered 处理程序中记录 bubbleChartGroup.all(),我注意到在第一次渲染后组乱序了!

你的代码没问题。但是您在 dc.js、which I filed here 中发现了一个新错误。

为了实现sortBubbleSize功能,我们对气泡进行排序。不幸的是,我们也在对 crossfilter 的内部组数组进行排序,它信任我们。 (group.all() return 是一个绝不能修改的内部数据结构。)

修复会很容易;我们只需要在排序之前复制数组。您可以在代码中通过注释掉 sortBubbleSize 并提供 data function 来测试它,这是它在内部所做的:

bubbleChart.data(function (group) {
    var data = group.all().slice(0);
    if (true) { // (_sortBubbleSize) {
        // sort descending so smaller bubbles are on top
        var radiusAccessor = bubbleChart.radiusValueAccessor();
        data.sort(function (a, b) { return d3.descending(radiusAccessor(a), radiusAccessor(b)); });
    }
    return data;
});

注意顶部的 .slice(0)

希望在下一个版本中解决这个问题,但这个解决方法非常可靠,以防需要更长的时间。

Here is a fiddle demonstrating the workaround.