由于我已经在其他一些项目中遇到了一些内存泄漏问题,因此我记录了如何释放d3.js事件侦听器内存。
我发现分配空值正在释放内存source 1 source 2:
svg.selectAll(".node").on('mouseover',null);
因此,在将此解决方案应用于我的代码之前,我做了第一次测试,看看有多少内存泄漏。
我第一次加载图表并进行垃圾收集。 然后几次:打开一个新的简单视图,回到图表并进行垃圾收集。
监听器和节点已经回退到初始值(754和1901)。但我还没有应用解决方案!
这里发生了什么,D3或AngularJS已经为我做了清理工作?我还应该在$ destroy事件中应用我的解决方案吗?
指令代码:
'use strict';
angular.module("appDirectives", []).directive("myGraph", function() {
return {
restrict: 'E',
scope: {
data: '='
},
link: function (scope, element, attrs) {
//values from controller
var links = scope.data.links;
var nodes = scope.data.nodes;
//force graph size, affect the gravitational center and initial random position
var width = 600,
height = 600;
//force graph initialisation
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(60)
.charge(-400)
.gravity(0.4);
//append svg element and width height
var svg = d3.select(element[0]).append("svg")
.attr("viewBox", "0 0 " + width + " " + height )
.attr("preserveAspectRatio", "xMinYMin");
//add links
var link = svg.selectAll(".link")
.data(force.links())
.enter().append("line")
.attr("class", "link")
.on("mouseover", function(d) {
scope.data.info = d.source.name+" | "+d.target.name;
scope.$apply();
});
//add nodes
var node = svg.selectAll(".node")
.data(force.nodes())
.enter().append("g")
.attr("class", function(d) { return "node "+d.type+" "+d.status; })
.on("mouseover", function(d) {
scope.data.info = d.type+" "+d.name+" <br/> "+d.status;
scope.$apply();
})
.call(force.drag);
//display node name on mouseover
node.append("title")
.text(function(d) { return d.name; });
// draw typeA as circle
var gateway = svg.selectAll(".typeA");
gateway.append("circle")
.attr("r", 6);
//draw typeB as square
var switche = svg.selectAll(".typeB");
switche.append("path").attr("d", d3.svg.symbol()
.type(function(d) { return 'square'; })
.size(100));
//draw typeC as triangle
var ap = svg.selectAll(".typeC");
ap.append("path").attr("d", d3.svg.symbol()
.type(function(d) { return 'triangle-up'; }));
function tick() {
link
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
//use timeout to allow the rest of the page to load first
setTimeout(function() {
// pre render the graph
force.start();
for (var i = 100 ; i > 0; --i) force.tick();
force.stop();
//render the graph
force
.on("tick", tick)
.start();
}, 10);
}
};
});