2013-06-28 4 views
6

Attualmente sto scrivendo una libreria di grafi in Java e vorrei uno strumento per visualizzare alcuni grafici. Ho scoperto Graph-viz, che sembra essere un ottimo modo di fare questo, anche se buggy.Graphviz (xdot): come creare nodi ricorsivi?

Nel mio modello, Grafici sono composti da nodi e bordi. Ogni nodo hanno un certo numero di Ports (I/O/IO) e Bordi link di quei Ports insieme. Alcuni nodi speciali sono chiamati GraphNodes e incorporano un grafico. Le porte di questi GraphNodes sono mappati alcuni porte degli interni Nodi.

Mi piacerebbe fornire diverse rappresentazioni. Il primo di essi, con la quale sono soddisfatto, è la seguente: http://i.stack.imgur.com/ujU71.png

l'ingresso Porte sono rappresentati in verde, quelle di uscita in rosso, e quelli di ingresso-uscita in blu.

In questa rappresentazione, le GraphNodes non vengono espansi e vengono visualizzati altrettanto semplice Nodi. In una seconda versione, vorrei creare qualcosa che assomigli alla seguente immagine: http://i.stack.imgur.com/Cx624.png

Il problema è che non riesco a creare un sottogramma (cluster) con aree fisse (sembra non essere possibile). Un'altra soluzione che ho provato è stata incorporare un grafico in un nodo. Tuttavia, l'inserimento del codice nella <td> </td> parte di un'etichetta HTML non valuta il codice:

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" 
    ] 

} 

Il codice precedente crea grafico seguente: http://i.stack.imgur.com/E9jQ1.png

Infine, la soluzione migliore che può venire in mente è il seguente: http://i.stack.imgur.com/VzS5g.png

Tuttavia io non sono soddisfatto, perché i GraphNodes 'Ports sono collocati in posizioni strane a volte.

Per favore, so come posso raggiungere il layout del grafico di destinazione? Si prega di chiedere qualsiasi altra informazione se necessario.


EDIT: io ancora non ho trovato alcuna soluzione. Un modo per gestire questo sarebbe essere in grado di correggere la posizione dei nodi dati all'interno del cluster contenente, ma non sembra possibile con il layout "punto". Qualche idea ?

risposta

1

Utilizzando un digraph, è possibile specificare le posizioni dei nodi (l'uno rispetto all'altro). Questo può essere usato per forzare alcuni elementi ad apparire sopra gli altri.Mentre altri nodi possono essere costretti a comparire sullo stesso livello (porta 101 e 102 in questo esempio)

fasullo nesting: Questo grafico non utilizza nidificate nodi in chiaro/semi-html perché non credo ciò è possibile (non una caratteristica). Non sono sicuro che nessuna delle librerie di graphviz possa supportarle, ma potrebbe valere la pena di esaminare altre librerie. Non ho mai nemmeno usato punti da Java o Python, altrimenti darei un suggerimento.


nesting


digramma { nodesep = 0.2 ranksep = 0,8 pad = 0,1 nodo [forma = square] nodo [style = riempito] edge [freccia = none]

// rankdir = LR

component_starter [label = < port02 port03 port06 S port07 port08 port04 port05 > style = "invisibile"]

sottografo cluster_container { label = "I/O dispositivo con componenti " color = orange

//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; 

} 

Il file di punti di cui sopra, compressi. Utilizzare base64 -d nesting.bz2.base64 |bzcat per vederlo.

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

Sto facendo cadere questo in grembo, perché devo correre ora. Fatemi sapere se ci sono domande (dettagli) che posso aggiungere alla risposta ... –

+0

Ciao! Grazie per la tua risposta, mi dispiace non averlo provato prima. Tuttavia non riesco a farlo funzionare. Sembra che Python stia fallendo l'attributo 'larghezza' dell'attore. Quale versione di Xdot usi per visualizzarla (la mia è 0.4)? O un altro morbido? Ad ogni modo, la tua risposta sembra perfetta per me! –

+0

L'ho reso direttamente con graphviz. dot - graphviz versione 2.26.3 –