Crossfilter arrays as keys
Trying to find a way how to expand array of keys into separate records, one per element of array
by Shahabaz Shafi
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.2.2/d3.v3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/dc/1.6.0/dc.min.js"></script>
<script src="http://crossfilter.github.io/crossfilter/crossfilter.v1.min.js"></script>
<div id="chart"></div>
<div id="piechart"></div>
<div id="chart2"></div>
CSS
.dc-chart {
float: left;
}
.dc-chart rect.bar {
stroke: none;
fill: steelblue;
}
.dc-chart rect.bar:hover {
fill-opacity: .5;
}
.dc-chart rect.stack1 {
stroke: none;
fill: red;
}
.dc-chart rect.stack2 {
stroke: none;
fill: green;
}
.dc-chart rect.deselected {
stroke: none;
fill: #ccc;
}
.dc-chart .sub .bar {
stroke: none;
fill: #ccc;
}
.dc-chart .pie-slice {
/*fill: white;*/
font-size: 12px;
cursor: pointer;
}
.dc-chart .pie-slice :hover {
fill-opacity: .8;
}
.dc-chart .selected path {
stroke-width: 3;
stroke: #ccc;
fill-opacity: 1;
}
.dc-chart .deselected path {
stroke: none;
fill-opacity: .5;
fill: #ccc;
}
.dc-chart .axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dc-chart .axis text {
font: 10px sans-serif;
}
.dc-chart .grid-line line {
fill: none;
stroke: #ccc;
opacity: .5;
shape-rendering: crispEdges;
}
.dc-chart .brush rect.background {
z-index: -999;
}
.dc-chart .brush rect.extent {
fill: steelblue;
fill-opacity: .125;
}
.dc-chart .brush .resize path {
fill: #eee;
stroke: #666;
}
.dc-chart path.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.dc-chart circle.dot {
fill: steelblue;
}
.dc-chart g.stack1 path.line {
stroke: green;
}
.dc-chart g.stack1 circle.dot {
fill: green;
}
.dc-chart g.stack2 path.line {
stroke: red;
}
.dc-chart g.stack2 circle.dot {
fill: red;
}
.dc-chart g.dc-tooltip path {
fill: none;
stroke: grey;
stroke-opacity: .8;
}
.dc-chart path.area {
fill: steelblue;
fill-opacity: .3;
stroke: none;
}
.dc-chart g.stack1 path.area {
fill: green;
}
.dc-chart g.stack2 path.area {
fill: red;
}
.dc-chart .node {
font-size: 0.7em;
cursor: pointer;
}
.dc-chart .node :hover {
fill-opacity: .8;
}
.dc-chart .selected circle {
stroke-width: 3;
stroke: #ccc;
fill-opacity: 1;
}
.dc-chart...
JavaScript
'option strict';
function reduceAdd(p, v) {
if (v.topics[0] === "") return p; // skip empty values
v.topics.forEach (function(val, idx) {
p[val] = (p[val] || 0) + 1; //increment counts
});
return p;
}
function reduceRemove(p, v) {
if (v.topics[0] === "") return p; // skip empty values
v.topics.forEach (function(val, idx) {
p[val] = (p[val] || 0) - 1; //decrement counts
});
return p;
}
function reduceInitial() {
return {};
}
var data = [
{"key":"KEY-1","state":"CA", "topics":["Technology", "Science", "Automotive"], "date":new Date("10/02/2012")},
{"key":"KEY-2","state":"CA", "topics":["Health"], "date": new Date("10/05/2012")},
{"key":"KEY-3","state":"OR", "topics":["Science"], "date":new Date("10/08/2012")},
{"key":"KEY-4","state":"WA", "topics":["Automotive", "Science"], "date":new Date("10/09/2012")},
{"key":"KEY-5","state":"WA", "topics":["Science"], "date":new Date("10/09/2012")}
];
var cf = crossfilter(data);
var topicsDim = cf.dimension(function(d){ return d.topics;});
var topicsGroup = topicsDim.groupAll().reduce(reduceAdd, reduceRemove, reduceInitial).value();
// hack to make dc.js charts work
topicsGroup.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 states = cf.dimension(function(d){ return d.state;});
var stateGroup = states.group();
var pieChart = dc.pieChart("#piechart");
pieChart.height(75).width(75).dimension(states).group(stateGroup);
var barChart = dc.rowChart("#chart");
barChart ...