我制作了一个angularjs指令,用于绘制d3力导向图。此图表会定期更新,包含新节点和链接。
最近,我注意到当图表更新时,它会重新绘制2倍,这需要花费很多时间。部分原因是因为我必须首先更新节点数组,然后更新边数组,并且每次触发重绘。 BOTH更新后我想看一下。
我已经看到很多关于如何处理OR
关系监视的问题,但我特别希望在BOTH节点AND
链接更新后重绘。< /强>
这是我目前的指令:
graphs.directive('myGraph', [function () {
function renderGraph(scope, elem) {
drawGraph(scope.data, scope.data.params || {}, elem);
scope.$watchCollection('data', function (newData) {
drawGraph(newData, scope.data.params || {}, elem);
});
}
function drawGraph(data, params, elem) {
const rawSvg = elem.find(".svg")[0];
forceDirectedGraph.create(data.nodes, data.links, data.nodeTypes, rawSvg, params);
}
return {
scope: {
data: '='
},
templateUrl: 'graph.html',
link: renderGraph
}
}]);
以下是我更新图表的方法:
//initialization code:
$scope.graph = { links:[], nodes:[], params:{ /*stuff*/} }
//graph update code:
$http.get(url).then( function(response) {
links = [];
nodes = [];
//process and format links and nodes for d3 from request
$scope.graph.links = links;
$scope.graph.nodes = nodes;
});
答案 0 :(得分:2)
我想到了几个选项,其中没有一个很好 - 尽管我倾向于#1。不确定它们对于您的特定需求有多么理想:
选项1
向名为data
的{{1}}对象添加新属性。在$ http.get成功回调的开头将其设置为false。数据更新完成后将其设置为true。在$ watch中,只有在设置时重绘:
shouldRedraw
选项2
更新您的//initialization code:
$scope.graph = { links:[], nodes:[], shouldRedraw:true, params:{ /*stuff*/} }
//graph update code:
$http.get(url).then( function(response) {
$scope.graph.shouldRedraw = false;
links = [];
nodes = [];
//process and format links and nodes for d3 from request
$scope.graph.links = links;
$scope.graph.nodes = nodes;
$scope.graph.shouldRedraw = true;
});
// the watch
scope.$watchCollection('data', function (newData) {
if (newData.shouldRedraw === true) {
drawGraph(newData, scope.data.params || {}, elem);
}
});
指令,将myGraph
,links
和nodes
值作为单独的范围输入接受。然后$观看params
和links
变量。标记nodes
默认为false。首先更新的是isStagedForRedraw
或links
,将触发要设置的标志,第二个将触发重绘并且标记将被取消:
nodes
选项3
让指令跟踪var isStagedForRedraw = false;
scope.$watchGroup(['links', 'nodes'], function (newValues, oldValues, scope) {
if (isStagedForRedraw) {
drawGraph({links:scope.links, nodes:scope.nodes}, scope.data.params || {}, elem);
isStagedForRedraw = false;
} else {
isStagedForRedraw = true;
}
});
对象,而不是跟踪data
和data.links
值的JSONified值。在观看时,JSONify data.nodes
和data.links
的新值。如果两者都更改,则重绘并更新跟踪的JSONified值。如果只有一个改变了,就什么都不做。