首页 > 解决方案 > 在 React 中的 D3 节点上添加文本

问题描述

所以我有一个名为 scratch 的 JSON 文件,其中包含节点和链接......

{
  "nodes": [
    {
      "name": "Guardians of the Galaxy",
      "id": "1"
    },
    {
      "name": "Chris Pratt"
    },
    {
      "name": "Vin Diesel"
    }
  ],
  "links": [
    {
      "source": "Guardians of the Galaxy",
      "target": "Chris Pratt"
    },
    {
      "source": "Guardians of the Galaxy",
      "target": "Vin Diesel"
    }
  ]
}

我试图让每个节点的名称在加载时悬停在节点上。文字也非常大。这是我制作节点的方式

         const nodes_data = data['nodes'];

         let simulation = d3.forceSimulation()
              .nodes(nodes_data);

         simulation
             .force("charge_force", d3.forceManyBody())
             .force("center_force", d3.forceCenter(width / 2, height / 2));

         let node = svg.append("g")
         .attr("class", "nodes")
         .selectAll("circle")
         .data(nodes_data)
         .enter()
         .append("circle")
         .attr("r", 5)
         .attr("fill", "red");

         node.append("text")
            node.attr('transform', d => `translate(${d.name})`);

         simulation.on("tick", tickActions);

         function tickActions() {
    
                    node
                        .attr("cx", function (d) {
                            return d.x;
                        })
                        .attr("cy", function (d) {
                            return d.y;
                        });
         }

注意:我现在知道由于 .attr("x/y"...),文本卡在左上角,我只是不知道如何使它更小并越过节点。


            let text = svg.append("g")
                .attr("class", "nodes")
                .selectAll("text")
                .data(nodes_data)
                .enter()
                .append("text")
                .attr("x", function(d) { return d.x })
                .attr("y", function(d) { return d.y })
                .text(function(d) { return d.name });

标签: javascriptreactjsd3.js

解决方案


为确保节点标签始终位于节点之上,首先为两者创建单独的层,并确保在节点层之后添加标签层。要使标签更小,只需设置font-size

const nodetLayer = svg.append('g');
const textLayer = svg.append('g');
...
const texts = textLayer.selectAll('text')
  .data(nodes_data)
  .enter()
  .append('text')
  .attr('font-size', `${your-font-size}px`)
...
const nodes = nodelayer.selectAll('circle')
  .data(nodes_data)
  .enter()
  .append('circle')
 

或者,您可以为每个节点创建一个<g>元素,并向其附加一个<circle>和一个<text>


推荐阅读