在d3中将元素添加到数组中

时间:2014-06-10 17:29:57

标签: javascript d3.js force-layout

我正在创建一个网页,该网页将使用来自JSON文件的数据制作d3强制布局图,当按下按钮时,将提示用户输入名称,并使用提供的信息创建新节点名称。页面加载成功,当按下按钮时,警报会询问名称,但是输入名称时会出现“未捕获的类型错误:未定义不是函数”并且未添加新节点的错误。

我该怎么做才能解决此错误?使用Chrome我知道错误发生在我尝试追加newNode的行中。这是我的代码:

<button onclick="addNode()">Click to add Node</button>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

function addNode() {
  var nodeName = prompt("Name of new node:");
  var newGroup = Math.floor(Math.random() * 6);
  if (nodeName != null) {
    var newNode = {"node":{"name":nodeName,"group":newGroup}};
    force.nodes.append(newNode);
    force.start();
  }
}

var width = 960,
    height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

d3.json("user_interactions(1).json", function(error, graph) {
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  var link = svg.selectAll(".link")
      .data(graph.links)
      .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

  var node = svg.selectAll(".node")
      .data(graph.nodes)
      .enter().append("circle")
      .attr("class", "node")
      .attr("r", 5)
      .style("fill", function(d) { return color(d.group); })
      .call(force.drag);

  node.append("title")
      .text(function(d) { return d.name; });

  force.on("tick", function() {
    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("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; });
  });
});

</script>

1 个答案:

答案 0 :(得分:1)

force.nodes是一个返回节点数组的函数。它不是财产。所以force.nodes.append没有任何意义。您可能希望将新节点添加到数据

force.nodes(force.nodes().push(newNode));
但是,我不确定D3会优雅地动态更改节点数组。

在任何情况下,您都必须为新节点添加SVG元素,并以与您设置初始属性的方式类似的方式指定其属性(r,{{1}等等。)