Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dc.js permalink or href to share the visualisation filter state?

I am working on a dataviz with dc.js (http://edouard-legoupil.github.io/3W-Dashboard/)

The main limitation is that when users find a specific fact while they explore the data, it is not easy to reproduce the exact filters they used in order to share their findings with other users (and initiate a discussion). A solution could be to have permalinks for each filter state.

dc.js has already the "dc.redrawAll();" to reset all filter but is there any capacity to freeze a certain filters state and pass it to a #href?

Ideally such href would be then shared through a share button or through the regular facebook/twitter sharing function.

Any code snippet or examples would really help!

Thanks in advance, Edouard

like image 267
user3148607 Avatar asked Dec 31 '13 07:12

user3148607


1 Answers

Here are the key methods that you will want to use:

  • dc.chartRegistry.list(): retrieves an array of all charts that dc has loaded
  • chart.filters(): retrieves an array of all filters for a given chart
  • chart.filter(): applies a filter to a given chart
  • dc.redrawAll(): redraws all charts after applying external filters

From there it's just a matter of serializing and deserializing the objects.

Here is one way to do that by stringifying a JSON object:

var filters = [];
for (var i = 0; i < dc.chartRegistry.list().length; i++) {
    var chart = dc.chartRegistry.list()[i];
    for (var j = 0; j < chart.filters().length; j++){
        filters.push({ChartID: chart.chartID(), Filter: chart.filters()[j]});  
    }
}
var urlParam =  encodeURIComponent(JSON.stringify(filters));

Here is the reverse process of parsing the JSON string and applying the filters:

var urlParam = ""; //have user input string somehow
var filterObjects = JSON.parse(decodeURIComponent(urlParam));
for (var i = 0; i< filterObjects.length; i++)
{
    dc.chartRegistry.list()[filterObjects[i].ChartID-1].filter(filterObjects[i].Filter);
}
dc.redrawAll();

Connecting the two steps will depend on your scenario. You could perhaps save the string to the database or append it as a url param.

This code might be missing some edge cases, but it seems to work for the basic dc.js examples.

like image 144
DJ Martin Avatar answered Sep 22 '22 13:09

DJ Martin