Простой макет графика в d3.js?

Я хотел бы нарисовать простой график с d3.js, как этот

Простой макет графика в d3.js?

Мне не удалось найти схему графа ни в документации по v5 API, ни в Интернете.

Во всех примерах используется макет d3.force из d3-сила. Хотя это выглядит впечатляюще, я не ищу компоновку графика с физическим моделированием.

Есть ли более простая раскладка или лучше всего использовать раскладку d3.force с отключенной физикой?

Поведение ключевого слова "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) для оценки ваших знаний,...
1
0
2 655
1

Ответы 1

Нет необходимости использовать d3.forceSimulation, это, в конечном счете, лишь один из множества предлагаемых макетов D3. Если вы посмотрите на пример Майка Бостока График, направленный по силе, то вам понадобятся следующие модификации:

  1. Определите набор nodes - в основном набор вещей для представления кругов
  2. Добавьте элементы svg:circle в DOM с помощью .data(nodes)
  3. Определился набор links
  4. Добавьте элементы svg:line в DOM с помощью .data(links)

По сути, здесь используется D3 для привязки данных чистой DOM, а не предварительно созданный макет.

Вы действительно можете скопировать любой из примеров силы - все, что он делает внизу, это установка x и позиции y внизу. Если они у вас уже есть, просто разместите свои круги в этих точках.

Все части, связанные с simulation и событием ticked, вы можете удалить из примера.

Вот пример статического макета:

var svg = d3.select("svg"),
  width = +svg.attr("width"),
  height = +svg.attr("height");

var color = d3.scaleOrdinal(d3.schemeCategory20);

const layout = (graph) => {
  return new Promise((resolve) => {
    var simulation = d3
      .forceSimulation()
      .alphaMin(0.3)
      .force("link", d3.forceLink().id(function(d) {
        return d.id;
      }))
      .force("charge", d3.forceManyBody())
      .force("center", d3.forceCenter(width / 2, height / 2))
      .on("end", resolve(graph));

    simulation.nodes(graph.nodes);
    simulation.force("link").links(graph.links);
  });
};

const render = (graph) => {

  var link = d3.select("#target").append("g")
    .attr("class", "links")
    .selectAll("line")
    .data(graph.links)
    .enter().append("line")
    .attr("stroke-width", function(d) { return Math.sqrt(d.value); })
    .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; });

  var node = d3.select("#target").append("g")
    .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
    .attr("r", 5)
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .attr("fill", function(d) { return color(d.group); });
}


d3.json("https://gist.githubusercontent.com/mbostock/4062045/raw/5916d145c8c048a6e3086915a6be464467391c62/miserables.json", function(error, graph) {
  if (error) throw error;
 
  layout(graph)
     .then((graph) => render(graph));
});
.links line {
  stroke: #999;
  stroke-opacity: 0.6;
}

.nodes circle {
  stroke: #fff;
  stroke-width: 1.5px;
}
<script src = "https://d3js.org/d3.v4.min.js"></script>
<svg width = "960" height = "600">
   <g id = "target" transform = "translate(480, 300)">
   </g>
</svg>

РЕДАКТИРОВАТЬ

Чтобы изменить расстояние между узлами, вам нужно изменить некоторые действующие силы. Документы действительно хороши - в частности, вы хотите изменить https://github.com/d3/d3-force#many-body

Итак, измените силу charge, чтобы она читалась:

.force("charge", d3.forceManyBody().strength(-charge))

Вам нужно будет определить заряд и немного подправить его, пока сила не даст вам хороший макет.

ПРИМЕЧАНИЕ. Когда я перехожу по указанной вами ссылке, я получаю Ошибка приложения

Zak 01.05.2018 22:37

Причина, по которой мне нужен макет, заключается в том, что я хочу, чтобы x и y были рассчитаны для меня для узлов и ссылок, например, в макете дерева.

ps-aux 01.05.2018 22:51

@Zak похоже, что bl.ocks.org сейчас не работает. Это будет временно, поэтому я пока оставлю ссылку. Источник можно увидеть на gist.github.com/mbostock/4062045

Ian 01.05.2018 22:57

@ dev-null вы можете использовать любой макет для расчета позиций. Вы даже можете использовать силу - дать ему поработать несколько сотен миллисекунд, остановить его и занять те позиции, которые он создал. Нет необходимости держать его в рабочем состоянии / перезапускать, давая эффекты движения.

Ian 01.05.2018 22:58

@ dev-null Я добавил пример использования силы только для расчета макета, а затем разделил рендеринг. Если вы хотите, вы можете изменить эту функцию layout для запуска макета tree, макета circle pack или любого другого пользовательского макета, который вы хотите.

Ian 01.05.2018 23:12

ОК. Я вижу результаты. Но они довольно плотно упакованы. Как мне отрегулировать, как далеко они должны быть? Кроме того, правильно ли я понимаю, что если мне нужен график и макет, это мой лучший выбор? Мне не нужен макет tree (и, кроме того, разве он не требует древовидной иерархии с корнями?), И подумал, что circle pack предназначен для группировки, что не подходит для моего случая.

ps-aux 02.05.2018 21:39

@ dev-null да, похоже, forceSimulation - лучший макет для вас. Настоятельно рекомендую посмотреть документацию по API (она не такая уж и длинная) github.com/d3/d3-force#forceSimulation. Но я обновлю свой ответ

Ian 03.05.2018 10:19

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