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

1

6

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

Agnostic answered 31/12, 2013 at 7:44 Comment(3)
You could add the values that pertain to the state (zoom, translate, etc) to the URL of the page as a query string and then parse them using JS (see e.g. #980475). Would that do what you want?Chandless
I think what Lars is saying is a good solution, but it may be tedious to code every time. It sounds like a great optional feature for the library to build in. You could request it in the github issues or do a pull request yourself.Fredela
#27675827 please help meMcmillin
J
11

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.

Johore answered 3/1, 2014 at 2:46 Comment(5)
Thanks a lot for this answer. It definitely looks like what I have in mind. My scenario would be to append the stringified filter as a URL param. Would you have a working example of the script? I tried to implement it in my project but it looks like I miss something...Agnostic
Just to clarify: One use case would be to allow users to freeze the visualisation and give them the opportunity to raise questions (for instance through Twitter) on the patterns they may find (trying to achieve an open data feedback loop). Another use case would be to insert some sort of story telling in the viz through links to specific filter states.Agnostic
github.com/dc-js/dc.js/issues/490#issuecomment-33299790 --> Thanks to Carlos for the great example!Agnostic
In case someone, is looking for a working example, check the repo -- line 134 @ github.com/Edouard-Legoupil/3W-Dashboard/blob/gh-pages/…Agnostic
@DJ Martin When I use above code to get the saved filters I am getting different chartID after navigating to different page of my application. Any help will be appreciated.Rule

© 2022 - 2024 — McMap. All rights reserved.