D3 v4缺少节点

时间:2017-02-15 13:07:55

标签: d3.js

我是D3库(v4)的新手,我需要构建几个强制直接布局。 重用[https://bl.ocks.org/mbostock/4062045][1]中的代码我已经构建了一个带有几个矩形节点和内部文本的测试。实际上有13个节点有一些链接。然而,布局仅显示12个节点(来自"节点1和#34;到"节点12和#34;)尽管节点0和#34;的链接也是如此。绘制。看看DOM只显示12和12,而console.log()正确列出13个节点对象和文本标签。请允许有人在下面的代码中解释我的错误。

   var graph = { "nodes":
   [{"id":"Node 0","group":2},{"id":"Node 1","group":2},
   {"id":"Node 2","group":2},{"id":"Node 3","group":2},
   {"id":"Node 4","group":2},{"id":"Node 5","group":2},
   {"id":"Node 6","group":2},{"id":"Node 7","group":2},
   {"id":"Node 8","group":2},{"id":"Node 9","group":2},
   {"id":"Node 10","group":2},{"id":"Node 11","group":2},
   {"id":"Node 12","group":4}],
   "links":
   [{"source":"Node 0","target":"Node 1","value":"5"},
   {"source":"Node 1","target":"Node 5","value":"5"},
   {"source":"Node 2","target":"Node 1","value":"5"},
   {"source":"Node 3","target":"Node 2","value":"5"},
   {"source":"Node 3","target":"Node 1","value":"5"},
   {"source":"Node 3","target":"Node 5","value":"5"},
   {"source":"Node 4","target":"Node 3","value":"5"},
   {"source":"Node 4","target":"Node 8","value":"5"},
   {"source":"Node 5","target":"Node 8","value":"5"},
   {"source":"Node 6","target":"Node 9","value":"5"},
   {"source":"Node 7","target":"Node 3","value":"5"},
   {"source":"Node 8","target":"Node 10","value":"5"},
   {"source":"Node 9","target":"Node 10","value":"5"},
   {"source":"Node 9","target":"Node 7","value":"5"},
   {"source":"Node 10","target":"Node 12","value":"20"},
   {"source":"Node 11","target":"Node 7","value":"5"}]
   };

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

   var color = d3.scaleOrdinal(d3.schemeCategory20).domain(d3.range(1,20));;

   var simulation = d3.forceSimulation()
       .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(100))
       .force("charge", d3.forceManyBody())
       .force("center", d3.forceCenter(width / 2, height / 2));

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

   var nodes = svg.selectAll("g")      
     .data(graph.nodes)
     .enter()
     .append("g");

   nodes.append("rect")
    .attr("class", "nodes")
    .attr("width", 70)
    .attr("height", 20)
    .attr("fill", function(d) { return color(d.group); })
    .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

   nodes.append("text")
    .attr("class", "labels")
    .attr("dy", "1.5em")
    .attr("dx", "1.5em")
    .attr("text-anchor", "start")
    .text(function(d) { return d.id; });

   nodes.selectAll('rect')
     .attr("width", function(d) {return this.parentNode.getBBox().width+10;})

   simulation
    .nodes(graph.nodes)
    .on("tick", ticked);

   simulation.force("link")
   .links(graph.links);

   function ticked() {
     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; });

    nodes.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
   }

   function dragstarted(d) {
     if (!d3.event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
   }

   function dragged(d) {
    d.fx = d3.event.x;
    d.fy = d3.event.y;
   }

   function dragended(d) {
    if (!d3.event.active) simulation.alphaTarget(0);
     d.fx = null;
     d.fy = null;  
   }

1 个答案:

答案 0 :(得分:1)

在这一行:

var nodes = svg.selectAll("g")      
   .data(graph.nodes)
   .enter()
   .append("g");

您是&#34;选择所有群组&#34;。但是,当它运行时,您在DOM中已经有一个<g>元素(查看var link)。因此,您的第一个数据将绑定到现有的<g>,并且您的输入选择将减少一个元素。

解决方案:选择不存在的内容

var nodes = svg.selectAll("foo")      
   .data(graph.nodes)
   .enter()
   .append("g");