D3.js 交叉过滤查询

D3.js 交叉过滤查询,d3.js,crossfilter,D3.js,Crossfilter,是否可以筛选以数组作为值的交叉筛选数据集 例如,假设我有以下数据集: var data = [ { bookname: "the joy of clojure", authors: ["Michael Fogus", "Chris Houser"], tags: ["clojure", "lisp"] }, { bookname: "Eloquent Ruby", authors: ["Russ Olsen"], tags: ["rub

是否可以筛选以数组作为值的交叉筛选数据集

例如,假设我有以下数据集:

var data = [
  {
    bookname: "the joy of clojure",
    authors: ["Michael Fogus", "Chris Houser"],
    tags: ["clojure", "lisp"]
  },
  {
    bookname: "Eloquent Ruby",
    authors: ["Russ Olsen"],
    tags: ["ruby"]
  },
  {
    bookname: "Design Patterns in Ruby",
    authors: ["Russ Olsen"],
    tags: ["design patterns", "ruby"]
  }
];
有没有一种简单的方法可以访问带有特定标签的书籍?还有那些有特定作者的书?到目前为止,我对如何使用交叉过滤器的理解让我做了如下工作:

var filtered_data = crossfilter(data);
var tags = filtered_data.dimension(function(d) {return d.tags});
var tag = tags.group();
/*
 v is the row in the dataset

 p is {} for the first execution (passed from reduceInitial). 
 For every subsequent execution it is the value returned from reduceAdd of the prev row
*/
function reduceAdd(p, v) {
  v.tags.forEach (function(val, idx) {
     p[val] = (p[val] || 0) + 1; //increment counts
  });
  return p;
}

function reduceRemove(p, v) {
   //omitted. not useful for demonstration
}

function reduceInitial() {
  /* this is how our reduce function is seeded. similar to how inject or fold 
   works in functional languages. this map will contain the final counts 
   by the time we are done reducing our entire data set.*/
  return {};  
}
然后当我访问分组时(像这样):

我明白了:

[{key: ["clojure", "lisp"], value: 1}, 
 {key: ["design patterns", "ruby"], value: 1}, 
 {key: ["ruby"], value: 1}]
当我想要这个的时候:

[{key: "ruby", value: 2}, 
 {key: "clojure", value: 1}, 
 {key: "lisp", value: 1},
 {key: "design patterns", value: 1}]
我从未使用过“交叉过滤器”(我假设这是一个JS库)。下面是一些纯JS方法

这个

data.filter(function(d) {
  return d.authors.indexOf("Michael Fogus") !== -1;
})
var res = {};
data.forEach(function(d) {
  d.tags.forEach(function(tag) {
    res.hasOwnProperty(tag) ? res[tag]++ : res[tag] = 1
  });
})
返回以下内容:

[{bookname:"the joy of clojure", authors:["Michael Fogus", "Chris Houser"], tags:["clojure", "lisp"]}]
({clojure:1, lisp:1, ruby:2, 'design patterns':1})
这个

data.filter(function(d) {
  return d.authors.indexOf("Michael Fogus") !== -1;
})
var res = {};
data.forEach(function(d) {
  d.tags.forEach(function(tag) {
    res.hasOwnProperty(tag) ? res[tag]++ : res[tag] = 1
  });
})
返回以下内容:

[{bookname:"the joy of clojure", authors:["Michael Fogus", "Chris Houser"], tags:["clojure", "lisp"]}]
({clojure:1, lisp:1, ruby:2, 'design patterns':1})

对于其中任何一个,您都可以应用
d3.entries
来获得
{key:“ruby”,value:2}
格式。

我已经在下面的代码中添加了注释。大图:使用reduce函数

var data = ...
var filtered_data = crossfilter(data);
var tags = filtered_data.dimension(function(d) {return d.tags});

tags.groupAll().reduce(reduceAdd, reduceRemove, reduceInitial).value()
请注意我是如何使用groupAll()而不是group()b/c的,我们希望我们的reduce函数(定义如下)在一个组而不是三个组上运行

现在,reduce函数应该如下所示:

var filtered_data = crossfilter(data);
var tags = filtered_data.dimension(function(d) {return d.tags});
var tag = tags.group();
/*
 v is the row in the dataset

 p is {} for the first execution (passed from reduceInitial). 
 For every subsequent execution it is the value returned from reduceAdd of the prev row
*/
function reduceAdd(p, v) {
  v.tags.forEach (function(val, idx) {
     p[val] = (p[val] || 0) + 1; //increment counts
  });
  return p;
}

function reduceRemove(p, v) {
   //omitted. not useful for demonstration
}

function reduceInitial() {
  /* this is how our reduce function is seeded. similar to how inject or fold 
   works in functional languages. this map will contain the final counts 
   by the time we are done reducing our entire data set.*/
  return {};  
}

我相信随着时间的推移,我的问题变得越来越模糊。这很不幸,一点也不晦涩。我今天正是在寻找这一点。我很感谢您的努力,但我使用交叉过滤器的原因是为了对一些相当大的数据集进行排序。实际上是另一个mike bostock图书馆,是一个非常有趣的想法,如果我能弄清楚如何正确使用它..啊。。我完全忽略了使用groupAll函数。谢谢你,我还没有测试过你的答案,但它看起来确实有我需要的正确的想法组合。非常感谢你!这太棒了。谢谢。答案的作者或者其他人能完成这个答案吗?问题是“有没有一种简单的方法可以访问带有特定标签的书籍?以及有特定作者的书籍?”但目前,这个答案只产生了一些“.value()”结果,而且还不清楚(至少对我来说,可能是从全新到交叉过滤,但仍然如此)如何给出问题的最终答案,我也需要知道。提前感谢。这有助于在不考虑单个组的情况下找到选择平均值。谢谢。@DestinyArchitect:Untested,但我认为您正在寻找这样的东西:
var reduce=tags.groupAll().reduce(reducead,reduceRemove,reduceInitial)
var books\u on\u design\u patterns=reduce.value()[“design patterns”]