barChart click event unable to toggle Selected and Deselected

298 views
Skip to first unread message

Utsav

unread,
Oct 18, 2017, 11:46:39 AM10/18/17
to dc-js user group
Hi All, 

I have click event on a barChart. I am looking to fade unselected bars. I am looking to toggle 'selected'  and 'deselected' class on bar.  

Looking at the source code, I believe I have to use .fadeDeselectedArea. When I try to add that I get:


Cannot read property 'selectAll' of undefined at Object._chart.fadeDeselectedArea (dc.js:5491) at window.onload


 Am I doing anything wrong? 




Thanks, 
Utsav. 

gor...@woodhull.com

unread,
Oct 18, 2017, 2:01:31 PM10/18/17
to dc-js-us...@googlegroups.com
Hi Utsav,

That's some good digging - indeed, fadeDeselectedArea is the function
dc.js uses to fade the deselected bars, but unfortunately it's an
internal function - not an option like you might expect, but a method
that actually applies the styles when the chart is drawing itself.

It would be great if the style of brushing were an option so that you
could enable ordinal-style click filtering when the scale is
quantitative, and brushing when the scale is ordinal.

It doesn't look like you can use to deselect bars when you are
performing the selection yourself, because it relies on the brush to
figure out which bars are selected, and you've disabled the brush.

There is also a problem with how you are performing the filtering -
when the bar chart has a quantititative scale, it's expecting the
filter to be a ranged filter. chart.filter also *toggles* filters
instead of replacing them, so you should set the filter like this:

chart.replaceFilter(dc.filters.RangedFilter(d.data.key,
d.data.key+1))

Note that you'll have to change "1" to whatever the width of your bars
really is.

Then, since you can't use the built-in fade, you could apply your own
fade like this:

chart.selectAll('rect.bar').classed('my-fade',
function(d1) { return d1.data.key !== d.data.key});


and set your own css for .my-fade, e.g.

rect.my-fade {
fill: #ddd;
}

Here's a fork of your fiddle: https://jsfiddle.net/gordonwoodhull/4zy79ofo/11/

Cheers,
Gordon
> --
> You received this message because you are subscribed to the Google
> Groups "dc-js user group" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to dc-js-user-gro...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/dc-js-user-group/5a5aba84-5480-41bf-a59c-2ccd0be55e83%40googlegroups.com.



Utsav

unread,
Oct 18, 2017, 2:33:54 PM10/18/17
to dc-js user group
Hi Gordon, 
Your solution works. Thanks a lot for the detailed description.  Good catch on chart.filter and great job with all dc questions over all :) 

Utsav

unread,
Oct 18, 2017, 2:35:52 PM10/18/17
to dc-js user group
Hi Gordon, 
Your solution works. Thanks a lot for the detailed description.  Good catch on chart.filter and great job with all dc questions over all :) 

Adnan Boota

unread,
Nov 22, 2018, 9:27:38 AM11/22/18
to dc-js user group
Hi Gordon,

Nice solution, i'm trying to implement for the barChart with scaleTime() when i select, i want to update the datatable which is not updating. 

Could you please tell me how can i update the datatable values based on selecting bar from scaleTime()?

what i have to do update to the datatable, as i have tried a lot of things but it's not working.
chart.selectAll('rect').on("click", function (d) {
                    console.log("click!", d.data)
                    chart.selectAll('rect.bar').classed('my-fade', function (d1) {
                        return d1.data.key !== d.data.key
                    });
           processInfoTable.replaceFilter(dc.filters.RangedFilter(d.data.key, d.data.key));
                    // chart.replaceFilter([d.data.key]);
                    // chartTimeDimension.filterRange([overviewChart_start_date, overviewChart_end_date]);
                    // timeHistChart.x(d3.scaleTime().domain([d.data.key, d.data.key]));

                    // dc.filterAll();
                    // spendDim.filterRange([d.data.key, d.data.key]);
                    // timeHistChart.x(d3.scaleTime().domain([moment(d.data.key), moment(d.data.key)]));
                    // spendDim.filterRange([moment(d.data.key), moment(d.data.key)]);
                    // spendDim.filter(d.data.key);
                    // chartTimeDimension.filter(d.data.key);
                    // chartTimeDimension.filter([d.data.key]);
                    // chart.replaceFilter(dc.filters.RangedFilter(moment(d.data.key), moment(d.data.key)));
                    // chart.redrawGroup();
                    // processInfoTable.filterRange([d.data.key, d.data.key]);
                    // processInfoTable.filter([moment(d.data.key), moment(d.data.key).add(1, 'day')]);
                   
                    // update();
                    // processInfoTable.redraw();
                    // dc.filterAll();
                })

Gordon Woodhull

unread,
Nov 22, 2018, 10:07:23 AM11/22/18
to dc-js-us...@googlegroups.com
Hi Adnan,

Doesn't sound like this is related to the topic in this thread.

You shouldn't need to manually filter the bar chart or dc.dataTable - that's automatic. (Unless you are talking about datatables.js, which does take a bit more work.)

Often when charts do not update each other it's because they are on the same dimension. It's by design but a common crossfilter stumbling block, so I documented it here:

https://github.com/crossfilter/crossfilter/wiki/Crossfilter-Gotchas#a-group-does-not-observe-its-dimensions-filters


If that's not it, I'd have to see a running example or at least the complete code. You shouldn't need to do any of the things that are commented out below, so the problem is probably in your dimension/group/chart definitions.


Cheers,

Gordon 


Reply all
Reply to author
Forward
0 new messages