我正在寻找如何在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。
每次按标签过滤时,有没有办法让行图标签计数更新?
感谢。
答案 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/
我希望这会有所帮助。