【问题标题】:crossfilter.js with dc.js update charts on callback group change带有 dc.js 的 crossfilter.js 更新回调组更改图表
【发布时间】:2017-04-19 11:38:56
【问题描述】:

我有一个创建 dc.js 图表的工厂,它使用绑定到 $scope 的交叉过滤器函数。 Plnkr Example

$scope.updateMyPie = function(data) {
     var cf = crossfilter(data)
     $scope.mypie.dimension = cf.dimension(function(d) { return d.key })
     $scope.mypie.group = 
     $scope.mypie.dimension.group().reduceSum(function(d){ return d.value });
}

图表工厂通过 Angular 指令通过 DOM 获取所有图表属性,因此标签就像这样

<mypie id="mypie" chart-dimesion="mypie.dimension" chart-group="mypie.group"...etc

这种方法适用于过滤、初始数据加载、绑定和图表渲染等......但是这是一个例外。如果我有类似触发新数据请求的按钮单击事件,然后我使用上面的回调作为它需要并很好地处理数据,但不更新图表。即使我包含 dc.redrawAll() 或 renderAll() 等。

我尝试嵌入 redraw()、redrawAll()、验证数据是否正确返回、完全销毁标签并重新创建和附加到 DOM 等。我的假设是我使用这种创建 DC/D3 图表的工厂风格实现存在问题,但我假设如果我更新了范围内的组和/或维度,它应该仍然有效吗?似乎图表对象没有接收到暗淡/组的更改?我可以通过在初始调用和第二次调用中使用以下内容来验证 $scope.etc 引用的 cf 组值是否已更改:

var print_filter = function(filter) {
    var f = eval(filter);
    if (typeof (f.top) != "undefined") { 
        f = f.top(Infinity);
    }
    if (typeof (f.dimension) != "undefined") { 
        f = f.dimension(function (d) { 
            return ""; 
        }).top(Infinity);
    }

    console.log(filter + "(" + f.length + ") = " + JSON.stringify(f).replace("[", "[\n\t").replace(/}\,/g, "},\n\t").replace("]", "\n]"));
};

更新:添加了 plnkr,并尝试更好地解释 = 所以在示例中,我有一种“传统”的方式来构建 dc 图表,而不是我试图使用指令和元素实现的基于服务的方法。一切正常,除了我试图在 plnkr 中显示的内容......当我请求新数据(ajax)时,第一次更新很好,基于指令的方法似乎没有任何效果。我尝试了很多方法,但基本上更新 $scope dim/group 应该可以正常工作吗?我相信这是双向绑定,因此这些“两个范围”应该共享一个参考?但即使我使用 scope.$parent.my.dimension 等也不会影响它。

【问题讨论】:

    标签: javascript angular d3.js dc.js


    【解决方案1】:

    您的图表仍绑定到旧的交叉过滤器、维度和组。通常,当您加载新数据或替换数据时,不要丢弃您的交叉过滤器、维度或组。使用crossfilter.removecrossfilter.add 方法添加或删除数据。

    以下是修改示例的方法:

    在创建控制器时预先创建交叉过滤器、维度和组,以后不要再创建或销毁它们:

    myapp.controller('mycontroller', ['$scope', 'dataCaller', function($scope, dataCaller){
          $scope.pageTitle = "Updating DC.js and Crossfilter";
    
          $scope.currentData1 = "data1.json";
          $scope.currentData2 = "data1.json";
    
          $scope.my = {};
          $scope.my.cf = crossfilter();
          $scope.my.dimension = $scope.my.cf.dimension(function(d){ return d.key; })
          $scope.my.group = $scope.my.dimension.group().reduceSum(function(d){ return d.value; })
    

    然后更改您的更新功能以仅切换交叉过滤器中的数据:

     $scope.factoryBuildPieExample = function(data) {
        $scope.my.cf.remove()
        $scope.my.cf.add(data.response.data)
        dc.redrawAll();
      }
    

    如果您想在执行此操作时维护您的 dc.js 过滤器,此问题/答案解释了如何:Updating dc.js data and reapplying original filters

    这是一个正常工作的 Plunker:http://plnkr.co/edit/UbfKsuhg9vH678MR6fQT?p=preview

    【讨论】:

    • 太棒了!再次感谢伊桑。这实际上是我昨天问的关于散点图的过滤器问题的基础。感谢帮助的人!
    • Ethan,我注意到在更新函数中实现这个之后,我传入数据,对其进行安慰,一切都在那里,然后是 cf.remove,然后是 cf.add,我只得到了添加响应数组的第一个对象?有什么想法吗?
    • 我应该提一下,我是从 renderlet 点击图表本身调用它......所以图表上的选择被保留(理想情况下),并且回调包含用于模拟过滤的参数。跨度>
    • 您用add 描述的行为听起来不对,但我不明白您在评论中围绕过滤器等做了什么。我认为您必须整理一个示例并为此提出一个新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-27
    • 2015-10-18
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多