获取与D3.js图中的节点一起移动的文本

时间:2014-01-21 20:55:44

标签: javascript d3.js

我在下面的代码中编写了一个类似于here的图表。我想向节点添加标签,并希望这个图的边缘,但是,在我的代码中,我移动图表时节点上的文本不会移动。如何让我的文本与节点一起移动?

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.link {
  stroke: #000;
  stroke-width: 1.5px;
}

.node {
  cursor: move;
  fill: #ccc;
  stroke: #000;
  stroke-width: 1.5px;
}

.node.fixed {
  fill: #f00;
}

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var width = 960,
    height = 500;

var force = d3.layout.force()
    .size([width, height])
    .charge(-400)
    .linkDistance(40)
    .on("tick", tick);

var drag = force.drag()
    .on("dragstart", dragstart);

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

var link = svg.selectAll(".link"),
    node = svg.selectAll(".node");
    text = svg.selectAll(".text");

var graph = {
  "nodes": [
    {"x": 469, "y": 410, "label": "A"},
    {"x": 493, "y": 364, "label": "B"},
    {"x": 442, "y": 365, "label": "C"},
    {"x": 467, "y": 314, "label": "D"},
    {"x": 477, "y": 248, "label": "E"},
    {"x": 425, "y": 207, "label": "F"},
    {"x": 402, "y": 155, "label": "G"},
    {"x": 369, "y": 196, "label": "H"},
    {"x": 350, "y": 148, "label": "I"},
    {"x": 539, "y": 222, "label": "J"},
    {"x": 594, "y": 235, "label": "K"},
    {"x": 582, "y": 185, "label": "L"},
    {"x": 633, "y": 200, "label": "M"}
  ],
  "links": [
    {"source":  0, "target":  1},
    {"source":  1, "target":  2},
    {"source":  2, "target":  0},
    {"source":  1, "target":  3},
    {"source":  3, "target":  2},
    {"source":  3, "target":  4},
    {"source":  4, "target":  5},
    {"source":  5, "target":  6},
    {"source":  5, "target":  7},
    {"source":  6, "target":  7},
    {"source":  6, "target":  8},
    {"source":  7, "target":  8},
    {"source":  9, "target":  4},
    {"source":  9, "target": 11},
    {"source":  9, "target": 10},
    {"source": 10, "target": 11},
    {"source": 11, "target": 12},
    {"source": 12, "target": 10}
  ]
};

(function() {
  console.log(graph)
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  link = link.data(graph.links)
    .enter().append("line")
      .attr("class", "link");

  node = node.data(graph.nodes)
    .enter().append("circle")
      .attr("class", "node")
      .attr("r", 12)
      .on("dblclick", dblclick)
      .call(drag);

  var text = svg.append("svg:g").selectAll("g")
           .data(force.nodes())
           .enter().append("svg:g");

  text.append("svg:text")
      .text(function(d) { return d.label; })

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

})();


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; });
}

function dblclick(d) {
  d3.select(this).classed("fixed", d.fixed = false);
}

function dragstart(d) {
  d3.select(this).classed("fixed", d.fixed = true);
}

</script>

2 个答案:

答案 0 :(得分:1)

您可以node引用一组元素,即circletext元素:

node = node.data(graph.nodes)
  .enter().append("g")
    .attr("class", "node")
    .on("dblclick", dblclick)
    .call(drag);

node.append("circle")
  .attr("r", 12);

node.append("svg:text")
  .attr("dx", -6)
  .attr("dy", 6)
  .text(function(d) { return d.label; });

然后,您需要更新tick功能,以便它仅转换组而不是圆圈:

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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}

最后,需要对CSS进行一次小更新,以反映圆圈现在位于一组node组中的事实,而不是自己属于该类:

.node circle {
  cursor: move;
  fill: #ccc;
  stroke: #000;
  stroke-width: 1.5px;
}

.node.fixed circle {
  fill: #f00;
}

工作示例here

答案 1 :(得分:0)

您应该翻译text功能上的tick群组,或者更好的是,将圈子和文字附加到群组,并仅翻译tick功能中的群组。< / p>