如何将文本居中放置在节点中?

时间:2019-02-25 04:31:52

标签: javascript d3.js svg

我正在了解d3.js和部队制度。我有一个阻止程序,因为我无法添加文本,并且该文本完全位于圆心内。我曾尝试创建<text>,但是它不起作用。我该如何实现?

在这篇文章中,我尝试创建一个text元素,但是它不起作用。

    var node = g.append("g")
        .attr("class", "nodes")
        .selectAll("circle")
        .data(graph.nodes)
        .enter()
        .append("circle")
        .attr("r", 20)
        .attr("fill", function(d){
          return colorNode(d.group);
        })
        .style("stroke", function(d){
          return colorNode(d.group);
        })

enter image description here

更新  我知道我必须以某种方式在g元素内使该内容包含圆圈和文本,但是我无法使其起作用。显然,我也不知道如何在圆内使文本居中。我的结果是该圆出现在力图的外面。我已经尝试过了,但是没有用:

    var node = g.append("g")
        .attr("class", "nodes")
        .selectAll("g")
        .data(graph.nodes)
        .enter()
        .append("g");
        node.append("circle")
        .attr("r", 20)
        .attr("fill", function(d){
          return colorNode(d.group);
        })
        .style("stroke", function(d){
          return colorNode(d.group);
        })

这是我的完整代码:

https://plnkr.co/edit/JhjhFKQgKVtmYQXmgbzF?p=preview

1 个答案:

答案 0 :(得分:6)

您需要做的就是将dominant-baseline设置为central,将文本垂直居中;将text-anchor设置为middle,将文本水平居中。另外,请摆脱那些xy属性。

这应该是选择:

var text = g.append("g")
    .attr("class", "labels")
    .selectAll("text")
    .data(graph.nodes)
    .enter()
    .append("text")
    .style("dominant-baseline", "central")
    .style("text-anchor", "middle")
    .style("font-family", "sans-serif")
    .style("font-size", "0.7em")
    .text(function(d) {
        return d.lotid;
    });

这是您所做的更改的代码:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .node {
    stroke: #fff;
    stroke-width: 1.5px;
  }
  
  .link {
    stroke: #999;
    stroke-opacity: .9;
  }
</style>

<body>
  <div id="grafica_back" style="width:100wh"></div>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
    var w = window,
      d = document,
      e = d.documentElement,
      g = d.getElementsByTagName('body')[0],
      width = w.innerWidth || e.clientWidth || g.clientWidth,
      height = w.innerHeight || e.clientHeight || g.clientHeight;

    var colorNode = d3.scaleOrdinal()
      .range(d3.schemeCategory20),
      colorLink = d3.scaleOrdinal()
      .range(d3.schemeCategory10)

    var svg = d3.select("#grafica_back").append("svg")
      .attr("width", width)
      .attr("height", height);

    var graph = {
      "nodes": [{
          "id": "18362286",
          "lotid": "TEST",
          "epoch": 1511295513000,
          "group": 1,
          "sourceOnly": true
        },
        {
          "id": "18362287",
          "lotid": "TEST",
          "epoch": 1511324313000,
          "group": 2,
          "sourceOnly": false
        }
      ],
      "links": [{
        "source": "18362286",
        "target": "18362287",
        "reltype": "GENEALOGY"
      }]
    };

    var width = 400,
      height = 200;

    var simulation = d3.forceSimulation()
      .nodes(graph.nodes);

    simulation
      .force("charge_force", d3.forceManyBody().strength(-100))
      .force("center_force", d3.forceCenter(width / 2, height / 2))
      .force("links", d3.forceLink(graph.links).id(function(d) {
        return d.id;
      }).distance(100).strength(0.1))
      .force("collide", d3.forceCollide().radius(2))

    ;

    simulation
      .on("tick", ticked);

    //add encompassing group for the zoom 
    var g = svg.append("g")
      .attr("class", "everything");

    //Create deffinition for the arrow markers showing relationship directions
    g.append("defs").append("marker")
      .attr("id", "arrow")
      .attr("viewBox", "0 -5 10 10")
      .attr("refX", 23)
      .attr("refY", 0)
      .attr("markerWidth", 8)
      .attr("markerHeight", 8)
      .attr("orient", "auto")
      .append("svg:path")
      .attr("d", "M0,-5L10,0L0,5");





    var link = g.append("g")
      .attr("class", "links")
      .selectAll("line")
      .data(graph.links)
      .enter().append("line")
      .attr("stroke", function(d) {
        console.log(d);
        return colorLink(d.group);
      })
      .attr("marker-end", "url(#arrow)");

    var node = g.append("g")
      .attr("class", "nodes")
      .selectAll("circle")
      .data(graph.nodes)
      .enter()
      .append("circle")
      .attr("r", 20)
      .attr("fill", function(d) {
        return colorNode(d.group);
      })
      .style("stroke", function(d) {
        return colorNode(d.group);
      })


    //add drag capabili



    var drag_handler = d3.drag()
      .on("start", drag_start)
      .on("drag", drag_drag)
      .on("end", drag_end);

    drag_handler(node);

    var text = g.append("g")
      .attr("class", "labels")
      .selectAll("text")
      .data(graph.nodes)
      .enter()
      .append("text")
      .style("dominant-baseline", "central")
      .style("text-anchor", "middle")
      .style("font-family", "sans-serif")
      .style("font-size", "0.7em")
      .text(function(d) {
        return d.lotid;
      });

    node.on("click", function(d) {
      d3.event.stopImmediatePropagation();
      self.onNodeClicked.emit(d.id);
    });

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

    //add zoom capabilities 
    var zoom_handler = d3.zoom()
      .on("zoom", zoom_actions);

    zoom_handler(svg);

    //Drag functions 
    //d is the node 
    function drag_start(d) {
      if (!d3.event.active) simulation.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
    }

    //make sure you can't drag the circle outside the box
    function drag_drag(d) {
      d.fx = d3.event.x;
      d.fy = d3.event.y;
    }

    function drag_end(d) {
      if (!d3.event.active) simulation.alphaTarget(0);
      d.fx = null;
      d.fy = null;
    }

    //Zoom functions 
    function zoom_actions() {
      g.attr("transform", d3.event.transform)
    }

    function ticked() {
      //update circle positions each tick of the simulation 
      node
        .attr("cx", function(d) {
          return d.x;
        })
        .attr("cy", function(d) {
          return d.y;
        });

      //update link positions 
      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;
        });

      text
        .attr("transform", function(d) {
          return "translate(" + d.x + "," + d.y + ")";
        });
    }
  </script>