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                                                                                                                                                                                                                                      ...