0

I am writing a web app that allows users to dynamically create one or more charts using dc.js. The user can specify some filter parameters, and the resulting JSON is retrieved and loaded into a new dc.js bar chart each time.

What I want though is for all the charts to be linked, so that if they filter on a chart it does the same on others, and if they zoom/scroll on a chart this also happens on the others. They all share the same data range on the x-axis (date). My understanding was that this is exactly what dc.js is for.

I have a single data array that all the data is being loaded into (so if they add another chart, the data is added into the existing array), and I have the crossfilter object pointed at this. I'm aware that crossfilter doesn't support updating data, so every time I change the array I recreate the crossfilter object. All the charts are using the same dimension and scale objects, which are also recreated on new data.

The data array, with two sets of data added, looks like:

[
  {dd: [Date object], date: "2015-09-14", count-1: 5, count-2: 23},
  {dd: [Date object], date: "2015-09-15", count-1: 3, count-2: 6},
  {dd: [Date object], date: "2015-09-16", count-1: 8, count-2: 34}
]

My reload function looks like:

function reloadData(){
  cf = crossfilter(allData);
  dimension = cf.dimension(function(d) { return d.dd } );
  scale = d3.time.scale().domain([allData[0].dd, allData[data.length - 1].dd]);
}

I create the chart as follows:

var chart = dc.barChart(id);
d3.json(url, function(error, json){
  //Load JSON into array here

  reloadData();

  var group = dimension.group().reduceSum(function(d) { return +d["count-"+id]; } );

  chart
    .dimension(dimension)
    .group(group)
    .x(scale)
    .xUnits(d3.time.days)
    .elasticY(true)
    .brushOn(true)
    .title(function(d) { return d.data.value; })
    .centerBar(true)
    .width(1140);
  chart.render();
  dc.redrawAll();
});

My code is unfortunately on an offline system, so the whole page isn't easy to share. Can anyone suggest what I might be missing though?

James Baker
  • 1,143
  • 17
  • 39
  • note that the zoom/scroll requirement is not something dc.js does automatically, although it sounds close to the idea of multiple focus charts for a range chart: http://stackoverflow.com/questions/27445259/dc-js-applying-range-chart-to-multiple-graphs/ – Gordon Sep 18 '15 at 09:13

1 Answers1

3

It looks like all your charts are based on a single dimension. Crossfilter filters are applied on a dimension and do not apply to groups on the same dimension as the filter. Therefore, charts defined on the same dimension will not change when filters are applied. I'd recommend you define new dimensions for each chart.

Ethan Jewett
  • 6,002
  • 16
  • 25
  • Thanks - I now create a new dimension in the createTimeline function so that each chart has it's own dimension. Presumably though, each time I recreate the crossfilter object to add new data, I will need to recreate all the dimensions? – James Baker Sep 17 '15 at 08:15
  • 1
    Don't recreate the crossfilter object to add new data. Use crossfilter.add() on your existing crossfilter. :-) – Ethan Jewett Sep 18 '15 at 15:11