I'm currently experimenting with the D3 Force Layout, and I've hit a roadblock when it comes to adding elements and restarting the calculation.
Every time I try, I keep encountering this error:
Uncaught TypeError: network.nodes.attr is not a function
Below is the code snippet causing the issue:
var topoConfig = {
width: 600,
height: 600
};
var network = {
nodes: [],
links: []
}
var tickFn = () => {
network.nodes
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
network.links
.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; });
};
var svg = d3.select("body")
.append('svg')
.style('width', topoConfig.width + 'px')
.style('height', topoConfig.height + 'px');
var force = d3.layout.force()
.nodes(network.nodes)
.links(network.links)
.charge(-400)
.linkDistance(80)
.size([topoConfig.width, topoConfig.height])
.on('tick', tickFn);
function reload(){
var nodes = svg.selectAll('.node')
.data(network.nodes, d => d.id);
nodes.enter()
.append('rect')
.attr({
width: 10,
height: 10,
x: function(d){return d.x},
y: function(d){return d.y}
});
force.start();
}
function addNode(node){
network.nodes.push(node);
reload();
}
window.setTimeout(function(){
addNode({
"id": "fabric:a",
"label": "Fabric Switch",
"type": "fabric-switch",
"x": 100,
"y": 100
});
}, 500)
If you want to check out the live example on JsFiddle, here's the link: https://jsfiddle.net/teone/wo2gv3ge/3/
Any suggestions on what could be going wrong in my implementation?
Thank you!