在 dc.js 中更新多个标签行图

Update multiple tags rowchart in dc.js

我正在寻找如何在 dc.js 中创建行图以显示和过滤具有多个标签的项目。我已经总结了一些关于堆栈溢出的答案,现在有了一个工作代码。

var data = [
{id:1, tags: [1,2,3]},
{id:2, tags: [3]},
{id:3, tags: [1]},
{id:4, tags: [2,3]},
{id:5, tags: [3]},
{id:6, tags: [1,2,3]},
{id:7, tags: [1,2]}]; 

    var content=crossfilter(data);

    var idDimension = content.dimension(function (d) { return d.id; });
    var grid = dc.dataTable("#idgrid");
    grid
            .dimension(idDimension)
            .group(function(d){ return "ITEMS" })
            .columns([
                function(d){return d.id+" : "; },
        function(d){return d.tags;},
    ])

    function reduceAdd(p, v) {
        v.tags.forEach (function(val, idx) {
            p[val] = (p[val] || 0) + 1; //increment counts
        });
        return p;
    }

    function reduceRemove(p, v) {
        v.tags.forEach (function(val, idx) {
            p[val] = (p[val] || 0) - 1; //decrement counts
        });
        return p;
    }

    function reduceInitial() {
        return {};
    }


    var tags = content.dimension(function (d) { return d.tags });
    var groupall = tags.groupAll();
    var tagsGroup = groupall.reduce(reduceAdd, reduceRemove, reduceInitial).value();
    tagsGroup.all = function() {
        var newObject = [];
        for (var key in this) {
            if (this.hasOwnProperty(key) && key != "") {
                newObject.push({
                    key: key,
                    value: this[key]
                });
            }
        }
        return newObject;
    }

    var tagsChart = dc.rowChart("#idtags")
    tagsChart
        .width(400)
        .height(200)
        .renderLabel(true)
        .labelOffsetY(10)
        .gap(2)
        .group(tagsGroup)
        .dimension(tags)
        .elasticX(true)
        .transitionDuration(1000)
        .colors(d3.scale.category10())
        .label(function (d) { return d.key })
        .filterHandler (function (dimension, filters) {
            var fm = filters.map(Number)
            dimension.filter(null);
            if (fm.length === 0)
                dimension.filter(null);
            else
                dimension.filterFunction(function (d) {
                    for (var i=0; i < fm.length; i++) {
                        if (d.indexOf(fm[i]) <0) return false;
                    }
                    return true;
                });

            return filters;
        }
    )
    .xAxis().ticks(5);

可以在http://jsfiddle.net/ewm76uru/24/

上看到

然而,当我按一个标签过滤时,行图没有更新。例如,在 jsfiddle 上,如果您 select 标记“1”,它会过滤项目 1、3、6 和 7。很好。但是行图没有更新……例如,我应该将标签“3”的计数降低到 2。

有没有办法在我每次按标签过滤时更新行图标签计数?

谢谢。

经过长时间的斗争,我想我终于找到了一个可行的解决方案。

如 crossfilter 文档所述:"a grouping intersects the crossfilter's current filters, except for the associated dimension's filter"

因此,修改标签选择时不会过滤标签维度,并且没有标志或函数强制重置。不过,有一个解决方法(此处给出:https://github.com/square/crossfilter/issues/146)。

想法是复制 'tags' 维度,并将其用作过滤维度:

var tags = content.dimension(function (d) { return d.tags });
// duplicate the dimension
var tags2 = content.dimension(function (d) { return d.tags });
var groupall = tags.groupAll();
...
tagsChart
  .group(tagsGroup)
  .dimension(tags2) // and use this duplicated dimension

在这里可以看到: http://jsfiddle.net/ewm76uru/30/

希望对您有所帮助。