DC.js 带有两个折线图的复合图均表示按日期计算的平均值
DC.js compositeChart with two lineChart both representing average value by date
我想创建 DC.js 图表,其中有两条线,每条线代表日期的平均值。
我相信这样做的方法是使用 DC.js compositeChart
并创建两个折线图放入其中,然后使用 reducio()
group.reduce(add, remove, initial)
以获得平均金额。
我的问题是条件逻辑去哪里了? How/where 我是否有条件地使用这个:
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>
您需要在 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
函数即可在群组中获取新的 属性 名称。
我想创建 DC.js 图表,其中有两条线,每条线代表日期的平均值。
我相信这样做的方法是使用 DC.js compositeChart
并创建两个折线图放入其中,然后使用 reducio()
group.reduce(add, remove, initial)
以获得平均金额。
我的问题是条件逻辑去哪里了? How/where 我是否有条件地使用这个:
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>
您需要在 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
函数即可在群组中获取新的 属性 名称。