javascript - 直流交叉滤波器不工作

标签 javascript grails dc.js crossfilter

在这里使用 dc 和 cross-filter js 库构建一个 grails 应用程序,但不知何故在可视化中遇到了一个非常奇怪的问题。

我的可视化是 5 个条形图,它们使用 dc 和 cross-filter js 库相互连接。

因此,有简单指标计算指标 (%) 和最后的计算指标(无 %)。对于这三种类型,每部分代码中都有三种不同类型的if-else(针对5条柱状图)

但是,问题出在最后一个 if-else,这里的交叉过滤器出错了,我们在几次选择后得到了负值,所有的栏图表离开 x 轴。这非常奇怪,我不明白这里出了什么问题。 (引用下图)

我们在第二个 if-else 和第三个 if-else 中有相同的代码片段,但是第三个 if-else 搞砸了交叉过滤器的功能。有人可以解释这里出了什么问题吗?

代码:

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

更新:

好的,在答案的帮助下,我更改了我的代码如下,负条消失了,但仍然只有初始 View 是正确的。 之后,如果我选择任何条形来过滤所有图表,则不会进行过滤。图表不再改变。

代码#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;
     },

我尝试在从回调方法中删除记录前后添加片段,但它们都不起作用

欢迎所有的方法/建议

最佳答案

很难说没有一个有效的例子,但我认为你的问题是在你的添加函数中你添加了“p.sumIndex2 += v.h”,而在你的删除函数中你减去“p.sumIndex2 -= v.g”。所以你的 sumIndex2 并没有真正跟踪任何特定的值。您应该从中添加和减去相同的内容,以便添加记录然后删除它不会产生任何变化。

此外,您应该在删除记录时重新计算平均值,而不仅仅是在添加记录时。应用过滤器后,您的平均值将会出错。

我还建议只创建您需要的所有三个组和带有默认组的条形图。然后在条形图上切换出组,并在您要显示的组更改时重新呈现。

关于javascript - 直流交叉滤波器不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25180398/

相关文章:

javascript - DC.js 动态刷新图表以使用更新的数据集

hibernate - 将字符串列转换为 Long grails createCriteria

grails - Grails 3.3.8:无法解析ControllerUnitTest

csv - 在 DC.js 中加载多个 CSV,添加一个值,并将结果连接到单个数据表中

javascript - React JS 自定义图表

javascript - 将其中的一部分替换为js

grails - 如何在 Config.groovy 中获取 Grails 应用程序名称?

javascript - 在 crossfilter 的 reducio 中将自定义函数与预定义函数混合

javascript - 使用两组的 dc.js 箱形图缩减器

JavaScript:如何获取给定函数对象的函数定义