Как я могу центрировать текст в узле?

Я изучаю d3.js и систему сил. У меня есть блокировщик, потому что я не могу добавить текст, и он идеально расположен по центру круга. Я пытался создать <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);
        })

Как я могу центрировать текст в узле?

ОБНОВИТЬ Я знаю, что я должен каким-то образом сделать это в элементе 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

атрибут text-anchor, объединить круг и текст в элементе g для каждого узла и анимировать элемент g

rioV8 25.02.2019 09:28

@ rioV8 Я обновил свой вопрос, я пробовал, но у меня не работает. Положение круга другое.

yavg 25.02.2019 17:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
2
272
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Все, что вам нужно, это установить dominant-baseline на central, чтобы центрировать текст по вертикали, и text-anchor на middle, чтобы центрировать текст по горизонтали. Кроме того, избавьтесь от этих атрибутов x и y.

Это должен быть выбор:

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.info(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>

Другие вопросы по теме