【问题标题】:Replace crossfilter data, restore dimensions and groups替换交叉过滤器数据,恢复维度和组
【发布时间】:2014-06-23 09:53:12
【问题描述】:

我正在使用dc.js 来呈现一个漂亮的数据集气泡图。底层 dc.js 是crossfilter

我想用来自服务器的新数据顺利刷新我的图表。 This issue on Github 明确表示可以通过以下方式做到这一点:

  1. 从交叉过滤器中删除所有数据
  2. 添加新数据
  3. 致电dc.redrawAll()

我已经完成了这项工作,但要删除所有数据,您首先必须清除所有过滤器(因为crossfilter.remove 只会删除与当前过滤器匹配的记录)。

我想“记住”我的数据之前是如何过滤的,这样我可以在替换所有数据后再次重建过滤器。我愿意深入了解crossfilter 代码的内容,但任何指针都会有所帮助。

另外:如果有人知道基于唯一键更新交叉过滤器数据的方法,那将是金粉!

【问题讨论】:

  • 你只是添加数据吗?然后我会说使用 crossfilter.add([data])。如果您还需要删除数据,我提供的内容不多,但您可能想看看这个问题,如果听起来方向正确,请发表评论:github.com/square/crossfilter/issues/109
  • @EthanJewitt 我没有添加 删除数据。我正在更新现有数据,每一行都是唯一键控的。或者add 是否可以根据密钥进行更新?
  • Gotcha - 那么您确实需要删除旧数据并添加新数据(据我所知,无法更新现有密钥)。该功能目前并不存在,因为您必须删除所有过滤器才能删除您的数据。就个人而言,我认为这是需要在 Crossfilter 中解决的问题,并且关于如何解决这个问题有一些讨论,但我认为没有人有时间解决它。

标签: javascript dc.js crossfilter


【解决方案1】:

这就是我最终一起破解的内容。它工作得非常好,尽管我确信它的效率非常低,因为所有维度都必须从头开始创建:

var _xfilter = crossfilter({x:1, y:2},{x:3, y:4}),
    _dimensions = [];

_dimensions.push(_xfilter.dimension(function(d) { return d.x; });

// Unfilters all the given dimensions, removes all data
// from xf and adds newData to xf.
var _xfilter_reset = function(xf, dimensions, newData) {
    var i;
    for (i = 0; i < dimensions.length; i++) {
        // Clear all filters from this dimension.
        // Necessary because xf.remove only removes records
        // matching the current filter.
        dimensions[i].filter(null);
    }
    xf.remove(); // Remove all data from the crossfilter
    xf.add(newData);
    return xf;
}

// Resets the global crossfilter object and reapplies all
// current dc.js chart filters.
var _refresh_data = function(data) {
    var i, j,
        chart, oldFilters,
        allCharts = dc.chartRegistry.list();

    _xfilter = _xfilter_reset(_xfilter, _dimensions, data);     

    // Reset all filters using dc.js
    for (i = 0; i < allCharts.length; i++) {
        chart = allCharts[i];
        oldFilters = chart.filters(); // Get current filters
        chart.filter(null); // Reset all filters on current chart
        for (j = 0; j < oldFilters.length; j++) {
            // Set all the oldFilters back onto the chart
            chart.filter(oldFilters[j]);
        }
    }
    dc.redrawAll();
}

【讨论】:

  • 我认为这可能是我们现在拥有的最佳效率 - 无论如何都必须重新计算所有组和减少。您可以尝试在没有数据的情况下重建过滤器,这样交叉过滤器就不会为每个.filter 调用打乱索引和减少。或者我们可以期待@Ethan 上面提到的功能。
【解决方案2】:

感谢@londonrob 的回答,所有数据现已从索引中删除。这是一种更实用的数据重置方法。

// reset the filter for a dimension
function resetDimensionFilter (dimension) {
  dimension.filter(null);
}

// reset filters for all given dimensions, 
// remove all data from index and
// return empty index
function resetData(ndx, dimensions) {
  // Clear all filters from dimensions, because `ndx.remove` 
  // only removes records matching the current filters.
  dimensions.forEach(resetDimensionFilter);

  // Remove all data from the cross filter
  ndx.remove();
}

【讨论】:

  • 哇!这真是个好消息。你能链接到解决这个问题的 github 修复/问题/公关吗?
  • 不确定你的意思。我只是稍微重写了你的代码来进行重置。
  • 哦。那么“感谢 londonrob 的回答,所有数据现在都已从索引中删除”指的是什么?我很困惑...
  • 您指出,所有维度的每个过滤器也必须重置。不仅是索引本身的那些。
  • 嘿 Rob,@line-o.. 我正在尝试在没有可重现示例的情况下实现这一点。我的版本似乎仅将原始过滤器重新应用到它创建的图形,而不是实际应该适应它的其他图形。见this jsfiddle。 3s 后页面刷新成功,有新数据。如果您选择例如Mr A 刷新前,相应的饼图并没有按原样过滤掉刷新后的2013 切片,除非您手动取消选择并重新选择过滤器(Mr A)。我是不是做错了什么?
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 2016-01-11
  • 1970-01-01
  • 2019-07-18
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
相关资源
最近更新 更多