【问题标题】:d3js (+crossfilter/dc) boxplot performanced3js (+crossfilter/dc) 箱线图性能
【发布时间】:2014-04-14 09:58:10
【问题描述】:

我正在尝试使用 D3、Crossfilter 和 DC 的组合生成交互式箱线图,主要使用这个例子:https://github.com/dc-js/dc.js/blob/master/web/examples/box-plot.html

我的数据看起来更像这样:

id      date        met1
6368    10/24/2013  0.84
6369    10/24/2013  0.67
6374    10/24/2013  0.96
6375    10/24/2013  0.97

大约有 50 万个数据点,这对于除箱线图之外的所有其他内容都适用。代码工作正常,箱线图也很好,但是当我在其他地方更改过滤器时,箱线图需要永远更新:

var met1Dim = data.dimension(function(d) {return "metric 01";});
var met1Values = met1Dim.group().reduce(
            function(p, v) {
                p.push(v.met1);
                return p;
            },
            function(p,v) {
                p.splice(p.indexOf(v.met1), 1);
                return p;
            },
            function() {
                return [];
            }

当我将整数作为数据传递(只需将 v.met1 替换为 parseInt(v.met1 * 100))时,性能会大大提高(但仍不完全理想),但这有点半途而废,我会喜欢在适当的范围内显示数据,而不是将所有内容强制转换为整数。最显着的减速发生在我删除数据集时,我认为是 slice(indexOf()) 减慢了一切(使用浮点数时)。我能做些什么来加快这个操作吗?我在想一个使用 id 数据的关联数组可能是一个键,但我不确定如何将关联数组传递给 reduce() 函数。

谢谢。

【问题讨论】:

    标签: javascript d3.js crossfilter dc.js


    【解决方案1】:

    使用地图查找而不是 indexOf 肯定会有所帮助,但不幸的是,当您真正想要的只是使用 met1 进行基本分组时,您需要跳过这些障碍。值显示在顶层,因为这是 dc.js 所期望的。

    如果 dc.js 允许您指定一个访问器函数,该函数允许您定义您希望如何在需要的点从绑定对象中提取 met1 值,那就太好了。 d3 在任何地方都使用这种模式,而且非常方便(也可以让您免于这种性能密集型的杂耍)。

    除非对 dc.js 进行这种更改,否则我认为您对地图查找的想法可能是最好的选择。您可以使用 reduce 函数的闭包范围来存储它。由于您的记录具有唯一 ID,因此您可以只使用单个地图而无需担心冲突:

    var indexMap = {};
    var met1Values = met1Dim.group().reduce(
        function(p, v) {
            indexMap[v.id] = p.length;  // length before push is index of pushed element
            p.push(v.met1);
            return p;
        },
        function(p,v) {
            p.splice(indexMap[v.id], 1);
            return p;
        },
        function() {
            return [];
        }
    );
    

    【讨论】:

    • 感谢您的帮助!您的修改使脚本运行得更快。我实际上是在尝试将映射合并到 reduce 函数中(如 reduceAdd 和 reduceRemove 函数中的 p[v.id] = v.dqc),但无法让它工作。你的方法比这更直观、更实用。
    • 更新:我认为这个解决方案有效,但显然它没有(没有注意到大型数据集)。 boxplot 函数按值对 p 数组进行排序,因此 indexMap 映射变得不正确。此外,当使用 p.slice 删除时,因为 indexMap 映射不会随着每次删除而更新,它们也会变得不正确。我将不得不进一步挖掘解决方案。不管怎样,谢谢。
    • 好吧,您将无法在多个归约中重用同一个 indexMap。每次调用 group.reduce 时,都应确保 indexMap 为空。换句话说,indexMap 仅用于单个 group.reduce 调用的持续时间。这对您描述的问题有帮助吗?
    • 我不确定如果每次 group.reduce 调用都清空 indexMap 会如何工作。如果它只是清空,如果我连续进行多次归约,indexMap 将如何填充?
    • 实际上,因为您使用的是 dc.js,所以您可能正在有状态地使用组,所以您是对的,这不起作用。 (我的正常用法是处理组并重新创建它们,因此我倾向于在每次通过时都使用 reduce 重新开始)。考虑到这一点,令我感到奇怪的是 dc.js 正在为箱线图本身进行统计计算。与其输入大量数据,是否可以自己计算统计数据并仅输入最小值、最大值、中值等?我对 dc.js 不熟悉,所以我不知道这是否可能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    • 2016-02-25
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多