有没有办法告诉crossfilter将元素的数组作为单独的记录,而不是将整个数组作为单键? [英] Is there a way to tell crossfilter to treat elements of array as separate records instead of treating whole array as single key?

查看:109
本文介绍了有没有办法告诉crossfilter将元素的数组作为单独的记录,而不是将整个数组作为单键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些数据集,其中一些字段值是数组,我想使用crossfilter和d3.js或dc.js来显示每个值在数据集中存在多少次的直方图。 p>

下面是一个例子:

  var data = [
{ key:KEY-1,tags:[tag1,tag2]},
{key:KEY-2,tags:[tag2]} ,
{key:KEY-3,tags:[tag3,tag1]}];

var cf = crossfilter(data);

var tags = cf.dimension(function(d){return d.tags;});
var tagsGroup = tags.group();


dc.rowChart(#chart)
.renderLabel(true)
.dimension(tags)
.group(tagsGroup)
.xAxis()。ticks(3);

dc.renderAll();

和JSFiddle



以下代码可防止某人遇到类似问题:

  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] = ] || 0) - 1; //递减计数
});
return p;

}

function reduceInitial(){
return {};
}


var data = [
{key:KEY-1,tags:[tag1,tag2], date:new Date(10/02/2012)},
{key:KEY-2,tags:[tag2],date 10,tag3,tag1],date:new Date(10/08/2012)},
{key:KEY-3 2012)}];

var cf = crossfilter(data);

var tags = cf.dimension(function(d){return d.tags;});
var tagsGroup = tags.groupAll()。reduce(reduceAdd,reduceRemove,reduceInitial).value();
// hack to make dc.js charts work
tagsGroup.all = function(){
var newObject = [];
for(var key in this){
if(this.hasOwnProperty(key)&& key!=all){
newObject.push({
key :key,
value:this [key]
});
}
}
return newObject;
}


var dates = cf.dimension(function(d){return d.date;});
var datesGroup = dates.group();


var chart = dc.rowChart(#chart);
chart
.renderLabel(true)
.dimension(tags)
.group(tagsGroup)
.filterHandler(function(dimension,filter){
dimension.filter(function(d){return chart.filter()!= null?d.indexOf(chart.filter())> = 0:true;}); //执行过滤
return filter; // return the actual filter value
})
.xAxis()。ticks(3);

var chart2 = dc.barChart(#chart2);
chart2
.width(500)
.transitionDuration(800)
.margins({top:10,right:50,bottom:30,left:40})
.dimension(dates)
.group(datesGroup)
.elasticY(true)
.elasticX(true)
.round(d3.time.day.round)
.x(d3.time.scale())
.xUnits(d3.time.days)
.centerBar(true)
.renderHorizo​​ntalGridLines(true)
。 brushOn(true);


dc.renderAll();


I have data set where some of the field values are arrays and I'd like to use crossfilter and d3.js or dc.js to display histogram of how many times each of those values was present in the dataset.

Here's an example:

var data = [
    {"key":"KEY-1","tags":["tag1", "tag2"]},
    {"key":"KEY-2","tags":["tag2"]},
    {"key":"KEY-3","tags":["tag3", "tag1"]}];

var cf = crossfilter(data);

var tags = cf.dimension(function(d){ return d.tags;});
var tagsGroup = tags.group();


dc.rowChart("#chart")
    .renderLabel(true)
    .dimension(tags)
    .group(tagsGroup)
    .xAxis().ticks(3);

dc.renderAll();

And JSFiddle http://jsfiddle.net/uhXf5/2/

When I run that code it produces graph like this:

But what I want is something like this:

To make things even more complicated it would be awesome to be able to click on any of the rows and filter dataset by the tag that was clicked.

Anyone has any ideas how to achieve that?

Thanks, Kostya

解决方案

Solved it myself, here's fiddle with working code http://jsfiddle.net/uhXf5/6/

Here's code in case someone will came across similar problem:

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 data = [
    {"key":"KEY-1","tags":["tag1", "tag2"], "date":new Date("10/02/2012")},
    {"key":"KEY-2","tags":["tag2"], "date": new Date("10/05/2012")},
    {"key":"KEY-3","tags":["tag3", "tag1"], "date":new Date("10/08/2012")}];

var cf = crossfilter(data);

var tags = cf.dimension(function(d){ return d.tags;});
var tagsGroup = tags.groupAll().reduce(reduceAdd, reduceRemove, reduceInitial).value();
// hack to make dc.js charts work
tagsGroup.all = function() {
  var newObject = [];
  for (var key in this) {
    if (this.hasOwnProperty(key) && key != "all") {
      newObject.push({
        key: key,
        value: this[key]
      });
    }
  }
  return newObject;
}


var dates = cf.dimension(function(d){ return d.date;});
var datesGroup = dates.group();


var chart = dc.rowChart("#chart");
    chart                                                                                       
    .renderLabel(true)
    .dimension(tags)
    .group(tagsGroup)
    .filterHandler(function(dimension, filter){     
        dimension.filter(function(d) {return chart.filter() != null ? d.indexOf(chart.filter()) >= 0 : true;}); // perform filtering
        return filter; // return the actual filter value
       })
    .xAxis().ticks(3);

var chart2 = dc.barChart("#chart2");
    chart2  
    .width(500)
    .transitionDuration(800)
    .margins({top: 10, right: 50, bottom: 30, left: 40})
    .dimension(dates)
    .group(datesGroup)
    .elasticY(true)
    .elasticX(true)
    .round(d3.time.day.round)    
    .x(d3.time.scale())    
    .xUnits(d3.time.days)
    .centerBar(true)
    .renderHorizontalGridLines(true)       
    .brushOn(true);    


dc.renderAll();

这篇关于有没有办法告诉crossfilter将元素的数组作为单独的记录,而不是将整个数组作为单键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆