多个数据源导致“无效的数组宽度!”错误

时间:2014-03-14 09:35:46

标签: javascript jquery ajax crossfilter dc.js

我通过循环ajax调用将记录加载到crossfilter对象中:

    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()函数基本上是我的crossfilter对象的维度和组的定义。

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调用的现有维度,而是每次都创建一个新维度。

如何防止这种情况发生?

2 个答案:

答案 0 :(得分:2)

Crossfilter最多只支持32个尺寸。您可以使用dimension.dispose函数管理维度数量,以便在完成维度(showData之后)或新维度进入之前({{1之前)消除维度}})。

如接受的答案所示,Crossfilter还支持添加新行。在内部,Crossfilter管理了一组侦听器,在添加或删除数据时通知内部维度和分组结构。因此,正确的做法是确保仅创建一次维度,然后在后续过程中根据需要更改数据。

答案 1 :(得分:0)

诀窍是通过检查是否定义了crossfilter,仅在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();
    }
});

}