#graph #graphviz #rank
#График #graphviz #ранг
Вопрос:
следующий код создает приведенный выше график:
digraph G {
//---graph config
fontname=Helvetica
rankdir = RL
splines = polyline
compound = true
//concentrate = true
labeljust = c
labelloc = t
ranksep=0.5
nodesep=0.5
//size="10,10"
ratio=compress
edge [
minlen=1
arrowsize=0.75
labeldistance=5
fontname=Helvetica
fontsize=12
fontcolor=black
labelfontsize=12
labelfontcolor=red
labelfontname=Helvetica
]
node [
fontname=Helvetica
fontsize=12
fontcolor=black
regular=true
shape=diamond
// width=0.25
// height=0.25
]
// --- # nodes
{// records
node [shape=record, width=1]
b10 [label=" { R-7 | 5 } | B/10 "]
b20 [label=" { R-6 | 10 } | B/20 "]
b30 [label=" { R-5 | 10 } | B/30 "]
d10 [label=" { R-10 | 15 } | D/10 "]
d20 [label=" { R-9 | 10 } | D/20 "]
d30 [label=" { R-8 | 10 } | D/30 "]
a20 [label=" { R-2 | 5 } | A/20 "]
a30 [label=" { R-1 | 10 } | A/30 "]
}
{// circles
node [shape=circle]
e [label="E"]
c [label="C"]
}
{// box
node [shape=box]
a [label="A"]
}
//--- # edges
{
edge [weight = 1000]
//straight
c -> b10 -> b20 -> b30
e -> d10 -> d20 -> d30
a20 -> a30 -> a
//combination
{b30 d30} -> a20
}
//--- # Clusters
// subgraph cluster_1{
// label="a "
// e d10 d20
// }
// subgraph cluster_2{
// label="b "
// c b10 b20 b30
// }
// subgraph cluster_3{
// label="c "
// a30 a20
// }
// --- # bugfixes
{// c before e
edge [style=invis]
c -> e
{rank=source e c} // force same rank before other nodes
}
}
Это именно так красиво и чисто, как я хочу, чтобы это было.
Тем не менее, я хочу иметь возможность отмечать и комментировать определенные разделы структуры, и я думаю, что кластеры должны быть правильным средством для этого.
Если вы раскомментируете раздел CLUSTERS в коде, вы получите следующий код и соответствующий график:
digraph G {
//---graph config
fontname=Helvetica
rankdir = RL
splines = polyline
compound = true
//concentrate = true
labeljust = c
labelloc = t
ranksep=0.5
nodesep=0.5
//size="10,10"
ratio=compress
edge [
minlen=1
arrowsize=0.75
labeldistance=5
fontname=Helvetica
fontsize=12
fontcolor=black
labelfontsize=12
labelfontcolor=red
labelfontname=Helvetica
]
node [
fontname=Helvetica
fontsize=12
fontcolor=black
regular=true
shape=diamond
// width=0.25
// height=0.25
]
// --- # nodes
{// records
node [shape=record, width=1]
b10 [label=" { R-7 | 5 } | B/10 "]
b20 [label=" { R-6 | 10 } | B/20 "]
b30 [label=" { R-5 | 10 } | B/30 "]
d10 [label=" { R-10 | 15 } | D/10 "]
d20 [label=" { R-9 | 10 } | D/20 "]
d30 [label=" { R-8 | 10 } | D/30 "]
a20 [label=" { R-2 | 5 } | A/20 "]
a30 [label=" { R-1 | 10 } | A/30 "]
}
{// circles
node [shape=circle]
e [label="E"]
c [label="C"]
}
{// box
node [shape=box]
a [label="A"]
}
//--- # edges
{
edge [weight = 1000]
//straight
c -> b10 -> b20 -> b30
e -> d10 -> d20 -> d30
a20 -> a30 -> a
//combination
{b30 d30} -> a20
}
//--- # Clusters
subgraph cluster_1{
label="a "
e d10 d20
}
subgraph cluster_2{
label="b "
c b10 b20 b30
}
subgraph cluster_3{
label="c "
a30 a20
}
// --- # bugfixes
{// c before e
edge [style=invis]
c -> e
{rank=source e c} // force same rank before other nodes
}
}
Как вы можете видеть из раздела исправлений в конце кода, я хочу, чтобы узлы C и E определенно отображались с одинаковым рангом «выше» всех других узлов.
Более того, я хочу, чтобы верхняя и нижняя последовательности записей были соединены красивыми прямыми линиями, как в первом примере. Вес ребер, который я ввел, не помогает.
Кто-нибудь знает, как исправить эту проблему и как заставить graphviz создавать хороший чистый график, как в примере # 1, с добавлением всего 3 охватывающих полей и соответствующих меток?
Ответ №1:
Я попытался изменить только то, что было необходимо:
- Добавлен дополнительный кластер без метки и
style=invis
(для d30) - Изменен порядок расположения узлов, чтобы кластер b располагался выше кластера a
- Удален вес ребра
- Раздел исправлений удален
- Удалены некоторые разрывы строк
Вот что я получаю с последней версией graphviz (2.29):
Не идеально, но намного ближе.
digraph G {
//---graph config
fontname=Helvetica
rankdir = RL
splines = polyline
compound = true
//concentrate = true
labeljust = c
labelloc = t
ranksep=0.5
nodesep=0.5
//size="10,10"
ratio=compress
edge [
minlen=1
arrowsize=0.75
labeldistance=5
fontname=Helvetica
fontsize=12
fontcolor=black
labelfontsize=12
labelfontcolor=red
labelfontname=Helvetica
]
node [
fontname=Helvetica
fontsize=12
fontcolor=black
regular=true
shape=diamond
// width=0.25
// height=0.25
]
// --- # nodes
{// records
node [shape=record, width=1]
d10 [label=" { R-10 | 15 } | D/10 "]
d20 [label=" { R-9 | 10 } | D/20 "]
d30 [label=" { R-8 | 10 } | D/30 "]
b10 [label=" { R-7 | 5 } | B/10 "]
b20 [label=" { R-6 | 10 } | B/20 "]
b30 [label=" { R-5 | 10 } | B/30 "]
a20 [label=" { R-2 | 5 } | A/20 "]
a30 [label=" { R-1 | 10 } | A/30 "]
}
{// circles
node [shape=circle]
e [label="E"]
c [label="C"]
}
{// box
node [shape=box]
a [label="A"]
}
//--- # edges
{
//straight
c -> b10 -> b20 -> b30
e -> d10 -> d20 -> d30
a20 -> a30 -> a
//combination
{b30 d30} -> a20}
//--- # Clusters
subgraph cluster_1{
label="a "
e d10 d20
}
subgraph cluster_2{
label="b "
c b10 b20 b30
}
subgraph cluster_3{
label="c "
a30 a20
}
subgraph cluster_4{
label=""
style=invis
d30
}
}
Комментарии:
1. Это именно то решение, которое я искал. Идеально для меня! Спасибо! Я внимательно рассмотрю ваши исправления. Отлично!
2. Существует ли определенное правило, которое объясняет мне, почему я должен определять общие узлы раньше других, хотя я хочу, чтобы они отображались внизу графика? Или вы просто перетасовывали определения, пока это не сработало?
3. Обычно узлы одного ранга отображаются в том порядке, в котором они были определены, за исключением случаев, когда макет необходимо оптимизировать. Поиграйте с
digraph{a;b->{c;d;};e;}
: удалите e, a помещается слева; удалите a, e помещается справа; измените порядок c и d, и они поменяются местами. Когда вы меняете rankdir , все меняется после rankdir. Более сложные графики часто невозможно предсказать, и тогда возникает та или иная ошибка и ограничение при использовании некоторых опций или фигур (record). Таким образом, это не просто перетасовка узлов, но мне всегда нужно визуальное подтверждение, чтобы быть уверенным 😉