Dc cross-filter not working

自作多情 提交于 2019-12-19 11:42:09

问题


Building a grails application using dc & cross-filter js libraries here, but facing an extremely weird issue in the visualization somehow.

My visualization is of 5 bar charts, which are interconnected to each other using dc and cross-filter js libraries.

So, there are simple metrics, calculated metrics (%) and lastly calculated metrics (without %). For these three types, there are three different types of if-else in each part of code (for 5 bar charts)

But, the problem lies in the last if-else, here the cross-filter goes wrong and we get negative values after a couple of selections and all the bar charts are lifted off the x-axis. This is extremely weird and I don't understand what is going wrong here. (See image below for reference)

We have the same code snippet in the second if-else and the third if-else, but the third if-else screws up the functionality of cross-filter. Can someone please explain what is going wrong here?

Code :

var devValue = facts.dimension(function (d) {return d.c;});
   var a = ($('metric').value);
   // Basic metrics
   if(a == "Product views"||a == "Visits"||a == "Units")
   {
   var devValueGroupSum = devValue.group().reduceSum(function(d) { return +d.g;});

     barChart4.width(600)
    .height(250)
    .margins({top: 10, right: 100, bottom: 20, left: 80})
    .dimension(devValue)
    .yAxisLabel($('metric').value)
    .group(devValueGroupSum)                            
    .transitionDuration(800)
    .centerBar(true)    
    .gap(60)                                            
    .x(d3.scale.ordinal().domain(["DESKTOP/LAPTOP", "SMARTPHONES", "TABLETS","OTHERS"]))
    .brushOn(false)
    .title(function(d) { return d.key + ": " + d3.round(d.value,2); })
    .elasticY(true)
    .barPadding(0.5)
    .xUnits(dc.units.ordinal);  
   }//end of if

  // Calculated metrics (%)
  else if(a == "Conversion Rate"||a=="Bounce Rate")
  {
    var devValueGroupSum = devValue.group().reduce(
     function (p, v) {
            p.sumIndex1 += v.g
            p.sumIndex2 += v.h
            if (p.sumIndex2 === 0)
            p.avgIndex = 0;
            else 
            p.avgIndex = (p.sumIndex1 / p.sumIndex2) * 100 ;
            return p;
        },
       function (p, v) {
            p.sumIndex1 -= v.g;
            p.sumIndex2 -= v.g;
            return p;
        },
function () {
            return {sumIndex1: 0,sumIndex2:0, avgIndex: 0};
        }
     );//end of reduce
        barChart4.width(600)
    .height(250)
    .margins({top: 10, right: 100, bottom: 20, left: 80})
    .dimension(devValue)                                
    .group(devValueGroupSum)
     .valueAccessor(function (p) {
            return p.value.avgIndex;
        })
    .transitionDuration(800)
    .yAxisLabel($('metric').value)
    .centerBar(true)    
    .gap(60)                                            
    .x(d3.scale.ordinal().domain(["DESKTOP/LAPTOP", "SMARTPHONES", "TABLETS","OTHERS"]))
    .brushOn(false)
    .title(function(d) { return d.key + ": " + d3.round(d.value.avgIndex,2); })
    .elasticY(true)
    .barPadding(0.5)
    .xUnits(dc.units.ordinal);  

  }//end of else-if

   // Calculated metrics ( without %)
   else if(a == "Average Order Size(AOS)" || a=="Average Unit Revenue(AUR)" || a=="Units per order")
  {
    var devValueGroupSum = devValue.group().reduce(
     function (p, v) {
            p.sumIndex1 += v.g
            p.sumIndex2 += v.h
            if (p.sumIndex2 === 0)
            p.avgIndex = 0;
            else 
            p.avgIndex = (p.sumIndex1 / p.sumIndex2) * 1 ;
            return p;
        },
       function (p, v) {
            p.sumIndex1 -= v.g;
            p.sumIndex2 -= v.g;
            return p;
        },
function () {
            return {sumIndex1: 0,sumIndex2:0, avgIndex: 0};
        }
     );//end of reduce

     barChart4.width(600)
    .height(250)
    .margins({top: 10, right: 100, bottom: 20, left: 80})
    .dimension(devValue)                                
    .group(devValueGroupSum)
    .valueAccessor(function (p) {
            return p.value.avgIndex;
        })
    .transitionDuration(800)
    .yAxisLabel($('metric').value)
    .centerBar(true)
    .gap(60)                                            
    .x(d3.scale.ordinal().domain(["DESKTOP/LAPTOP", "SMARTPHONES", "TABLETS","OTHERS"]))
    .brushOn(false)
    .title(function(d) { return d.key + ": " + d3.round(d.value.avgIndex,2); })
    .elasticY(true)
    .barPadding(0.5)
    .xUnits(dc.units.ordinal);  

  }

else
{
}//end of else

UPDATE:

okay, with the help of answers, I changed my code as following, the negative bars have disappeared but still only the initial view is correct. After which, if I select any of the bars to filter across all the charts, the filtering does not happen. Charts don't change anymore.

Code #2 :

function (p, v) {
         //snippet begins
         p.sumIndex1 += v.g
         p.sumIndex2 += v.h
         if (p.sumIndex2 === 0)
         p.avgIndex = 0;
         else 
         p.avgIndex = (p.sumIndex1 / p.sumIndex2) ;
         //snippet ends
         p.sumIndex1 -= v.g;
         p.sumIndex2 -= v.h;

         return p;
     },

I have tried adding the snippet before and after the removal of records from the callback method, but neither of them work

All approaches/suggestions are most welcome


回答1:


Hard to say without a working example, but I think your problem is that in your add function you are adding "p.sumIndex2 += v.h" while in your remove function you are subtracting "p.sumIndex2 -= v.g". So your sumIndex2 isn't really tracking any specific value. You should add and subtract the same thing from it so that adding a record and then removing it results in no change.

Additionally, you should recalculate your average value when you remove records, not just when you add them. Your average is going to be wrong after filters are applied.

I'd also recommend just creating all three groups you need and the bar chart with the default group. Then switch out the group on the bar chart and rerender it when the group you want to display changes.



来源:https://stackoverflow.com/questions/25180398/dc-cross-filter-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!