labels for circles not showing up in d3 data visualization

一曲冷凌霜 提交于 2021-01-28 10:51:48

问题


I am following this tutorial to create a node-like data visualization.

<!DOCTYPE html>
<meta charset="utf-8">
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

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

var color = d3.scaleOrdinal(d3.schemeCategory20);

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

d3.json("miserables.json", function(error, graph) {
  if (error) throw error;

  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 node = svg.append("g")
      .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
      .attr("r", 5)
      .attr("fill", function(d) { return color(d.group); })
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

  node.append("span")
      .text(function(d) { return d.id; });

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

    node
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return 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;
}

</script>

However, I want to text next to each circle with its id/name on it with the extra element g but nothing is showing up for some reason.

When I inspect each circle. It shows the with the correct id, but the spans are not showing on the graph at all. <circle><span>example id</span></circle>


回答1:


You are not appending text to g elements, you are appending text to circles, let's follow your code to see what the variable node holds:

  var node = svg.append("g")    // returns a selection holding a g
    .attr("class", "nodes")     // returns the same g, now with class "nodes"
    .selectAll("circle")        // returns an empty selection as there are no circles yet
    .data(graph.nodes)          // returns the empty selection with bound data
    .enter().append("circle")   // returns a selection of newly entered circles
      .attr("r", 5)             // continues to return the circles
      ...

So node holds a selection of circles, so when using node.append("span") we are attempting to add text to circles, which won't work. So we need to modify this slightly by breaking up your chaining:

var node = svg.append("g")  
  .attr("class", "nodes")
  .selectAll("circle")
  .data(graph.nodes)
  .enter().append("g");  // returns a selection of newly entered g elements

node.append("circle")   // returns a selection of circles, newly append to each g in node
  .attr("r", 5)
  .attr("fill", function(d) { return color(d.group); })
  .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

And now since node holds a selection of g elements, we can append text as well:

  node.append("text") // returns a selection of text, newly append to each g in node
      .text(function(d) { return d.id; });

There is a change here as well, I've changed node.append("span") to node.append("text"), we are appending svg elements, not html elements to the svg. While the span tags may be appended, it won't display as they aren't svg elements.

Lastly, as in this answer, you need to update the translate of each g in each tick rather than the cx and cy properties because a g isn't positioned by cx and cy attributes:

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

Here's an demo.

Note, to see your links you need to set a stroke color: .attr("stroke","black'); on your lines



来源:https://stackoverflow.com/questions/49882951/labels-for-circles-not-showing-up-in-d3-data-visualization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!