1

我的目标是在所有节点折叠的情况下开始布局,点击它们展开。这里的问题是文本标签在鼠标悬停时会创建重复项。他们还在屏幕的左上角创建副本。

我已将 json 减少到用于测试的最小量,低于代码块。

我究竟做错了什么?

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <title>Force-Directed Graph</title>
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <style type="text/css">

circle.node {
  cursor: pointer;
  stroke: #3182bd;
  stroke-width: 1.5px;
}

line.link {
  fill: none;
  stroke: #9ecae1;
  stroke-width: 1.5px;
}

    </style>
  </head>
  <body>
    <div id="chart"></div>
    <script type="text/javascript">

var w = 960,
    h = 500,
    node,
    link,
    root, 
    t;

var force = d3.layout.force()
    .on("tick", tick)
    .size([w, h]);

var vis = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

d3.json("test.json", function(json) {
  root = json;
  update();

 function toggleAll(d) {
    if (d.children) {
      d.children.forEach(toggleAll);
      toggle(d);
    }
  }
    // Initialize the display to show a few nodes.
  root.children.forEach(toggleAll);


update(root); 
});

function update() {
  var nodes = flatten(root),
      links = d3.layout.tree().links(nodes);

  // Restart the force layout.
  force
      .nodes(nodes)
      .links(links)
        .charge(-1000)
    .linkDistance(100)
    .friction(0.5)
      .start();

  // Update the links…
  link = vis.selectAll("line.link")
      .data(links, function(d) { return d.target.id; });

  // Enter any new links.
  link.enter().insert("svg:line", ".node")
      .attr("class", "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; });

  // Exit any old links.
  link.exit().remove();

  // Update the nodes…
  node = vis.selectAll("circle.node")
      .data(nodes, function(d) { return d.id; })
      .style("fill", color);

  // Enter any new nodes.
  node.enter().append("svg:circle")
      .attr("class", "node")
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; })
      .attr("r",  "15")
      .style("fill", color)
      .on("mouseover", mouseover)     
      .call(force.drag);

  // Exit any old nodes.
  node.exit().remove();

  t = vis.selectAll("t.node")
      .data(nodes, function(d) { return d.id; })
      .style("fill", color);

  // Enter any new nodes.
  t.enter().append("svg:text")
      .attr("class", "t-node")
      .attr("dx", "25px")
      .attr("y", 0)
      .text("test");
     // .call(force.drag);

  // Exit any old nodes.
  t.exit().remove();

}

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

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

}

// Color leaf nodes orange, and packages white or blue.
function color(d) {
  return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}

// Toggle children on click.
function mouseover(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  update();
}

// Returns a list of all nodes under the root.
function flatten(root) {
  var nodes = [], i = 0;

  function recurse(node) {
    if (node.children) node.children.forEach(recurse);
    if (!node.id) node.id = ++i;
    nodes.push(node);
  }

  recurse(root);
  return nodes;
}
function toggle(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
}
    </script>
  </body>
</html>

    {
 "name": "Test",
 "children": [
  {
   "name": "cat 1",
   "children": [
    {"name": "subcat 1-a", "size": 1082},
    {"name": "subcat 1-b", "size": 1082}
   ]
  },
  {
   "name": "cat 2",
   "children": [
    {"name": "subcat 2-a", "size": 1082}
   ]
  }  
 ]
}
4

1 回答 1

2

At the risk of stealing @Lars' answer, vis.selectAll("t.node") looks like it needs to be vis.selectAll(".t-node"). If you don't use a selector in selectAll that matches the nodes you append in the .enter() selection, you'll get duplicate nodes every time it runs.

于 2013-07-06T21:47:19.090 回答