2013-06-28 3 views
6

В настоящее время я пишу библиотеку графов в Java, и мне нужен инструмент для визуализации некоторых графиков. Я обнаружил Graph-viz, который, случается, отличный, хотя и глючный, способ сделать это.Graphviz (xdot): Как сделать рекурсивные узлы?

В моей модели, Графы состоят из Узлов и Грани. Каждый узла имеет определенное количество портов (I/O/IO) и Edges ссылки эти портов вместе. Некоторые специальные узлы называются GraphNodes и вставляют График. В порты этих GraphNodes отображаются в некоторых портов внутренних узлов.

Я хотел бы предоставить несколько представлений. Первый из них, с которыми я доволен, выглядит следующим образом: http://i.stack.imgur.com/ujU71.png

вход Порты представлены зеленым цветом, выход из них красным цветом, а вход-выход из них в синий цвет.

В этом представлении GraphNodes не расширены и отображаются так же просто Вершины. Во второй версии я хотел бы создать что-то, что выглядит следующим образом: http://i.stack.imgur.com/Cx624.png

Проблема в том, что я не могу создать подграф (кластер) с фиксированными областями (похоже, это не так возможное). Еще одно решение, которое я пробовал, - это встроить граф в узел. Тем не менее, вставив код в <td> </td> часть HTML этикетки не оценивает код:

digraph graph0 
{ 

    node1 
    [ 
     label = 
     < 
      <table border="0" cellspacing="0"> 
       <tr> 
        <td cellpadding="0"> 
         <table border="0" cellspacing="0"> 
          <tr> 
           <td bgcolor="palegreen" border="1" port="port2">port2</td> 
           <td bgcolor="palegreen" border="1" port="port3">port3</td> 
          </tr> 
         </table> 
        </td> 
       </tr> 
       <tr> 
        <td cellpadding="0"> 
         <table border="0" cellspacing="0"> 
          <tr> 
           <td cellpadding="0"> 
            <table border="0" cellspacing="0"> 
             <tr> 
              <td bgcolor="skyblue" border="1" port="port5">port5</td> 
             </tr> 
            </table> 
           </td> 
           <td bgcolor="peachpuff" border="1"> 

            subgraph clusterTest 
            { 
             nodeTest 
            } 

           </td> 
          </tr> 
         </table> 
        </td> 
       </tr> 
       <tr> 
        <td cellpadding="0"> 
         <table border="0" cellspacing="0"> 
          <tr> 
           <td bgcolor="lightpink" border="1" port="port4">port4</td> 
          </tr> 
         </table> 
        </td> 
       </tr> 
      </table> 
     > 
     style = "invisible" 
    ] 

} 

Предыдущий код создает следующий график: http://i.stack.imgur.com/E9jQ1.png

Наконец, самое лучшее решение, которое я могу придумать это следующее: http://i.stack.imgur.com/VzS5g.png

Однако я не доволен, потому что GraphNodes "Порты расположены в странных местах иногда.

Вы знаете, как я могу достичь целевого графика? При необходимости запросите любую другую информацию.


EDIT: Я до сих пор не нашли какого-либо решения. Способ справиться с этим состоял бы в том, чтобы уметь фиксировать положение заданных узлов внутри содержащего кластера, но, похоже, это не представляется возможным с помощью «точечного» макета. Есть идеи ?

ответ

1

Используя орграф, можно указать положения узлов (относительно друг друга). Это можно использовать, чтобы заставить определенные элементы появляться над другими.В то время как другие узлы могут быть вынуждены появиться на том же уровне (порт 101 и 102 в этом примере)

Поддельный вложенности: Этот график не использует вложенные открытого текста/полупрофессиональных HTML узлы, потому что я не думаю, это возможно (не функция). Я не уверен, поддерживают ли их библиотеки graphviz, но, возможно, стоит посмотреть на другие библиотеки. Я даже не использовал точку с Java или Python, иначе я бы сделал предложение.


nesting


Орграф { nodesep = 0,2 ranksep = 0,8 колодки = 0,1 узел [форма = квадрат] узел [стиль = заполненный] край [Arrowhead = нет]

// rankdir = LR

component_starter [этикетка = < port02 port03 port06 S port07 port08 port04 port05 > стиль = "невидимый"]

подграф cluster_container { этикетка = "I/O устройство с компонентами " цвет = оранжевый

//margin = 0 
edge [ style="invis"] 
//edge [ len="0.5" minlen="1" ] 
node [ height="0.5" width="2" fixedsize=true ]; 
node [ shape=rectangle style=filled ] 
{ 
node [ color=palegreen ]; 
    { rank = same port101 -> port102 } 
} 
{ 
node [ color=skyblue]; 
    port103 port104 } 
{ 
node [ height="1.5" width="2" fixedsize=true ]; 
node [ color=peachpuff]; 
    //notaport 
} 
{ 
node [ height="0.5" width="4" fixedsize=true ]; 
node [ color=lightpink]; 
    output 
} 

// -

//subgraph cluster_inner { 
    //label="abstractions" 
    //color="black" 
    //style="invis" 
    component_a [ label = < 
     <table border="0" cellspacing="0"><tr> 
      <td border="1" bgcolor="white" > </td> 
      <td border="1" bgcolor="palegreen" port="port2">port2</td> 
      <td border="1" bgcolor="palegreen" port="port3">port3</td> 
     </tr><tr> 
      <td border="1" bgcolor="skyblue" port="port6">port6</td> 
      <td border="1" bgcolor="peachpuff" rowspan="3" colspan="2">A</td> 
     </tr><tr> 
      <td border="1" bgcolor="skyblue" port="port7">port7</td> 
     </tr><tr> 
      <td border="1" bgcolor="skyblue" port="port8">port8</td> 
     </tr><tr> 
      <td border="1" bgcolor="lightpink" colspan="1" port="port4">port4</td> 
      <td border="1" bgcolor="lightpink" colspan="2" port="port5">port5</td> 
     </tr></table> > style = "invisible" ] 

    component_b [ label = < 
     <table border="0" cellspacing="0"><tr> 
      <td border="1" bgcolor="white" > </td> 
      <td border="1" bgcolor="palegreen" port="port22">port22</td> 
      <td border="1" bgcolor="palegreen" port="port23">port23</td> 
     </tr><tr> 
      <td border="1" bgcolor="skyblue" port="port25">port25</td> 
      <td border="1" bgcolor="peachpuff" colspan="2"> B </td> 
     </tr><tr> 
     <td border="1" bgcolor="lightpink" colspan="3" port="port24">port24</td> 
     </tr></table> > style = "invisible" ] 

// -

component_c [ label = < 
     <table border="0" cellspacing="0"><tr> 
      <td border="1" bgcolor="white" > </td> 
      <td border="1" bgcolor="palegreen" port="port32">port32</td> 
      <td border="1" bgcolor="palegreen" port="port33">port33</td> 
     </tr><tr> 
      <td border="1" bgcolor="skyblue" port="port35">port35</td> 
      <td border="1" bgcolor="peachpuff" colspan="2"> C </td> 
     </tr><tr> 
     <td border="1" bgcolor="lightpink" colspan="3" port="port34">port34</td> 
     </tr></table> > style = "invisible" ] 
//} 


port101 -> port103 
port102 -> component_a 
port102 -> component_b 
port103 -> port104 

component_a -> output; 
component_b -> output; 
component_c -> output; 

edge [ style="" arrowhead="normal" color="#444444"] 
component_a:port4 -> output; 

component_c:port34 -> component_a:port3; 
component_a:port5 -> component_b:port22; 

port101 -> component_c:port33 

// -

{ rank = same 

    edge [ dir=back ] 
    port104 -> component_a:port8 
} 

} 

component_starter; 
component_starter:port5 -> port101; 

} 

выше файл дот, сжимаются. Используйте base64 -d nesting.bz2.base64 |bzcat для просмотра.

QlpoOTFBWSZTWd/epEIABCzfgHAwWAP/3zgkmAq/7//6UASZm8a7VNrQBQQlSDUaYjTINGjIyZAG 
ho0aNMgkUZJpEIzUw0TTEzQBoAIwCTUiFT1NppDymGk0Pap6gMmCaAAcwAAAAAAAAAAFSRJoGp6B 
TyNTyhABoD1DQ0aephLyAcTAhMSQiKogMBLsVaZBYIwUHIGFISYVKCMVkRgLypG2mhHPb5z0hBap 
yN3HCL2iJVDYvXI6SykmzPN9LCaex+63c7jyTnk18c2KgvDZq6Kkz+WWf4DU4KoQsCQJ1gKpAcwC 
mp5nGnmlI8wBNtgDi+Hmf0/g/v4PoNaZVrhy5cdWCavJkutPC0t50kljBJLHXrbQUjJMPPDCUKwN 
NHO8aaiqKTus3tLEpprCW8Gzr68DtvyteHrqa7JJ9J46R4muUMuU39kJYPEgwJWwCSqsgMteezTo 
ta1rr3va1sccdW/32OJUROFkmUzqeyHn+g96EccgEY5SfJixh2aJgQC0JVmWAtrdagoOkDZAViKA 
qUpGZ1dXNJikmmsRZmAO16Kq9osW7KzzPZPS9IeLIqXo0cOoNwatry3Mi792YMRvA3oiKxe84ac7 
EMGmdrabTaG0qqDpAMJJn5IeAbvMNiSJW8og7y+Ik+CExJBhLDZlKFSFKMBgIIMai57J5pLmgl5R 
Qm261e797RF6qhy82NQypLEa8ktUVAL2R1hxThWC3pVB0jBThRxVLfHHJeZHv+pMEkxZ3P6KP+ho 
QWyC9gtIM2cxJK2pIiiIooOPlxE0kkspJPijcgrHRHw6XvMpwy5ldiqlUpWzvymgxr78zAXh4vSW 
L3jya8Hqc6ekwhhDROybThDBnIdmdlN6ClO8bo7ucxNqSVjHNGd8F8ocW2qmT0bJRujojA9MJqnC 
TPg09tZlJ5d/am7W8E6GeU3TkyVC0N5nTgeXXn7Sj1UWijm1Q07OKeXiyPbENRSNcNzrnkyxkNeu 
RgS5GWEXKkpTdIy8NenUhVYpqkbUCushe+cQ15oMcRIrb4GZscDDVmLk3LF7Txk6yFvmky8aoiK5 
T+3pVRjVVVUtLRVFFI0q1lrpHlGqNnHKOVIKkktUYAuq2L1bekwQeG68LX3tK64kVNRw2tDb7rLn 
acBl0J61Ld57HXXHKpXLjoqAo5yyRvQ/YxLdufjNCSaEk4mmYLcZp1ybI1BqDTum20PSm2cId4pU 
Zx00pZzOJZwnSHjAqXNkWCM4s/+LuSKcKEhv71IhAA== 
+0

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

+0

Привет! Спасибо за ваш ответ, извините, что я не мог проверить это раньше. Однако я не могу заставить его работать. Похоже, что Python терпит неудачу при получении атрибута «ширина». Какую версию Xdot вы используете для визуализации (мой - 0,4)? Или другой мягкий? Во всяком случае, ваш ответ выглядит идеально для меня! –

+0

Я визуализировал это непосредственно с помощью графика. dot - graphviz version 2.26.3 –