var bubbleCF = dc.bubbleChart('#bubble-cf'), heatCF = dc.heatMap('#heatmap-cf'), heatClone = dc.heatMap('#heatmap-clone'), bubbleClone = dc.bubbleChart('#bubble-clone'); d3.csv('iris.csv', function(error, iris) { var fields = { sl: 'sepal_length', sw: 'sepal_width', pl: 'petal_length', pw: 'petal_width' }; var species = ['setosa', 'versicolor', 'virginica']; iris.forEach(function(d) { Object.keys(fields).forEach(function(ab) { d[fields[ab]] = +d[fields[ab]]; }); }); // autogenerate a key function for an extent function key_function(extent) { var div = extent[1]-extent[0] < 5 ? 2 : 1; return function(k) { return Math.floor(k*div)/div; }; } var extents = {}; var keyfuncs = {}; Object.keys(fields).forEach(function(ab) { extents[ab] = d3.extent(iris, function(d) { return d[fields[ab]]; }); keyfuncs[ab] = key_function(extents[ab]); }); var cf = crossfilter(iris); function duo_key(ab1, ab2) { return function(d) { return [keyfuncs[ab1](d[fields[ab1]]), keyfuncs[ab2](d[fields[ab2]])]; }; } function key_part(i) { return function(kv) { return kv.key[i]; }; } function reduce_species(group) { group.reduce( function(p, v) { p[v.species]++; p.total++; return p; }, function(p, v) { p[v.species]--; p.total--; return p; }, function() { var init = {total: 0}; species.forEach(function(s) { init[s] = 0; }); return init; } ); } function max_species(d) { var max = 0, i = -1; species.forEach(function(s, j) { if(d.value[s] > max) { max = d.value[s]; i = j; } }); return i >= 0 ? species[i] : null; } function initialize_bubble(bubbleChart, dim, group) { bubbleChart .width(400) .height(400) .x(d3.scale.linear()).xAxisPadding(0.5) .y(d3.scale.linear()).yAxisPadding(0.5) .elasticX(true) .elasticY(true) .label(d3.functor('')) .keyAccessor(key_part(0)) .valueAccessor(key_part(1)) .radiusValueAccessor(function(kv) { return kv.value.total; }) .colors(d3.scale.ordinal() .domain(species.concat('none')) .range(['#e41a1c','#377eb8','#4daf4a', '#bbb'])) .colorAccessor(function(d) { return max_species(d) || 'none'; }); } function initialize_heatmap(heatMap) { heatMap .width(400) .height(400) .xBorderRadius(15).yBorderRadius(15) .keyAccessor(key_part(0)) .valueAccessor(key_part(1)) .colors(d3.scale.ordinal() .domain(species.concat('none')) .range(['#e41a1c','#377eb8','#4daf4a', '#bbb'])) .colorAccessor(function(d) { return max_species(d) || 'none'; }); } var sepalDim = cf.dimension(duo_key('sl', 'sw')), sepalGroup = sepalDim.group(), petalDim = cf.dimension(duo_key('pl', 'pw')), petalGroup = petalDim.group(); reduce_species(sepalGroup); reduce_species(petalGroup); initialize_bubble(bubbleCF.dimension(sepalDim).group(sepalGroup)); initialize_heatmap(heatCF.dimension(petalDim).group(petalGroup)); // return brand-new objects and keys every time function clone_group(group) { function clone_kvs(all) { return all.map(function(kv) { return { key: kv.key.slice(0), value: Object.assign({}, kv.value) }; }); } return { all: function() { return clone_kvs(group.all()); }, top: function(N) { return clone_kvs(group.top(N)); } }; } var lengthDim = cf.dimension(duo_key('sl', 'pl')), lengthGroup = lengthDim.group(), widthDim = cf.dimension(duo_key('sw', 'pw')), widthGroup = widthDim.group(); reduce_species(widthGroup); reduce_species(lengthGroup); initialize_heatmap(heatClone.dimension(widthDim).group(clone_group(widthGroup))); initialize_bubble(bubbleClone.dimension(lengthDim).group(clone_group(lengthGroup))); dc.renderAll(); });