Установить направление узла на графике

Предположим, этот код использует neato:

graph sample {
  layout=neato
  overlap=false
  splines=true
  tailclip=false
  headclip=false
  A -- I
  A -- J
  A -- B
  A -- H
  A -- E
  A -- K
  B -- D
  B -- C
  B -- L
  C -- M
  C -- N
  C -- O
  D -- P
  D -- Q
  E -- R
  F -- A
  G -- F
  H -- J
}

Это дает нам эту схему:

диаграмма Нейто

Что мне нужно, это разместить узел X, всегда фиксируется в позиции к югу от родительского узла. т.е. если я поставлю другое отношение A -- X, X должен быть всегда расположен на юге от A, И мне все равно, где все остальное заканчивается.

Я посмотрел в pos атрибут, но это не кажется решением, так как X на самом деле не в фиксированной позиции, но в положении относительно его отношения.

Также tailport а также headport, но они только определяют, откуда ребро будет выходить / входить, но на самом деле не влияют на направление узла.

Обновить

Дополнительное изображение, чтобы прояснить ситуацию:

х должен быть к югу от своего родителя

Мне не нужен Neato, но я не хочу, чтобы график выглядел как дерево точек UD или LR, я не хочу, чтобы он был линейно упорядочен. Цирко, FDP, SFDP, Twopi тоже в порядке.

2 ответа

Решение

Программа neato поддерживает несколько режимов, один из которых может дать вам то, что вы хотите. В частности, если вы установите mode = ipsep, вы можете указать точечные ограничения, которые будут соблюдаться во время макета. Например, я беру ваш график и использую атрибуты графика

mode=ipsep
diredgeconstraints=true
levelsgap=0.5

Первый включает режим ipsep, второй сообщает модели, что она поддерживает направленные ребра, как в точке, а последний указывает, насколько сильным должно быть разделение. Затем я устанавливаю атрибут edge dir

edge[dir=none]

и добавить ребро A - X [dir=1]

Значение dir = 1 указывает, что этот край должен вызывать ограничение направления. Если я затем запускаю Neato, я получаю приложенную картинку.

аккуратный макет

В документации по атрибутам Graphviz http://www.graphviz.org/content/attrs содержится дополнительная информация об этих атрибутах.

В ответ на обновленные ограничения одним из решений является закрепление A и X, а затем разметка графика вокруг них:

graph sample {
overlap=false;
splines=true;
tailclip=false;
headclip=false;

A [pin=true,pos="0,.2"]
X [pin=true,pos="0,.1"]
A -- I
A -- J
A -- B
A -- H
A -- E
A -- K
B -- D
B -- C
B -- L
C -- M
C -- N
C -- O
D -- P
D -- Q
E -- R
F -- A
G -- F
H -- J
A -- X

вывод графика

Я пробовал компоновку как с Neato, так и с fdp, и кажется, что график выглядит так, как вы хотите. Естественно, если вы хотите наложить такое ограничение на произвольные пары узлов в одном графе, это решение может не сработать.

--- более ранний ответ ---

Если вы решили использовать neato, я не уверен, что есть способ решить проблему без изменения графика на этапе последующей обработки. Если neato - просто удобное значение по умолчанию, тогда вы сможете решить свою проблему, используя вместо этого точку в качестве движка компоновки, и используя "rankdir=UD", плюс пару дополнительных ключей, если X нужно направить на юг.

В случае, если вам нужно только ограничение для применения к одному узлу X, тогда объединение X и A в кластере должно сделать эту работу:

graph sample {
  rankdir=UD 
  layout=dot
  overlap=false
  // .. as before
  A -- X
  subgraph clusterone {
   style=invisible
   A
   X
  }
}

Если вам нужно ограничение строго на юг для применения к произвольным дочерним элементам A, то за такого рода кластеризацией следует трюк, описанный в:

Как заставить все узлы в одном столбце в графвизе?

может сделать трюк. Атрибут clusterrank=local может также быть полезным в этом случае, но я не уверен. Надеюсь это поможет.

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