2015-04-16 1 views
0

Я хочу иметь большую точку (или нечто подобное) в центре некоторых краев. Следующий код - лучшее, что я смог произвести.Как сделать края украшены большой точкой в ​​Graphviz?

digraph BDD { 
    ordering = out; 
    splines = true; 
    edge [arrowhead="none"]; 
    node [shape = none, label = "SUM"] 0; 
    node [shape = circle, label = "x"] 1; 
    node [shape = circle, label = "y"] 2; 
    node [shape = circle, label = "w"] 3; 
    node [shape = none, label = "1"] 4; 
    node [shape = circle, label = "z"] 5; 
    node [shape = none, label = "1"] 6; 
    node [shape = circle, label = "y"] 7; 
    node [shape = circle, label = "w"] 8; 
    node [shape = none, label = "1"] 9; 
    0 -> 1; 
    1 -> 2; 
    1 -> 7 [arrowhead="dot"]; 
    2 -> 3; 
    2 -> 5 [arrowhead="dot"]; 
    3 -> 4 [arrowhead="dot"]; 
    3 -> 4; 
    5 -> 6 [arrowhead="dot"]; 
    5 -> 6; 
    7 -> 5; 
    7 -> 8; 
    8 -> 9; 
    8 -> 5; 
} 

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

enter image description here

Может кто-нибудь предложить мне решение, чтобы произвести это:

enter image description here

EDIT 1: с помощью дополнительных узлов в точках создает неприемлемый выход.

digraph BDD { 
    ordering = out; 
    splines = true; 
    edge [arrowhead="none"]; 
    node [shape = none, label = "SUM"] 0; 
    node [shape = circle, label = "x"] 1; 
    node [shape = circle, label = "y"] 2; 
    node [shape = circle, label = "w"] 3; 
    node [shape = none, label = "1"] 4; 
    node [shape = circle, label = "z"] 5; 
    node [shape = none, label = "1"] 6; 
    node [shape = circle, label = "y"] 7; 
    node [shape = circle, label = "w"] 8; 
    node [shape = none, label = "1"] 9; 
    0 -> 1; 
    1 -> 2; 
    node [shape = point width=0.1] p1p7; 
    1 -> p1p7 -> 7; 
    2 -> 3; 
    node [shape = point width=0.1] p2p5; 
    2 -> p2p5 -> 5; 
    node [shape = point width=0.1] p3p4; 
    3 -> p3p4 -> 4; 
    3 -> 4; 
    node [shape = point width=0.1] p5p6; 
    5 -> p5p6 -> 6; 
    5 -> 6; 
    7 -> 5; 
    7 -> 8; 
    8 -> 9; 
    8 -> 5; 
} 

enter image description here

EDIT 2: Я могу также принять график, где точки не точно по центру. Они только не должны касаться узла, то есть, возможно, было бы хорошо, если бы я мог установить/сделать расстояние между стрелкой и узлом.

ответ

1

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

digraph { 
    node [shape = circle] 
    A 
    C 
    node [shape = point width=0.2] 
    B 
    edge [arrowhead=none] 
    A -> B -> C 
} 

производит

enter image description here


EDIT:

Вы можете макет вашего графика в * .dot файл, в котором все узлы и ребра размещены. то вы можете использовать свой любимый язык программирования для чтения и изменения этого файла. Существует также встроенный язык скриптов, который я еще не пробовал. Наконец, вы используете nop2-engine для преобразования измененного DOT-файла в формат изображения по вашему выбору. Вы должны выяснить, как разместить точки на сплайнах Безье. Согласно документации

splineType 
    spline (';' spline)* 
    where spline = (endp)? (startp)? point (triple)+ 
    and triple = point point point 
    and endp = "e,%f,%f" 
    and startp = "s,%f,%f" 

мы всегда имеем 4 + 3n (0 < = п) очков за края. это 4 набора кубических сплайнов, где конечная точка одного сплайна является начальной точкой следующего сплайна. при непосредственном касании начальных/конечных точек они являются кандидатами на размещение точки, если есть по меньшей мере два сплайна (7 баллов). в общем, каждая точка [4 + 3n] является кандидатом. если у нас есть один сплайн, этот подход не подходит. мы должны поместить точку на сплайн. действительные 4-кортежи начинаются с 0 + 3n и заканчиваются 3 + 3n.

вы можете использовать любой 4-кортеж х/у координаты вычислить точку на шлицы

x = (x1 + 3*x2 + 3*x3 + x4)/8 

это простой формульной для делителя 2. аналогично вы можете сделать для у-координаты.

Пример:

digraph { rankdir = LR ranksep=1 nodesep=1 pad=0.5 
    node [shape = circle] 
    edge [arrowhead=none] 
    { rank=same 
     A -> B 
     B -> C 
     A -> C 
    } 
} 

дает

digraph { 
    graph [bb="0,0,74.575,252", 
     nodesep=1, 
     pad=0.5, 
     rankdir=LR, 
     ranksep=1 
    ]; 
    node [label="\N", 
     shape=circle 
    ]; 
    edge [arrowhead=none]; 
    { 
     graph [rank=same]; 
     A  [height=0.5, 
      pos="56.575,234", 
      width=0.5]; 
     B  [height=0.5, 
      pos="56.575,126", 
      width=0.5]; 
     A -> B  [pos="56.575,215.75 56.575,191.88 56.575,168.01 56.575,144.14"]; 
     C  [height=0.5, 
      pos="56.575,18", 
      width=0.5]; 
     A -> C  [pos="44.02,220.46 24.619,197.84 -9.2417,150.66 2.5745,108 10.795,78.323 31.695,48.606 44.952,31.836"]; 
     B -> C  [pos="56.575,107.75 56.575,83.878 56.575,60.01 56.575,36.141"]; 
    } 
} 

край от линии

 A -> C  [pos="44.02,220.46 24.619,197.84 -9.2417,150.66 2.5745,108 10.795,78.323 31.695,48.606 44.952,31.836"]; 

состоит из 2 шлицев. мы имеем один перекрывающийся старт/конечную точку, что мы можем использовать непосредственно

U1 [shape=point width=0.2 color=red pos="2.5745,108"] 

от выбранного края выше, есть 2 действительные 4-кортежи на выбор в результате 2-х точках по шлицам (для divider2)

X1 [shape=point width=0.2 pos="11.59,171.75"] 
X2 [shape=point width=0.2 pos="21.87,65.08"] 

объединенный файл

digraph { 
    graph [bb="0,0,74.575,252", 
     nodesep=1, 
     pad=0.5, 
     rankdir=LR, 
     ranksep=1 
    ]; 
    node [label="\N", 
     shape=circle 
    ]; 
    edge [arrowhead=none]; 
    { 
     graph [rank=same]; 
     A  [height=0.5, 
      pos="56.575,234", 
      width=0.5]; 
     B  [height=0.5, 
      pos="56.575,126", 
      width=0.5]; 
     A -> B  [pos="56.575,215.75 56.575,191.88 56.575,168.01 56.575,144.14"]; 
     C  [height=0.5, 
      pos="56.575,18", 
      width=0.5]; 
     A -> C  [pos="44.02,220.46 24.619,197.84 -9.2417,150.66 2.5745,108 10.795,78.323 31.695,48.606 44.952,31.836"]; 
     B -> C  [pos="56.575,107.75 56.575,83.878 56.575,60.01 56.575,36.141"]; 

     U1 [shape=point width=0.2 color=red pos="2.5745,108"] 
     X1 [shape=point width=0.2 pos="11.59,171.75"] 
     X2 [shape=point width=0.2 pos="21.87,65.08"] 
    } 
} 

дает

enter image description here

+0

Это работает в тривиальном примере, но, к сожалению, он дает неприемлемый вывод для реальных примеров. Как показано в отредактированном вопросе, есть два очень плохих свойства. Во-первых, линии между узлами теперь состоят из 2 частей, например. y-z не является прямым, а во-вторых, дополнительные точки очень сильно меняют ранги узлов. – meolic

+0

В этом случае вам приходится иметь дело с манипулированием сплайнами самостоятельно. см. мое редактирование. – stefan

+0

В моем ответе было неправильное определение правильных 4-х кортежей. Я исправил это и добавил также возможность прямого использования точек переключения сплайнов. – stefan

Смежные вопросы