0

I have three Row Charts and my code calculates and updates the percentages for each chart whenever a user first lands on the page or clicks a rectangle bar of a chart.  This is how it calculates the percentages

posChart:
% Position= unique StoreNumber counts per Position / unique StoreNumber counts for all POSITIONs

deptChart:
% Departments= POSITION counts per DEPARTMENT/POSITION counts for all DEPARTMENTs

stateChart:
% States= unique StoreNumber counts per STATE / unique StoreNumber counts for all STATEs

What I want is when a user clicks a rectangle bar of a rowChart such as “COUNTS BY STATE”, it should NOT update/recalculate the percentages for that chart (it should not affect its own percentages), however, percentages should be recalculated for the other two charts i.e. “COUNTS BY DEPARTMENT” and “COUNTS BY POSITION”.  The Same scenario holds for the other charts as well. This is what I want

If a user clicks a

  1. “COUNTS BY DEPARTMENT” chart --> recalculate percentages for “COUNTS BY POSITION” and “COUNTS BY STATE” charts

  2. “COUNTS BY POSITION” chart --> recalculate percentages for “COUNTS BY DISTRIBUTOR” and “COUNTS BY STATE” charts

Please Help!!
link:http://jsfiddle.net/mfi_login/z860sz69/

Thanks for the reply. There is a problem with the solution you provided. I am looking for the global total for all filters but I don’t want those totals to be changed when user clicks on a current chart's rectangular bar.
e.g. if there are two different POSITIONS (Supervisor, Account Manager) with the same StoreNumber (3), then I want StoreNumber to be counted as 1 not 2

If we take an example of Account Manager % calculation (COUNTS BY POSITION chart)

total unique StoreNumbers=3
Total Account Manager POSITIONs=2
% = 2/3=66%

Is there a way to redraw the other two charts without touching the current one?

1 Answers1

0

It seems to me that what you really want is to use the total of the chart's groups, not the overall total. If you use the overall total then all filters will be observed, but if you use the total for the current group, it will not observe any filters on the current chart.

This will have the effect you want - it's not about preventing any calculations, but about making sure each chart is affected only by the filters on the other charts.

So, instead of bin_counter, let's define sum_group and sum_group_xep:

function sum_group(group, acc) {
    acc = acc || function(kv) { return kv.value; };
  return d3.sum(group.all().filter(function(kv) {
    return acc(kv) > 0;
  }), acc); 
}

function sum_group_xep(group) {
    return sum_group(group, function(kv) {
    return kv.value.exceptionCount;
  });
}

And we'll use these for each chart, so e.g.:

    posChart
        .valueAccessor(function (d) { 
            //gets the total unique store numbers for selected filters                
            var value=sum_group_xep(posGrp)
            var percent=value>0?(d.value.exceptionCount/value)*100:0                
            //this returns the x-axis percentages
            return percent               
        })

    deptChart
        .valueAccessor(function (d) { 
                total=sum_group(deptGrp)
                var percent=d.value?(d.value/total)*100:0
                return percent
        })  

    stateChart 
        .valueAccessor(function (d) {
            var value=sum_group_xep(stateGrp);
            return value>0?(d.value.exceptionCount/value)*100:0
        })  

... along with the other 6 places these are used. There's probably a better way to organize this without so much duplication of code, but I didn't really think about it!

Fork of your fiddle: http://jsfiddle.net/gordonwoodhull/yggohcpv/8/

EDIT: Reductio might have better shortcuts for this, but I think the principle of dividing by the total of the values in the current chart's group, rather than using a groupAll which observes all filters, is the right start.

Gordon
  • 19,811
  • 4
  • 36
  • 74