Добавьте ссылки, специфичные для узла, в граф forceSimulation, ориентированный на силу, в d3.js

У меня есть этот график силы. Я хочу, чтобы каждый круг содержал ссылку на другую страницу, чтобы при нажатии на нее зритель перенаправлялся.

Есть ли способ сделать это?

Кроме того, было бы неплохо прикрепить текст (внутри) к каждому узлу, но это гораздо менее важно.

var numNodes = 12
var nodes = d3.range(numNodes).map(function(d) {
  return {
    radius: Math.random() * 20 + 40
  }
})

var simulation = d3.forceSimulation(nodes)
  .force('charge', d3.forceManyBody().strength(4))
  .force('center', d3.forceCenter(400, 250))
  .force('collision', d3.forceCollide().radius(function(d) {
    return d.radius
  }))
  .on('tick', ticked);

function orb() {
  var u = d3.select('svg')
    .selectAll('circle')
    .data(nodes)

  u.enter()
    .append('circle')
    .attr('r', function(d) {
      return d.radius
    })
    .merge(u)
    .attr('cx', function(d) {
      return d.x
    })
    .attr('cy', function(d) {
      return d.y
    })

  u.exit().remove()
}

function ticked() {
  orb()
}
circle:hover {
  fill: red;
  stroke: #444;
  stroke-width: 0.5;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.min.js"></script>

<svg width = "800" height = "800" class=''>
  <g>
  </g>
</svg>
Поведение ключевого слова "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) для оценки ваших знаний,...
0
0
272
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Посмотрите, отвечает ли это на оба ваших вопроса. Я хорошо это прокомментировал; дайте мне знать, если что-то неясно:

<!DOCTYPE html>

<html>
  <head>
    <style>
      circle:hover {
        fill: red;
        stroke: #444;
        stroke-width: 0.5;
      }
      text {
        fill: #fff;
      }
    </style>
  </head>

  <body>
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.min.js"></script>

    <svg width = "800" height = "800" class = "">
      <g></g>
    </svg>

    <script>
      var numNodes = 12;
      var nodes = d3.range(numNodes).map(function (d) {
        return {
          radius: Math.random() * 20 + 40,
          link:
            Math.random() < 0.5
              ? 'https://www.wikipedia.org'
              : 'https://www.google.com',
          text: Math.random() < 0.5 ? 'text' : 'string'
        };
      });

      var simulation = d3
        .forceSimulation(nodes)
        .force('charge', d3.forceManyBody().strength(4))
        .force('center', d3.forceCenter(400, 250))
        .force(
          'collision',
          d3.forceCollide().radius(function (d) {
            return d.radius;
          })
        )
        .on('tick', ticked);

      function orb() {

        // update selection
        let g = d3.select('svg')
          .selectAll('g')
          .data(nodes);

        // enter selection
        let ge = 
          g.enter()
          .append('g');
        
        // on enter append `a`
        // around the circle
        ge
          .append('a')
          .attr('href', function (d) {
            return d.link;
          })
          .attr('target', '_blank')
          .append('circle')
          .attr('r', function (d) {
            return d.radius;
          });

        // on enter create text element
        // for each circle
        ge
          .append('text')
          .attr('text-anchor', 'middle')
          .text(function(d){
            return d.text;
          })

        // merge update and enter
        g = ge.merge(g);

        // position circle
        g
          .selectAll('circle')
          .attr('cx', function (d) {
            return d.x;
          })
          .attr('cy', function (d) {
            return d.y;
          })

        // position text "in" circle
        g.selectAll('text')
          .attr('transform', function(d){
            return 'translate(' + d.x + ',' + d.y + ')';
          })

        g.exit().remove();
      }

      function ticked() {
        orb();
      }
    </script>
  </body>
</html>

это именно то, что я пытался сделать, и это очень ясно. Я действительно не могу отблагодарить вас достаточно!

Sean McClure 23.12.2020 21:03

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