在 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/
希望对您有所帮助。
我正在寻找如何在 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/
希望对您有所帮助。