带有dc.js的crossfilter.js在回调组更改时更新图表 [英] crossfilter.js with dc.js update charts on callback group change

查看:117
本文介绍了带有dc.js的crossfilter.js在回调组更改时更新图表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个工厂来创建dc.js图表​​,该图表使用绑定到$ scope的交叉过滤器函数. Plnkr示例

I have a factory for creating dc.js charts which uses crossfilters functions bound to $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获取所有图表属性,因此标记就像这样

chart factory takes all chart properties through the DOM via angular directive so the tags are like so

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

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

this approach works fine for filtering, initial data loading, binding and chart rendering, etc....however this is one exception. If I have something like a button click event that fires a new data request, and then I use the above as the callback it takes and processes the data fine, but doesn't update the chart. Even if I include dc.redrawAll() or renderAll(), etc.

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

I have tried embedding redraw(), redrawAll(), verified the data is coming back correctly, destroying the tag entirely and re-creating and appending to DOM,etc. My assumption is there is an issue with my usage of this factory-style implementation of creating the DC/D3 charts, but I would assume that if I updated the group and/or dimenstion in the scope it should still work? It seems as though the chart objects don't pick up the changes to the dim/groups? I can verify that the cf group values referenced by the $scope.etc have changed by using the following in both the initial call and second call:

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等也不会影响它.

UPDATE: added plnkr, and attempt to better explain= so with the example I have sort of a "traditional" way to build the dc chart versus the service based approach I am trying to achieve using a directive and element. Everything works except what I have attempted to show in the plnkr...when I request new data (ajax) the first updates fine, with the directive based approach nothing seems to work. I have tried numerous ways but essentially updating the $scope dim/group should be working right? I believe it is two way binding therefore these "two scopes" should share a reference?? But even if I use scope.$parent.my.dimension, etc it doesn't affect it.

推荐答案

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

Your chart is still bound to your old crossfilter, dimension, and groups. Generally, when you load new data or replace data, don't throw away your crossfilter, dimension, or groups. Use the crossfilter.remove and crossfilter.add methods to add or remove data.

以下是修改示例的方法:

Here's how to modify your example:

在创建控制器时,先创建Cross滤镜,尺寸和组,然后在将来不再创建或销毁它们:

Create your Crossfilter, dimensions, and groups up front when you create your controller, then don't create or destroy any more of them in the future:

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; })

然后将您的更新功能更改为仅在Crossfilter中切换出数据:

Then change your update function to just switch out the data in the Crossfilter:

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

如果您要在执行此操作时维护dc.js过滤器,则此问题/答案将说明如何:

If you want to maintain your dc.js filters when you do this, this question/answer explains how: Updating dc.js data and reapplying original filters

这是工作正常的柱塞: http://plnkr.co/edit/UbfKsuhg9vH678MR6fQT?p =预览

Here is a working Plunker: http://plnkr.co/edit/UbfKsuhg9vH678MR6fQT?p=preview

这篇关于带有dc.js的crossfilter.js在回调组更改时更新图表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆