Двунаправленные стрелки возможны в силе направленного графа?

Я создал граф, похожий на этот силовой направленный граф: http://bl.ocks.org/d3noob/5141278 :

введите здесь описание изображения

Используя ссылку в качестве примера: Сара связана с Джеймсом, а Джеймс связан с Сарой. Вместо того, чтобы загромождать страницу двумя стрелками (по одной в каждом направлении), есть ли способ сделать так, чтобы на ней была только одна стрелка с треугольниками на обоих концах?


person Bubbles    schedule 06.12.2013    source источник
comment
Привет! можете ли вы сказать мне, есть ли у вас этот пример, но с прямоугольником вместо кругов? Спасибо   -  person Alan Grosz    schedule 10.03.2020


Ответы (2)


Все, что вам нужно сделать для этого, это добавить еще один маркер к ссылкам:

var path = svg.append("svg:g").selectAll("path")
  .data(force.links())
  .enter().append("svg:path")
  .attr("class", "link")
  .attr("marker-end", "url(#end)")
  .attr("marker-start", "url(#end");

Пример здесь. Однако это не работает идеально из-за того, как спецификация SVG указывает как следует вычислять направление, в котором указывает стрелка, в частности:

Если из вершины выходит только сегмент пути (например, первая вершина на открытом пути), положительная ось x маркера должна указывать в том же направлении, что и касательный вектор для сегмента пути, выходящего из вершины. (Обратитесь к примечаниям по реализации элемента «путь» для более подробного обсуждения направленности сегментов пути.)

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

person Lars Kotthoff    schedule 06.12.2013
comment
Я попытался добавить это, и, к сожалению, у меня все еще были две линии, а теперь еще и дополнительная стрелка с другой стороны моего узла. Я создал jfiddle: jsfiddle.net/6w2La - person Bubbles; 06.12.2013
comment
Да, это, как я уже сказал, из-за спецификации SVG. Нет простого способа обойти это, кроме рисования второй (идентичной) линии в противоположном направлении, чтобы создать впечатление одной линии со стрелками, указывающими в правильном направлении. - person Lars Kotthoff; 06.12.2013
comment
Я предполагаю, что вы редактировали свой ответ, когда я публиковал свой комментарий (я добавил свой комментарий до того, как отредактированная часть вашего ответа появилась на моем экране - я не игнорировал то, что вы написали). Я думаю, что смогу увидеть, если добавить стрелки к такому примеру (bl.ocks.org/mbostock/2706022) будет работать лучше... - person Bubbles; 07.12.2013
comment
Вместо того, чтобы рисовать вторую линию, я просто избавился от кривизны линии. См. скорректированную функцию тика ниже: , dr = Math.sqrt(dx * dx + dy * dy); вернуть M + d.source.x +, + d.source.y + + d.target.x +, + d.target.y; }) ; Вот обновленная скрипта для просмотра результатов: jsfiddle.net/6w2La/2 - person Bubbles; 07.12.2013

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

Итак, сначала создайте два определения стрелок:

vis.append("defs").selectAll("marker")
    .data(["arrow"])
    .enter().append("marker")
    .attr("id", "markerEnd")
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 19)
    .attr("refY", -0,7)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr('markerUnits', "userSpaceOnUse")
    .attr("orient", "auto")
    .append("path")
    .attr("d", "M0,-5L10,0L0,5");

vis.append("defs").selectAll("marker")
    .data(["arrow"])
    .enter().append("marker")
    .attr("id", "markerStart")
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", -12)
    .attr("refY", -0,7)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr('markerUnits', "userSpaceOnUse")
    .attr("orient", "auto")
    .append("path")
    .attr("d", "M0,0L10,-5L10,5Z");

Как видите, один называется "markerStart" и один "markerEnd", теперь они в противоположном направлении.

Тогда путь выглядит так:

hlink.enter().append("path")
    .attr("class", "hlink")
    .attr("marker-start", "url(#markerStart)")
    .attr("marker-end", "url(#markerEnd)");
person Highriser    schedule 18.03.2016