Javascript DC.js compositeChart,带有两个折线图,均表示日期的平均值

Javascript 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”的

我想创建一个DC.js图表,其中两行分别表示日期的平均值

我相信这样做的方法是使用DC.js
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或类似网站上)或者共享您正在运行的完整代码和数据