我有一个工厂用于创建dc.js图表,它使用绑定到$ scope的crossfilters函数。 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 });
}
图表工厂通过角度指令通过DOM获取所有图表属性,因此标签就像这样
<mypie id="mypie" chart-dimesion="mypie.dimension" chart-group="mypie.group"...etc
这种方法适用于过滤,初始数据加载,绑定和图表渲染等等。但这是一个例外。如果我有类似按钮点击事件触发新数据请求,然后我使用上面作为回调它采取并处理数据罚款,但不更新图表。即使我包含dc.redrawAll()或renderAll()等等。
我尝试嵌入redraw(),redrawAll(),验证数据是否正确返回,完全销毁标记并重新创建并附加到DOM等。我的假设是我使用这种工厂式创建DC / D3图表的实现存在问题,但我认为如果我更新了范围内的组和/或尺寸,它应该仍然有用吗?似乎图表对象没有获取对dim / groups的更改?我可以通过在初始调用和第二次调用中使用以下内容来验证$ 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应该正常工作?我认为它是双向绑定因此这些“两个范围”应该共享参考?但即使我使用范围。$ parent.my.dimension等也不会影响它。
答案 0 :(得分:1)
您的图表仍然绑定到旧的交叉过滤器,维度和组。通常,在加载新数据或替换数据时,请不要丢弃交叉过滤器,维度或组。使用crossfilter.remove
和crossfilter.add
方法添加或删除数据。
以下是修改示例的方法:
在创建控制器时预先创建Crossfilter,尺寸和组,然后在将来不再创建或销毁它们:
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中的数据:
$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