我有一个用于创建 dc.js 图表的工厂,它使用绑定到 $scope 的 crossfilters 函数。Plnkr 示例
$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,并试图更好地解释 = 所以在这个例子中,我有一种“传统”的方式来构建直流图表,而不是我试图使用指令和元素来实现的基于服务的方法。一切正常,除了我试图在 plnkr 中显示的内容……当我请求新数据(ajax)时,第一次更新很好,使用基于指令的方法似乎没有任何效果。我尝试了很多方法,但基本上更新 $scope dim/group 应该可以正常工作吗?我相信这是双向绑定,因此这两个“两个范围”应该共享一个引用?但即使我使用 scope.$parent.my.dimension 等,它也不会影响它。
您的图表仍然绑定到旧的交叉筛选器、维度和组。通常,当您加载新数据或替换数据时,不要丢弃您的交叉过滤器、维度或组。使用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 过滤器,此问题/答案解释了如何:更新 dc.js 数据并重新应用原始过滤器
这是一个工作的Plunker:http ://plnkr.co/edit/UbfKsuhg9vH678MR6fQT?p=preview
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句