我开始玩D3 Force Layout
了,我不得不添加元素并重新开始计算。
继续获取:Uncaught TypeError: network.nodes.attr is not a function
这是我的代码:
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)
这里有小提琴:https://jsfiddle.net/teone/wo2gv3ge/3/
对我做错了什么的想法?
由于
答案 0 :(得分:2)
正如Lars在评论中提到的,attr
方法在d3选择中可用,而在JavaScript数组中不可用。
所以你必须更换你的tick函数,如下所示。
var tickFn = () => {
svg.selectAll('.node') //Where node is the class name of node elements.
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; });
svg.selectAll('.link') //Where link is the class name of link elements.
.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; });
};
注意:好像您正在使用rect
来重新体验节点。如果节点是rect
元素,则应更新节点的x
和y
属性,而不是cx
和cy
属性。 (如果节点是圆形元素,则使用cx
,cy
属性