我拥有包含多个数字列的D3数据集,我已成功使用它们来呈现DC.js图表。图表目前固定为仅使用数字列之一。
但是,我希望能够在数字列之间动态切换,以将它们交换为DC.js图表中的值。
我计划通过使用页面顶部的一组html链接和一个onclick
事件来实现此目的,以创建变量来更改D3数据集中选择的列。一切正常。
但是,我坚持如何刷新DC.js图表以使用更新的数据集。
我看到了其他类似的问题here和here,但它们并没有帮助我。
这是我的代码:
bucket.getObject({
Bucket: 's3-google-analytics',
Key: 'merged.csv'
},
function awsDataFile(error, data) {
if (error) {
return console.log(error);
}
mergedcsv = d3.csv.parse(data.Body.toString());
var parseDate = d3.time.format("%Y%m%d").parse;
var counter = 0;
var varMetric = 'sessions';
// Note, i can successfully manually change varMetric variable
//to change numeric column is used in chart.
mergedcsv.forEach(function(d) {
d.date = parseDate(d.date);
d.dateString = formatDateYYYYMMDD(d.date);
if (varMetric == 'sessions') {
d.metric = +d.sessions;
} else if (varMetric == 'users') {
d.metric = +d.users;
} else if (varMetric == 'bounceRate') {
d.metric = +d.bounceRate;
} else if (varMetric == 'newUsers') {
d.metric = +d.newUsers;
} else if (varMetric == 'sessionDuration') {
d.metric = +d.sessionDuration;
} else if (varMetric == 'sessionsPerUser') {
d.metric = +d.sessionsPerUser;
} else if (varMetric == 'twitterSessions') {
d.metric = +d.twitterSessions;
}
countLoop = counter++;
});
var ndx = crossfilter(mergedcsv);
// where to put this?
$('#metric a').click(function(e) {
var varMetric = $(e.target).text();
console.log(varMetric);
ndx.remove();
// which to use .. add or crossfilter?
//ndx.add(mergedcsv);
//ndx = crossfilter(mergedcsv);
// which to use .. redrawAll or renderAll?
//dc.redrawAll();
//dc.renderAll();
});
var yyyymmDim = ndx.dimension(function(d) { return d["yyyymm"]; });
var PPCCByYYYYMM = yyyymmDim.group().reduceSum( function(d) { return +d.metric; });
BarChartAlltimeByMonth = dc.barChart("#barchart-alltime-by-month");
BarChartAlltimeByMonth
.height(100)
.width(1000)
.margins({top: 0, right: 10, bottom: 50, left: 35})
.dimension(yyyymmDim)
.group(PPCCByYYYYMM)
dc.renderAll();
//on click put here but doesn't work
$('#metric a').click(function(e) {
var varMetric = $(e.target).text();
console.log('onclick ' + varMetric);
ndx.remove();
ndx.add(mergedcsv);
//dc.redrawAll();
dc.renderAll();
});
});
我将onclick
处理程序放在脚本的底部。
在上述其他SO问题中,似乎可以做到这一点:1)删除旧数据,2)添加新数据,3)重绘所有图表。
ndx.remove()
确实删除了数据,但是ndx.add(mergedcsv)
没有添加数据。
dc.redrawAll()
不会执行任何操作,但是尽管dc.renderAll()
确实会导致图表再次呈现,但是数据没有变化。
这可能是DC.js和一般的Javascript问题,因为我都不熟练。
答案 0 :(得分:1)
是的,是的,这是编程和JavaScript问题,与dc.js或d3.js无关。
首先,我们研究了将回调(如单击处理程序)放置在何处,该回调程序可处理由另一个回调(如接收数据处理程序)设置的可视化效果和/或数据。
问题在于数据和图表可能在顶级范围内不可用。
最简单的解决方案是将点击处理程序放入数据处理程序中,以便可以访问图表和数据。
您要处理的下一个问题是在哪里放置数据转换,以便在绘制图表之前和单击之后都将调用它。
当前,您的点击处理程序不执行任何操作,因为它会将数据替换为...相同的数据。 (长号悲伤的声音)
有很多方法可以解决此问题,但是更改当前代码的最简单方法是将数据转换移动到可重用的函数
:function transform_data(data, varMetric) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.dateString = formatDateYYYYMMDD(d.date);
if (varMetric == 'sessions') {
d.metric = +d.sessions;
} else if (varMetric == 'users') {
d.metric = +d.users;
} else if (varMetric == 'bounceRate') {
d.metric = +d.bounceRate;
} else if (varMetric == 'newUsers') {
d.metric = +d.newUsers;
} else if (varMetric == 'sessionDuration') {
d.metric = +d.sessionDuration;
} else if (varMetric == 'sessionsPerUser') {
d.metric = +d.sessionsPerUser;
} else if (varMetric == 'twitterSessions') {
d.metric = +d.twitterSessions;
}
countLoop = counter++;
});
}
现在这可以在绘制图表之前发生:
function awsDataFile(error, data) {
if (error) {
return console.log(error);
}
mergedcsv = d3.csv.parse(data.Body.toString());
var parseDate = d3.time.format("%Y%m%d").parse;
var counter = 0;
var varMetric = 'sessions';
transform_data(mergedcsv, varMetric);
var ndx = crossfilter(mergedcsv);
// ...
我们可以单击一下来重复数据转换:
$('#metric a').click(function(e) {
var varMetric = $(e.target).text();
console.log('onclick ' + varMetric);
transform_data(mergedcsv, varMetric);
ndx.remove();
ndx.add(mergedcsv);
dc.redrawAll();
});
注意:对于dc.js,您肯定只想第一次渲染,然后在数据更改时重新绘制。渲染从头开始,而重绘将执行(通常)漂亮的动画过渡。