Javascript DC.js compositeChart,带有两个折线图,均表示日期的平均值
我想创建一个DC.js图表,其中两行分别表示日期的平均值 我相信这样做的方法是使用DC.jsJavascript DC.js compositeChart,带有两个折线图,均表示日期的平均值,javascript,d3.js,dc.js,crossfilter,Javascript,D3.js,Dc.js,Crossfilter,我想创建一个DC.js图表,其中两行分别表示日期的平均值 我相信这样做的方法是使用DC.jscompositeChart并创建两个折线图放入其中,然后使用reduceio()group.reduce(添加、删除、初始)获得平均金额 我的问题是,条件逻辑去了哪里?我如何/在何处有条件地使用此选项: var group = dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial); 要计算具有d.PPCC==“PPCC”的
compositeChart
并创建两个折线图放入其中,然后使用reduceio()
group.reduce(添加、删除、初始)
获得平均金额
我的问题是,条件逻辑去了哪里?我如何/在何处有条件地使用此选项:
var group = dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial);
要计算具有d.PPCC==“PPCC”
的记录的平均值,以及具有d.PPCC==“Other”
的记录的另一个平均值
我试过两种方法,但都不管用
这是第一次尝试:
var bounce30DaysPPCC = function(d) { if (d.PPCC === "PPCC")
{ dateDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
} else { dateDim.group().reduce(0); } };
var bounce30DaysOther = function(d) { if (d.PPCC === "Other")
{ dateDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
} else { dateDim.group().reduce(0); } };
这将产生以下错误:
dc.js:4017 Uncaught TypeError: layer.group.all is not a function
这是第二次尝试:
var bounce30DaysPPCC = dateDim.group().reduce( function(d) { if (d.PPCC === "PPCC")
{ return reduceAdd, reduceRemove, reduceInitial; } else { return 0; }});
var bounce30DaysOther = dateDim.group().reduceSum( function(d) { if (d.PPCC === "Other")
{ return reduceAdd, reduceRemove, reduceInitial; } else { return 0; } });
这也会产生一个错误:
Uncaught TypeError: reduceInitial is not a function
这是我的完整javascript代码
<script type="text/javascript">
// get csv data
d3.csv("merged.csv", function(data) {
// get csv data and format date
var parseDate = d3.time.format("%Y-%m-%d").parse;
data.forEach(function(d) {
d.date = parseDate(d.date);
d.sessions = +d.sessions;
d.ad_requests = +d.ad_requests;
d.bounceRate = +d.bounceRate;
d.clicks = +d.clicks;
d.earnings = +d.earnings;
d.newUsers = +d.newUsers;
d.sessionDuration = +d.sessionDuration;
d.sessionsPerUser = +d.sessionsPerUser;
d.twitterSessions = +d.twitterSessions;
d.users = +d.users;
});
// setup crossfilter
var ndx = crossfilter(data);
// create dimension
var dateDim = ndx.dimension(function(d) { return d["date"]; });
// create data groups
var bounce30DaysPPCC = function(d) { if (d.PPCC === "PPCC")
{ dateDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
} else { dateDim.group().reduce(0); } };
var bounce30DaysOther = function(d) { if (d.PPCC === "Other")
{ dateDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
} else { dateDim.group().reduce(0); } };
// create min and max dates to limit chart x axis values
var minDateTime = new Date(new Date().setDate(new Date().getDate()-30));
var maxDateTime = new Date(new Date().setDate(new Date().getDate()+1));
// create chart
BounceChart30Day = dc.compositeChart("#bounce-chart-30day");
// create two line charts to put into composite chart
var ppccLine = dc.lineChart(BounceChart30Day)
.group(bounce30DaysPPCC)
var otherLine = dc.lineChart(BounceChart30Day)
.group(bounce30DaysOther)
// create composite chart
BounceChart30Day
.height(50)
.width(450)
.margins({top: 10, right: 10, bottom: 5, left: 35})
.dimension(dateDim)
.transitionDuration(500)
.brushOn(false)
.elasticY(true)
.compose([ppccLine, otherLine])
.x(d3.time.scale().domain([minDateTime, maxDateTime]))
.yAxis().ticks(3);
// create value accessor to calculate averages
BounceChart30Day.valueAccessor(function(p) {
return p.value.count > 0 ? p.value.total / p.value.count : 0; });
// create add, remove, initial reduce functions
function reduceAdd(p, v) {
++p.count;
p.total += v.bounceRate;
return p;
}
function reduceRemove(p, v) {
--p.count;
p.total -= v.bounceRate;
return p;
}
function reduceInitial() {
return {count: 0, total: 0};
}
// render chart
dc.renderAll();
</script>
//获取csv数据
d3.csv(“merged.csv”,函数(数据){
//获取csv数据并格式化日期
var parseDate=d3.time.format(“%Y-%m-%d”).parse;
data.forEach(函数(d){
d、 日期=解析日期(d.date);
d、 sessions=+d.sessions;
d、 ad_请求=+d.ad_请求;
d、 反弹率=+d.反弹率;
d、 点击次数=+d次点击;
d、 收益=+d.收益;
d、 newUsers=+d.newUsers;
d、 持续时间=+d.持续时间;
d、 sessionsPerUser=+d.sessionsPerUser;
d、 twitterSessions=+d.twitterSessions;
d、 用户=+d用户;
});
//设置交叉滤波器
var ndx=交叉滤波器(数据);
//创建维度
var dateDim=ndx.dimension(函数(d){returnd[“date”];});
//创建数据组
var bounce30dayspcc=函数(d){if(d.PPCC==“PPCC”)
{dateDim.group().reduce(reducead、reduceRemove、reduceInitial);
}else{dateDim.group().reduce(0);};
var bounce30DaysOther=函数(d){if(d.PPCC==“其他”)
{dateDim.group().reduce(reducead、reduceRemove、reduceInitial);
}else{dateDim.group().reduce(0);};
//创建最小和最大日期以限制图表x轴值
var minDateTime=new Date(new Date().setDate(new Date().getDate()-30));
var maxDateTime=新日期(new Date().setDate(new Date().getDate()+1));
//创建图表
BounceChart30Day=dc.compositeChart(“bounce-chart-30day”);
//创建两个折线图以放入合成图
var ppccLine=dc.折线图(BounceChart30天)
.组(反弹30天SPPCC)
var otherLine=dc.折线图(BounceChart30天)
.组(反弹30天以上)
//创建复合图表
反弹30天
.身高(50)
.宽度(450)
.margins({顶部:10,右侧:10,底部:5,左侧:35})
.维度(dateDim)
.过渡期(500)
.brushOn(错)
.弹性(真实)
.撰写([ppccLine,otherLine])
.x(d3.time.scale().domain([minDateTime,maxDateTime]))
.yAxis().ticks(3);
//创建值访问器以计算平均值
BounceChart30Day.valueAccessor(函数(p){
返回p.value.count>0?p.value.total/p.value.count:0;});
//创建添加、删除、初始减少功能
函数还原D(p,v){
++p、 计数;
p、 总+=v.反弹率;
返回p;
}
功能减速机移动(p,v){
--p、 计数;
p、 总计-=v.反弹率;
返回p;
}
函数还原初始(){
返回{count:0,total:0};
}
//渲染图
dc.renderAll();
您需要评估reduce函数中的数据。因此,请使reduce函数看起来像这样:
// create add, remove, initial reduce functions
function reduceAdd(p, v) {
if (v.PPCC === "PPCC") {
++p.PPCCcount;
p.PPCCtotal += v.bounceRate;
} else if(v.PPCC === "Other") {
++p.Othercount;
p.Othertotal += v.bounceRate;
}
return p;
}
function reduceRemove(p, v) {
if (v.PPCC === "PPCC") {
--p.PPCCcount;
p.PPCCtotal -= v.bounceRate;
} else if(v.PPCC === "Other") {
--p.Othercount;
p.Othertotal -= v.bounceRate;
}
return p;
}
function reduceInitial() {
return { PPCCcount: 0, PPCCtotal: 0, Othercount: 0, Othertotal: 0};
}
然后按正常方式创建您的组:
var bounce30DaysPPCC = dateDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
var bounce30DaysOther = dateDim.group().reduceSum(reduceAdd, reduceRemove, reduceInitial);
乍一看,其他一切都很正常。您只需更新
valueAccessor
函数,即可获得组上的新属性名。您需要在'if'语句中进行赋值。'var a=if(b){1}else{2}'导致'a'为'undefined'IIRC。如果您使用的是ReduceTio,请查看筛选选项:我的第一次尝试是在If
语句中进行的,但不确定如何具体引用组。在If
语句中使用reduce(添加、删除、初始)
。很抱歉,我删除了对reduceIO()的错误引用
我没有使用它/reductio()
你的reduce调用看起来不错。我相信你的问题是没有任何东西被分配给“bounce30DaysOther”。很抱歉,我忘记在我的代码中包含一些东西。刚刚添加了add、remove、initial reduce函数和dimension变量。Javascript问题:d.PPCC
是否可以在不指定函数(d)的情况下访问
在reduceAdd
和reduceRemove
功能中?不,复制/粘贴我的打字错误。我已将其更改为v
,它应该放在第一位。非常感谢。我将控制台.log(v.date,v.PPCC,v.bounceRate)
放在if(v.PPCC==“PPCC”)之前{
它成功地在控制台中打印了日期、PPCC、bounceRate值。但是我得到了未捕获的类型错误:当它到达if(v.PPCC==“PPCC”)时,无法读取未定义的属性“PPCC”{
如果它可以将v.PPCC
打印到控制台,为什么v.PPCC
在If
语句中突然没有定义?我看不出有任何原因。我认为对于这一点,您可能需要编写一个工作示例(在JSFIDLE或类似网站上)或者共享您正在运行的完整代码和数据