1

I have gone through all the SO questions on removing empty bins from a dc.js graph but couldn't find anything besides the fake group approach

filter_group = function(oldGroup) {
    return {
        all: oldGroup.all().filter(...)
    };
}
newGroup = filter_group(oldGroup);

and then use newGroup in the dc.js graphs.

What this does for me is create the right set of bins on first draw but it doesn't re-filter when I apply filters to other dimensions. So I end up with the correct intial bins but in subsequent redraws I still end up with empty bins.

What I would like to achieve is proper re-filter and redraw i.e getting rid of the bins according to my filter function and redraw excluding the filtered bins so having a varying number of bins.

Here is a fiddle that shows what I mean. I have set up the data so that filtering on a in the first graph should remove the g bar in the second (and filtering on g in the second should remove the a one in the first graph) But it doesn't remove the empty bar from the axis, it just shows the label with no bar.

Starting point : enter image description here

After filtering on g in second graph (I would like a to not even show on the axis) : enter image description here

PS : I have tagged reductio and d3.js in case there is an elegant solution using those packages even though I'd rather keep it within dc.js.

Chapo
  • 2,563
  • 3
  • 30
  • 60
  • I just removed the Javascript tag because these questions tend to get downvotes when they have that tag :( It would be really helpful if you could share an example of what you're actually trying to do, what dc.js chart you are using, etc. Generally I would say a fake group is the best thing to do if you just want to filter out empty groups. But it seems like that's not working for you and we would need to see more context to help you fix it. That said, the fact that your fake group is using `.map` and not `.filter` may be contributing to your problem. – Ethan Jewett Apr 24 '18 at 00:17
  • This is just pseudo code. I actually use filter in my actual code. Will try and come up with a fiddle – Chapo Apr 24 '18 at 00:18
  • 1
    Thanks - and in the future, please try to include a real working example in your question, not pseudo-code. This introduction of unintentional issues (or even removing the actual issue) tends to happen a lot when converting questions to pseudo-code :D – Ethan Jewett Apr 24 '18 at 00:21
  • added a proper fiddle in the question – Chapo Apr 24 '18 at 06:48
  • Sorry, this fiddle doesn't run (`group is not defined`) and doesn't seem to have `remove_empty_bins` in it. – Gordon Apr 24 '18 at 14:17
  • I'm guessing in your real code the x scale is ordinal and that might have something to do with it. In the fiddle, it's a time scale, which wouldn't make sense for a,b,c,d,... – Gordon Apr 24 '18 at 15:22
  • Must be the wrong link I put in there. Will have a look. – Chapo Apr 24 '18 at 15:26
  • Yeah, IIRC, you have to re-render to get the actual buckets/axis to update, and the default is just to redraw (as it should be). – Ethan Jewett Apr 24 '18 at 17:30
  • have updated the fiddle link. will have a look at re-rendering – Chapo Apr 25 '18 at 01:21
  • cf the fiddle. even when adding a `on("filtered",...` event to force the other graph to re-render it doesn't get rid of the empty bin. – Chapo Apr 25 '18 at 01:31

1 Answers1

0

The X scale's domain determines which bars are shown.

You are manually setting the domains on your charts:

.x(d3.scale.ordinal().domain(filter_group(group).all().map(function(d) {return(d.key);}).unshift("")))

I'm sure you were solving some other problem with that, but if you remove that, and specify

.elasticX(true)

instead, then you don't need the on("filtered",... and the charts will remove bins when their values are zero.

Fork of your fiddle.

Gordon
  • 19,811
  • 4
  • 36
  • 74