Я пытаюсь воссоздать в graphviz диаграмму, подобную той, что взята из книги CLR: enter image description here

Я использую следующий код в Python:

s = Digraph(node_attr={'shape': 'record'})
s.node('struct', ' 3| 13| 1| 2| 8| 5')
s.edge("struct:f0", "struct:f1")
s.edge("struct:f0", "struct:f2")
s.edge("struct:f1", "struct:f3")
s.edge("struct:f1", "struct:f4")
s

Результат таков: введите описание изображения здесь

Это очень близко к тому, что я хочу, за исключением того, что ребра перекрывают узлы, а не проходят над/под ними.

Я не смог найти способ изменить поведение граней. Также мне кажется, что я неправильно использую функцию структуры graphviz, но я не знаю, как заставить элементы графа слипаться в один ряд в противном случае.

Можно ли избежать наложения краев (кроме как изменив SVG самостоятельно, конечно) или вообще использовать другой подход?

Gadi A

Ответов: 1

Ответы (1)

Вы можете использовать "порты" для задания точек соединения.

Я попробовал ваш график на онлайн-сервисе, похоже, что ваш рендеринг происходит с точкой http://dreampuf.github.io/GraphvizOnline

.

Вы можете проверить с другими, Circo и остальные не пересекают ячейки, но по умолчанию они все рисуют с одной стороны (снизу) и края получаются неаккуратными.

Но есть свойства "ports", которые позволяют решить эту проблему, указывая суффиксы ":s", ":n" и т.д. n, s, e, w, nw, ne, sw, s. - т.е. юг, север и т.д.

Похоже, что у Dot другие порты по умолчанию, чем у Circo и Neato, и последние не возражают против этого:

digraph Structs {
    node [shape=record];        
    s [label=" 3| 13| 1|2|8|5"];
    s:f0 -> s:f1;
    s:f0 -> s:f2;
    s:f1:n -> s:f3:n;
    s:f1:n -> s:f4:n;
}

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

Также необходимо указать порты первых двух узлов:

digraph Structs {
    node [shape=record];       
    s [label=" 3| 13| 1|2|8|5"];
    s:f0:s -> s:f1:s;
    s:f0:s -> s:f2:s;
    s:f1:n -> s:f3:n;
    s:f1:n -> s:f4:n;
}

Так что я предполагаю, что в вашем коде:

s.edge("struct:f0:s", "struct:f1:s")
s.edge("struct:f0:s", "struct:f2:s")
s.edge("struct:f1:n", "struct:f3:n")
s.edge("struct:f1:n", "struct:f4:n")

См: Как предотвратить наложение ребер в graphviz друг на друга

Graphviz Dot Edge Ports for Family Tree

2022 WebDevInsider