D3 Force Layout Tick Fn - nodes.attr()不是函数

时间:2016-01-19 00:28:58

标签: javascript d3.js force-layout

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

对我做错了什么的想法?

由于

1 个答案:

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