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

Javascript 获取要与D3.js图形中的节点一起移动的文本,javascript,d3.js,Javascript,D3.js,我有下面的代码,它对一个类似于的图形进行编码。我想在节点上添加标签,并希望在这个图的边缘添加标签,但是,在我下面的代码中,当图形移动时,节点上的文本不会移动。如何使文本随节点一起移动 <!DOCTYPE html> <meta charset="utf-8"> <style> .link { stroke: #000; stroke-width: 1.5px; } .node { cursor: move; fill: #ccc; st

我有下面的代码,它对一个类似于的图形进行编码。我想在节点上添加标签,并希望在这个图的边缘添加标签,但是,在我下面的代码中,当图形移动时,节点上的文本不会移动。如何使文本随节点一起移动

<!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>

.链接{
行程:#000;
笔划宽度:1.5px;
}
.节点{
光标:移动;
填充:#ccc;
行程:#000;
笔划宽度:1.5px;
}
.node.fixed{
填充:#f00;
}
可变宽度=960,
高度=500;
var-force=d3.layout.force()
.尺寸([宽度、高度])
。收费(-400)
.linkDistance(40)
.在(“滴答”,滴答)上;
var drag=force.drag()
.on(“dragstart”,dragstart);
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
var link=svg.selectAll(“.link”),
node=svg.selectAll(“.node”);
text=svg。选择全部(“.text”);
变量图={
“节点”:[
{“x”:469,“y”:410,“标签”:“A”},
{“x”:493,“y”:364,“标签”:“B”},
{“x”:442,“y”:365,“标签”:“C”},
{“x”:467,“y”:314,“标签”:“D”},
{“x”:477,“y”:248,“标签”:“E”},
{“x”:425,“y”:207,“标签”:“F”},
{“x”:402,“y”:155,“标签”:“G”},
{“x”:369,“y”:196,“标签”:“H”},
{“x”:350,“y”:148,“标签”:“I”},
{“x”:539,“y”:222,“标签”:“J”},
{“x”:594,“y”:235,“标签”:“K”},
{“x”:582,“y”:185,“标签”:“L”},
{“x”:633,“y”:200,“标签”:“M”}
],
“链接”:[
{“源”:0,“目标”:1},
{“源”:1,“目标”:2},
{“源”:2,“目标”:0},
{“源”:1,“目标”:3},
{“源”:3,“目标”:2},
{“源”:3,“目标”:4},
{“源”:4,“目标”:5},
{“源”:5,“目标”:6},
{“源”:5,“目标”:7},
{“源”:6,“目标”:7},
{“源”:6,“目标”:8},
{“源”:7,“目标”:8},
{“源”:9,“目标”:4},
{“来源”:9,“目标”:11},
{“源”:9,“目标”:10},
{“源”:10,“目标”:11},
{“源”:11,“目标”:12},
{“源”:12,“目标”:10}
]
};
(功能(){
console.log(图形)
力
.nodes(图.nodes)
.links(graph.links)
.start();
link=link.data(graph.links)
.enter().append(“行”)
.attr(“类”、“链接”);
node=node.data(graph.nodes)
.enter().append(“圆”)
.attr(“类”、“节点”)
.attr(“r”,12)
.on(“dblclick”,dblclick)
.呼叫(拖动);
var text=svg.append(“svg:g”)。选择全部(“g”)
.data(force.nodes())
.enter().append(“svg:g”);
text.append(“svg:text”)
.text(函数(d){返回d.label;})
text.attr(“转换”,函数(d){
返回“translate”(“+d.x+”,“+d.y+”);
})
})();
函数tick(){
attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;});
}
函数dblclick(d){
d3.选择(this).classed(“fixed”,d.fixed=false);
}
函数dragstart(d){
d3.选择(this).classed(“fixed”,d.fixed=true);
}

您应该翻译
勾选
函数中的
文本
组,或者更好的是,将圆圈和文本附加到组中,并仅翻译
勾选
函数中的组。

您可以让
节点
引用一组元素,即
圆圈
文本
元素:

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; });
然后,您需要更新
勾选
函数,使其仅转换组而不是圆:

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 circle {
  cursor: move;
  fill: #ccc;
  stroke: #000;
  stroke-width: 1.5px;
}

.node.fixed circle {
  fill: #f00;
}
工作示例