I'm trying to build a reproducible example of this question about how to replace a crossfilter data restoring dimensions and groups - i.e. reapplying any filters created by the user before data is updated. Here's my stab at implementing the accepted answer. Here's a working jsfiddle.
The script refreshes after 3 seconds to switch from data1
to data2
. If you apply a filter before then (e.g. click Mr A
), the filter is 'remembered' when the graphs update as the right element is highlighted (others greyed out). But the filter isn't applied across to other graphs. You need to remove the filter and reapply for it to work (e.g. remove 2013
pie segment).
Is there something wrong with my implementation, or the solution itself?
<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js - Example</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="http://dc-js.github.io/dc.js/css/dc.css"/>
<script type="text/javascript" src="http://dc-js.github.io/dc.js/js/d3.js"></script>
<script type="text/javascript" src="http://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script type="text/javascript" src="http://dc-js.github.io/dc.js/js/dc.js"></script>
</head>
<body>
<div id="chart-ring-year"></div>
<div id="chart-row-spenders"></div>
<script type="text/javascript">
var yearRingChart = dc.pieChart("#chart-ring-year"),
spenderRowChart = dc.rowChart("#chart-row-spenders");
var data1 = [
{Name: 'Mr A', Spent: 40, Year: 2011},
{Name: 'Mr B', Spent: 10, Year: 2011},
{Name: 'Mr C', Spent: 40, Year: 2011},
{Name: 'Mr A', Spent: 70, Year: 2012},
{Name: 'Mr B', Spent: 20, Year: 2012},
{Name: 'Mr B', Spent: 50, Year: 2013},
{Name: 'Mr C', Spent: 30, Year: 2013}
];
var data2 = [
{Name: 'Mr A', Spent: 10, Year: 2011},
{Name: 'Mr B', Spent: 20, Year: 2011},
{Name: 'Mr C', Spent: 50, Year: 2011},
{Name: 'Mr A', Spent: 20, Year: 2012},
{Name: 'Mr B', Spent: 40, Year: 2012},
{Name: 'Mr B', Spent: 50, Year: 2013},
{Name: 'Mr C', Spent: 50, Year: 2013}
];
// data reset function (adapted)
function resetData(ndx, dimensions) {
dimensions.forEach(function(dim){dim.filter(null);});
ndx.remove();
}
// set crossfilter with first dataset
var ndx = crossfilter(data1),
yearDim = ndx.dimension(function(d) {return +d.Year;}),
spendDim = ndx.dimension(function(d) {return Math.floor(d.Spent/10);}),
nameDim = ndx.dimension(function(d) {return d.Name;}),
spendPerYear = yearDim.group().reduceSum(function(d) {return +d.Spent;}),
spendPerName = nameDim.group().reduceSum(function(d) {return +d.Spent;}),
spendHist = spendDim.group().reduceCount();
function render_plots(){
yearRingChart
.width(200).height(200)
.dimension(yearDim)
.group(spendPerYear)
.innerRadius(50);
spenderRowChart
.width(250).height(200)
.dimension(nameDim)
.group(spendPerName)
.elasticX(true);
dc.renderAll();
}
render_plots();
// REFRESH DATA AFTER 3 SECONDS
setTimeout(function() {
console.log("data reset");
resetData(ndx, [yearDim, spendDim, nameDim]);
ndx = crossfilter(data2),
yearDim = ndx.dimension(function(d) {return +d.Year;}),
spendDim = ndx.dimension(function(d) {return Math.floor(d.Spent/10);}),
nameDim = ndx.dimension(function(d) {return d.Name;}),
spendPerYear = yearDim.group().reduceSum(function(d) {return +d.Spent;}),
spendPerName = nameDim.group().reduceSum(function(d) {return +d.Spent;}),
x = spendPerName,
spendHist = spendDim.group().reduceCount();
render_plots();
}, 3000);
</script>
</body>
</html>