Как разместить текст в круге при использовании принудительного макета D3.js?

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

<style>

.node {
  stroke: #fff;
  stroke-width: 1.5px;
}

.link {
  stroke: #999;
  stroke-opacity: .6;
}

</style>
<body>
</body>
<script src="d3.v3.min.js"></script>
<script>

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("data.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", function(d) {return d.r;})
      .style("fill", function(d) { return color(d.group); })

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

  node.append("text")
       .text("A");

  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>
</html>

В приведенном выше коде используется D3js для рисования графика Force-Directed из некоторых данных, и я просто хочу поместить некоторый текст в круг, поэтому я использую node.append("text"), вы можете видеть это выше.

Но однако, когда его добавить, он не работает, в круге все еще нет текста, поэтому мне интересно, как это могло быть????


person user2579274    schedule 18.12.2013    source источник


Ответы (1)


SVG не допускает элемент text внутри элемента circle. Вы должны поместить элементы circle и text в общий элемент g. Попробуйте что-то вроде этого (не проверено):

  var node = svg.selectAll(".node")
      .data(graph.nodes).enter().append('g').classed('node', true);

  node.append("circle")
      .attr("r", function(d) {return d.r;})
      .style("fill", function(d) { return color(d.group); })
      .append("title")
      .text(function(d) { return d.name; });

  node.append("text")
       .text("A");

А затем вместо установки cx и cy на узлах установите свойство transform на g.node:

  force.on("tick", function() {
    // ...

    node.attr("transform", function(d) { return 'translate(' + [d.x, d.y] + ')'; })
  });
person musically_ut    schedule 18.12.2013