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

时间:2015-03-01 17:46:52

标签: dc.js crossfilter

我正在寻找如何在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上,如果选择标记“1”,则会过滤项目1,3,6和7.好。但是行图没有更新......例如,我应该将标签'3'计数降低到2。

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

感谢。

1 个答案:

答案 0 :(得分:2)

经过长期的斗争,我想我终于找到了一个有效的解决方案。

正如在crossfilter文档中所述:“分组与交叉滤波器的当前滤波器相交,但相关维度的滤波器除外”

因此,修改标记选择时不会过滤标记维度,并且没有标记或函数来强制重置。然而,有一种解决方法(在此处给出: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/

我希望这会有所帮助。