D3 强制布局 Tick Fn - nodes.attr() 不是一个函数

D3 Force Layout Tick Fn - nodes.attr() is not a function

本文关键字:函数 一个 attr 布局 Tick Fn nodes D3      更新时间:2023-09-26

我开始玩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/

知道我做错了什么吗?

谢谢

正如Lars在评论中提到的,attr方法在d3选择中可用,而不是在JavaScript数组中可用。

因此,您必须替换如下所示的即时报价函数。

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元素,则应更新节点的xy属性,而不是cxcy属性。(如果节点是圆元素,请使用cxcy属性)