Установить направление узла на графике
Предположим, этот код использует 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
может также быть полезным в этом случае, но я не уверен. Надеюсь это поможет.