d3.js - dc.js 删除 PIE 图表中单击的切片而不是灰显?

标签 d3.js dc.js

我想从 PIE 图表中删除选定的切片而不是灰显。例如DC page “增益/损失天数”或“季度”PIE 图表,如果我单击切片(例如 Q4),我想从显示中删除该条目(包括切片 + 图例,如果我想恢复,我可以使用控件来重置它) )。

如何实现这种行为?

我在点击处理程序中尝试了以下操作:

let filter = chart.keyAccessor()(d);
            if (d3.event['shiftKey']) {
                if ('Others' === filter) {
                    chart['_invokeFilteredListener'](Array.isArray(filter)? filter : [filter], 'error');
                } else {
                    chart['__inclusive'] = true;
                    chart['replaceFilter'](filter);
                    //if (multivalued) {
                    dc.redrawAll(); //why renderAll()?
                    //}
                }
            } else {
                dc.events.trigger(() => {
                    chart.filter(filter);
                    dc.redrawAll();
                });
            }

filterHandler:

.filterHandler((dim: Crossfilter2.Dimension<any, any>, filters: string[]) => {
                dim.filter(null);
                const data = this._chart.data();
                const filterObject = {};
                for (let f of filters) {
                    if ('Others' === f) {
                        let others: any[] = data[data.length - 1].others;
                        if (Array.isArray(others)) {
                            for (let o of others) {
                                filterObject[o] = true;
                            }
                        } else {
                            dim.group().all().forEach(g => {
                                let p = filters.indexOf(g.key);
                                if (p < 0) {
                                    filterObject[g.key] = p;
                                }
                            });
                        }
                    } else {
                        filterObject[f] = true;
                    }
                }
                dim.filterFunction(d => {
                    return filterObject[Array.isArray(d)? d[0] : d] !== void 0;
                });
                return filters;
            });

最佳答案

可能有很多方法可以做到这一点,但我首先想到的是,“听起来像 fake group ”,其行为就像一个普通的组,但它确实观察自己维度的过滤器:

function filter_self_group(chart, group) {
    return {
        all: function() {
            var filters = chart.filters();
            return group.all().filter(kv => !filters.includes(kv.key));
        }
    };
}
yearRingChart
    .group(filter_self_group(yearRingChart, spendPerYear))

只需从图表中抓取过滤器并确保排除这些垃圾箱即可。这不涉及其他,但添加起来很简单。

接下来,我们想要过滤值,而不是像dc.js通常那样过滤值。我们可以通过修改默认过滤器处理程序来做到这一点。我认为这与您上面所做的类似,但更简单:

function negate_filters(dimension, filters) {
    if (filters.length === 0)
        dimension.filter(null);
    else
        dimension.filterFunction(function(d) {
            return !filters.includes(d);
        })
    return filters;
}

另外,我认为如果在过滤掉最后一个切片时重置过滤器,那就太好了:

function all_is_nothing(N, filterHandler) {
    return function(dimension, filters) {
        console.log(filters.length, N)
        if(filters.length === N)
            filters = [];
        return filterHandler(dimension, filters);
    }
}

将它们联系在一起:

yearRingChart
    .filterHandler(all_is_nothing(spendPerYear.all().length, negate_filters));

最后,“取消选择的灰色”对我们来说没有用,而且我不知道如何禁用 CSS 规则的效果,所以让我们在图表绘制之后但之前从切片中删除该类它显示:

yearRingChart.on('pretransition', function(chart) {
    chart.selectAll('g.deselected').classed('deselected', false);
});

我确信还有很多其他方法可以做到这一点,也许还有更干净的方法。这就是我想到的。我很乐意为其他人提供支持,但我想首先介绍基本想法。

Here is an example fiddle.

关于d3.js - dc.js 删除 PIE 图表中单击的切片而不是灰显?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48433307/

相关文章:

d3.js - 使用 d3.js 绘制纽约街区

javascript - DC.js 使用过滤器排序

javascript - 复杂数据如何使用散点图?

javascript - 添加轴和起点之间的间距

d3.js - d3.partition 旭日 : rotating text and other glitches

javascript - 悬停(从 .ease(d3.easeBounceOut) 迁移到 .ease ("easeBounceOut"))

javascript - 制作单词频率直方图

javascript - 连接到 CrossFilter 的 D3 JS 布局树

crossfilter - 返回 DC.js/Crossfilter 组中的最大值

javascript - 在条形图中的条形顶部显示值