graphviz: как предотвратить переопределение кластерами инструкции rank = source

#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). Таким образом, это не просто перетасовка узлов, но мне всегда нужно визуальное подтверждение, чтобы быть уверенным 😉