问题描述
使用dc& amp; amp;在这里交叉过滤js库,但在可视化方面面临着一个非常奇怪的问题。我的可视化图是5个柱状图,它们使用dc和因此,有简单指标,计算指标(%),最后是 strong>计算的指标(不含%)。对于这三种类型,在代码的每个部分中都有三种不同类型的if-else(对于5个条形图)
但是,问题在于最后一个if-else ,这里交叉过滤器出错,经过几次选择后我们得到负值,并且所有条形图都从x轴移开。这非常奇怪,我不明白这里出了什么问题。 (请参阅下图以供参考)
第二个if-else和第三个if-else中有相同的代码片段,但第三个if-else将交叉过滤器的功能。有人可以解释这里出了什么问题吗?
代码:
var devValue = facts.dimension(function(d){return dc;});
var a =($('metric')。value);
//基本指标
if(a ==Product views|| a ==Visits|| a ==Units)
{
var devValueGroupSum = devValue.group()。reduceSum(function(d){return + dg;});
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);
} //如果
结束//计算出的指标(%)
else if(a ==Conversion Rate|| a ==Bounce Rate)
{
var devValueGroupSum = devValue.group()。reduce(
function(p,v){
p.sumIndex1 + = vg
p.sumIndex2 + = vh
if(p.sumIndex2 === 0)
p.avgIndex = 0;
else
p.avgIndex =(p.sumIndex1 / p.sumIndex2)* 100;
返回p;
},
函数(p,v){
p.sumIndex1 - = vg;
p.sumIndex2 - = vg;
return (b)
},
function(){
return {sumIndex1:0,sumIndex2:0,avgIndex:0};
}
); // end of减少
barChart4.width(600)
.height(250)
.margins({top:10,right:100,bottom:20,left:80})
。维(devValue)
.group(devValueGroupSum)
.valueAccesso r(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
//计算出的度量(不含%)
else if(a ==Average Order Size(AOS) || a ==平均单位收入(AUR)|| a ==单位每个订单)
{
var devValueGroupSum = devValue.group()。reduce(
function( p,v){
p.sumIndex1 + = vg
p.sumIndex2 + = vh
if(p.sumIndex2 === 0)
p.avgIndex = 0;
else
p.avgIndex =(p.sumIndex1 / p.sumIndex2)* 1;
return p;
},
function(p,v){
p.sumIndex1 - = vg;
p.sumIndex2 - = vg;
return p;
},
function(){
return {sumIndex1:0 ,sumIndex2:0,avgIndex:0};
}
); //结束减少
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
更新:
好的,在回答的帮助下,我改变了我的代码如下,负面栏消失了,但仍然只有最初的观点是正确的。
之后,如果我选择任何横条过滤所有图表,则不会发生过滤。
代码#2:
函数(p,v){
// snippet开始
p.sumIndex1 + = vg
p.sumIndex2 + = vh
if(p.sumIndex2 === 0)
p.avgIndex = 0;
else
p.avgIndex =(p.sumIndex1 / p.sumIndex2);
// snippet结束
p.sumIndex1 - = v.g;
p.sumIndex2 - = v.h;
return p;
},
我曾尝试添加代码段从回调方法中删除记录后,但他们都没有工作
所有方法/建议都是最受欢迎的
另外,您应该在移除时重新计算平均值记录,而不仅仅是当你添加它们。在应用过滤器后,您的平均分会出错。
我还建议您只创建所需的三个组,并使用默认组的条形图。然后在条形图上将组切换出来,并在要显示的组发生变化时重新渲染。
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
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.
这篇关于直流过滤器不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!