D3.js Observable Force Layout, Labels not appearing

那年仲夏 提交于 2021-02-11 12:12:51

问题


My force layout code is standard, based of the usual data:

chart = {
  const links = data.links.map(d => Object.create(d));
  const nodes = data.nodes.map(d => Object.create(d));

  const simulation = d3.forceSimulation(nodes)
      .force("link", d3.forceLink(links).id(d => d.id))
      .force("charge", d3.forceManyBody())
      .force("center", d3.forceCenter(width / 2, height / 2))
      .force("link", d3.forceLink().distance(function(d) {return d.value;}).strength(0.1))

  const svg = d3.create("svg")
      .attr("viewBox", [0, 0, width, height]);

  const link = svg.append("g")
      .attr("stroke", "#999")
      .attr("stroke-opacity", 0.6)
    .selectAll("line")
    .data(links)
    .join("line")
      .attr("stroke-width", d => Math.sqrt(d.id));

  const node = svg.append("g")
      .attr("stroke", "#fff")
      .attr("stroke-width", 1.5)
      .attr("class", "labels")
    .selectAll("circle")
    .data(nodes)
    .join("circle")
      .attr("r", 10)
      .attr("fill", color)
      .call(drag(simulation));

  var lables = node.append("text")
      .text(function(d) {
        return d.id;
      })
      .attr('x', 6)
      .attr('y', 3);

  node.append("title")
      .text(d => d.id);

  simulation.on("tick", () => {
    link
        .attr("x1", d => d.source.x)
        .attr("y1", d => d.source.y)
        .attr("x2", d => d.target.x)
        .attr("y2", d => d.target.y);

    node
        .attr("cx", d => d.x)
        .attr("cy", d => d.y);
  });

  invalidation.then(() => simulation.stop());

  return svg.node();
}

I am trying to add labels to each node. Note the label code above. This adds the labels to the node element (confirmed by browser console), but the labels do not appear:

Since D3 doesn't support z-index the order of adding elements is obviously wrong. How can I make the labels appear on each node?


回答1:


Here is the updated Observable.

The problem was that you were adding the text "inside" the circle and that is not possible in an SVG. The solution is to create a group instead of a circle, use translate instead cx and cy in the tick function, and finally, create the circle and the text inside the group. I hope it helps.



来源:https://stackoverflow.com/questions/57172926/d3-js-observable-force-layout-labels-not-appearing

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