storing dc.js filters in URI and restoring them
Asked Answered
P

2

1

Here i selected 3 filters 1 from each chart and pasted that encoded url in url param. but when i press decode url button it is redrawing only middle chart filters but not the remaining once.. what should i do? thanks

function encodeFunction()
{
    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));
    alert(urlParam);
}
function decodeFunction()
{
    //encoded url here
    var urlParam="%5B%7B%22ChartID%22%3A1%2C%22Filter%22%3A2012%7D%2C%7B%22ChartID%22%3A2%2C%22Filter%22%3A%5B1.0454545454545454%2C4.045454545454545%5D%7D%2C%7B%22ChartID%22%3A3%2C%22Filter%22%3A%22Mr%20B%22%7D%5D ";

    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.renderAll();

    dc.redrawAll();
}

here is the fiddle: js fiddle link

Primine answered 28/12, 2014 at 9:51 Comment(3)
I'm no expert at dc.js, but you might get more people willing to answer if you ran your code through jsbeautifier.org and only supplied the code relevant to your problem. If there's an error being thrown, perhaps a stacktrace would be helpful as well. This seems like a vague problem to me, and would be a much better question if you could at least narrow down what your problem is.Lid
I agree with @PatrickRoberts. The better/more polite way to a ask this kind of question is to put your code in a jsFiddle so that people can try it out. Then post only the relevant parts in your SO question. Will upvote back to zero if you edit. :-) It's an interesting problem btw. We'd like to have a canonical way to store filters in an URL.Katiekatina
fixed your formatting and added a code snippet.Katiekatina
K
2

It looks like your code is correct for the general case, but due to some quirks in the way that dc.js handles filters, you can't just restore a range filter from its serialized form.

I was able to get it working by adding a special case for arrays:

   for (var i = 0; i< filterObjects.length; i++)
   {
       var filter = filterObjects[i].Filter;
       if(filter instanceof Array) filter = dc.filters.RangedFilter(filter[0], filter[1]);
       dc.chartRegistry.list()[filterObjects[i].ChartID-1].filter(filter);
   }

Here is my fork of your fiddle: http://jsfiddle.net/gordonwoodhull/4dv93aht/10/

I don't think such special cases should be needed, so I opened an issue here: https://github.com/dc-js/dc.js/issues/819

Katiekatina answered 30/12, 2014 at 17:15 Comment(2)
Glad to help. Please accept the answer... only so I can better keep track of the tag, of course. ;-)Katiekatina
yeah it worked for me...@Katiekatina . thank you once againPrimine
P
1

Have a look at this question & working example dc.js permalink or href to share the visualisation filter state?

https://github.com/Edouard-Legoupil/3W-Dashboard/blob/gh-pages/index.html

Prejudge answered 29/12, 2014 at 12:5 Comment(1)
I like this approach better because it explicitly fetches the filters and applies them by name, rather than by index - although the code in the question is good for a quick and dirty solution. Thanks for sharing, I will be sure to use this when I document how to do this. For now this question can serve as informal docs.Katiekatina

© 2022 - 2024 — McMap. All rights reserved.