我通过执行循环的ajax调用将记录加载到交叉筛选器对象中:
for (i=0;i<rangeToLoad.length;i++) {
url = "http://myserver/"+rangeToLoad[i]+"/myrecords.js"
$.ajax({
url: url,
dataType:"json",
success: function (jsondata) {
var records = jsondata.records;
var parseDate = d3.time.format("%Y-%m-%d").parse;
records.forEach(function(d) {
d.date = parseDate(d.date);
});
if (typeof myCrossfilter === "undefined") { //first call
myCrossfilter = crossfilter(records);
} else {
myCrossfilter.add(records);
}
initData();
showData();
}
});
}
我的initData()
函数基本上是定义交叉过滤器对象的维度和组的地方。
dims.date = myCrossfilter.dimension(function(d) {return(+d.date);});
groups.date={};
dims.date2 = myCrossfilter.dimension(function(d) {return(+d.date);});
groups.date2={};
dims.instrumenttype = myCrossfilter.dimension(function(d) {return(d.product);});
groups.instrumenttype = {};
groups.date.pnlSum = dims.date.group().reduceSum(function(d) {return(d.pnl);});
groups.date2.cumPnlSum = dims.date2.group().reduceSum(function(d) {return(d.cumpnl);});
groups.instrumenttype.pnlSum = dims.instrumenttype.group().reduceSum(function(d) {return(d.pnl);});
我的猜测是,每次创建一个新维度,而不是更新每个ajax调用的现有维度。
我怎样才能防止这种情况发生呢?
发布于 2014-03-19 00:54:25
诀窍是,只在ajax调用的第一次传递时才创建维度,方法是检查是否定义了交叉筛选器。我还取消了ajax调用的异步属性,因为在我的示例中它不是一个大问题(数据加载非常快)。它防止了找出哪个呼叫是先做的令人头痛的任务。
for (i=0;i<rangeToLoad.length;i++) {
url = "http://myserver/"+rangeToLoad[i]+"/myrecords.js"
$.ajax({
url: url,
dataType:"json",
async:false,
success: function (jsondata) {
if (typeof myCrossfilter === "undefined") { //first call
myCrossfilter = crossfilter(records);
initData()
} else {
myCrossfilter.add(records);
}
showData();
}
});
}
发布于 2014-03-18 08:18:51
交叉过滤器只支持最大32维。您可以通过使用dimension.dispose函数来管理维度的数量,这样既可以在完成维度时(在showData
之后),也可以在新维度出现之前(在initData
之前)。
正如接受的答案所说明的那样,Crossfilter还支持添加新行。在内部,Crossfilter管理一组侦听器,在添加或删除数据时通知内部维度和分组结构。因此,正确的做法是确保只创建一次维度,然后在随后的传递中根据需要更改数据。
https://stackoverflow.com/questions/22401085
复制相似问题