I'd like to draw a diagram like this.
I thought and searched for a long time and I can only generate the picture below.
digraph G {
node [shape=plaintext]
// newrank=true;
subgraph part1 {
{rank=same state0, state9, state6}
subgraph nest1 {
state0 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">0</TD></TR>
<TR><TD PORT="text1" bgcolor="red">S→ ・E$</TD></TR>
<TR><TD PORT="text2" bgcolor="green">E→ ・E+T <br/> E→・T </TD></TR>
<TR><TD PORT="text3" bgcolor="green">T→ ・id <br/> T→・(E)</TD></TR>
</TABLE>>];
}
subgraph nest2 {
state6 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">6</TD></TR>
<TR><TD PORT="text1" bgcolor="red">T→(・E) </TD></TR>
<TR><TD PORT="text2" bgcolor="green">E→ ・E+T <br/> E→・T </TD></TR>
<TR><TD PORT="text3" bgcolor="green">T→ ・id <br/> T→・(E)</TD></TR>
</TABLE>>];
}
subgraph nest3 {
state9 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">9</TD></TR>
<TR><TD PORT="text" bgcolor="red">E→T・ </TD></TR>
</TABLE>>];
state5 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">5</TD></TR>
<TR><TD PORT="text" bgcolor="red">T→id・ </TD></TR>
</TABLE>>];
}
// {rank=same; nest1; nest2; nest3;}
// nest1 -> nest2 -> nest3 [style=invis]
}
subgraph part2 {
{rank=same state1, state3, state7}
state1 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">1</TD></TR>
<TR><TD PORT="text" bgcolor="red">S→E・$<br/>E→E・+T</TD></TR>
</TABLE>>];
state7 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">7</TD></TR>
<TR><TD PORT="text1" bgcolor="red">T→(E・) </TD></TR>
<TR><TD PORT="text2" bgcolor="green">E→ E・+T</TD></TR>
</TABLE>>];
state3 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">3</TD></TR>
<TR><TD PORT="text1" bgcolor="red">E→E+・T </TD></TR>
<TR><TD PORT="text2" bgcolor="green">T→・id <br/> T→・(E) </TD></TR>
</TABLE>>];
}
subgraph part3 {
{rank=same state2, state4, state8}
state2 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">2</TD></TR>
<TR><TD PORT="text" bgcolor="red">S→E$・ </TD></TR>
</TABLE>>];
state8 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">8</TD></TR>
<TR><TD PORT="text" bgcolor="red">T→(E)・ </TD></TR>
</TABLE>>];
state4 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">4</TD></TR>
<TR><TD PORT="text" bgcolor="red">E→E+T・ </TD></TR>
</TABLE>>];
}
// state0:s -> state1:n [label="E"]
// state0:title:e -> state9:title:w [label="T"]
// state0:text3:e -> state5:text:w [label="id"]
// state0:text2:e -> state6:text2:w [label="("]
state0:s -> state1:n [label="E"]
state0 -> state9 [label="T"]
state0 -> state5 [label="id"]
state0 -> state6 [label="(", weight=100]
state1:s -> state2:n [label="$"]
state1:title:e -> state3:title:w [label="+"]
state3:s -> state4:n [label="T"]
state3:n -> state5:s [label="id"]
// state3:title:e -> state6:s [label="("]
state3:title:e -> state6 [label="("]
// state6:text3:w -> state5:text:e [label="id"]
// state6:s -> state7:n [label="E"]
// state6:title:w -> state9:title:e [label="T"]
// state6:title:n -> state6:e [label="("]
state6:s -> state7:n [label="E"]
state6 -> state9 [label="T"]
state6 -> state5 [label="id"]
state6 -> state6 [label="("]
state7:text2:w -> state3:text2:e [label="+"]
state7:s -> state8:n [label=")"]
// ------------ Invisible edges to order vertically node groups
state9:s -> state5:n [style=invis]
state5:s -> state3:n [style=invis]
state3:s -> state4:n [style=invis]
state6:s -> state7:n [style=invis]
state7:s -> state8:n [style=invis]
// ---------------------------------------------------
// below two lines make sure the order 1 3 7 | 2 4 8 is right
state1 -> state3 -> state7 [style=invis]
state2 -> state4 -> state8 [style=invis]
state0:text1:e -> state9:text1:w [style=invis]
state9:text1:e -> state6:text1:w [style=invis]
}
I want to adjust the 0 9 5 6 part. This means I need to rank same 0 9/5 6, I have tried using subgraph, but it doesn't solve the problem.
Is there any way to align two nodes horizontally and keep them top/bottom align like HTML image?
tk421 memtions neato in his answer, see How to force node position (x and y) in graphviz for more detail.
A couple fixes you can apply. splines=ortho will change the edges to vertical and horizontal lines. When you do this, the edge labels have to be redone as xlabel= instead of label=.
However, the 9 and 5 are not placed properly. If you use neato instead
of dot, you can position the nodes exactly where you want. Then you can
remove all the subgraph and invisible nodes and weight and do this:
The graphviz code would be:
digraph G {
splines=ortho;
node [shape=plaintext]
state0 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">0</TD></TR>
<TR><TD PORT="text1" bgcolor="red">S→ ・E$</TD></TR>
<TR><TD PORT="text2" bgcolor="green">E→ ・E+T <br/> E→・T </TD></TR>
<TR><TD PORT="text3" bgcolor="green">T→ ・id <br/> T→・(E)</TD></TR>
</TABLE>>, pos="0,4!"];
state6 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">6</TD></TR>
<TR><TD PORT="text1" bgcolor="red">T→(・E) </TD></TR>
<TR><TD PORT="text2" bgcolor="green">E→ ・E+T <br/> E→・T </TD></TR>
<TR><TD PORT="text3" bgcolor="green">T→ ・id <br/> T→・(E)</TD></TR>
</TABLE>>, pos="4,4!"];
state9 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">9</TD></TR>
<TR><TD PORT="text" bgcolor="red">E→T・ </TD></TR>
</TABLE>>, pos="2,4.7!"];
state5 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">5</TD></TR>
<TR><TD PORT="text" bgcolor="red">T→id・ </TD></TR>
</TABLE>>, pos="2,3.3!"];
state1 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">1</TD></TR>
<TR><TD PORT="text" bgcolor="red">S→E・$<br/>E→E・+T</TD></TR>
</TABLE>>, pos="0,1.5!"];
state7 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">7</TD></TR>
<TR><TD PORT="text1" bgcolor="red">T→(E・) </TD></TR>
<TR><TD PORT="text2" bgcolor="green">E→ E・+T</TD></TR>
</TABLE>>, pos="4,1.5!"];
state3 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">3</TD></TR>
<TR><TD PORT="text1" bgcolor="red">E→E+・T </TD></TR>
<TR><TD PORT="text2" bgcolor="green">T→・id <br/> T→・(E) </TD></TR>
</TABLE>>, pos="2,1.5!"];
state2 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">2</TD></TR>
<TR><TD PORT="text" bgcolor="red">S→E$・ </TD></TR>
</TABLE>>, pos="0,0!"];
state8 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">8</TD></TR>
<TR><TD PORT="text" bgcolor="red">T→(E)・ </TD></TR>
</TABLE>>, pos="4,0!"];
state4 [label=<
<TABLE ALIGN="LEFT" BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="title" bgcolor="yellow">4</TD></TR>
<TR><TD PORT="text" bgcolor="red">E→E+T・ </TD></TR>
</TABLE>>, pos="2,0!"];
state0:s -> state1:n [xlabel="E"]
state0 -> state9 [xlabel="T"]
state0:e -> state5:w [xlabel="id"]
state0 -> state6 [xlabel="("]
state1:s -> state2:n [xlabel="$"]
state1:title:e -> state3:title:w [xlabel="+"]
state3:s -> state4:n [xlabel="T"]
state3:n -> state5:s [xlabel="id"]
state3:title:e -> state6 [xlabel="("]
state6:s -> state7:n [xlabel="E"]
state6 -> state9 [xlabel="T"]
state6 -> state5 [xlabel="id"]
state6 -> state6 [xlabel="("]
state7:text2:w -> state3:text2:e [xlabel="+"]
state7:s -> state8:n [xlabel=")"]
}
References
Node, Edge and Graph Attributes:Splines
Node, Edge and Graph Attributes:pos
Placing Graphviz nodes in fixed positions
Related
I have a, generated, UML diagram and render this with dot (tests are done with version 7.0.5), the results are OK nut when I want to split the lines in the graph the rendering is not as I like it.
I tried to get the results with the HTML like labels in dot but this looks worse (I know that the dot manual, https://graphviz.org/doc/info/shapes.html#html, states it has only limited possibilities).
The original (node2) and adjusted / test (node3) code:
digraph "Class" {
bgcolor="transparent";
edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10];
node [fontname=Helvetica,fontsize=10,shape=record,height=0.2,width=0.8];
Node2 [label="{FClass\n|# m_trackingEnabled\l|+ FClass()\l+ InsertRenderMaterial\lInsertRenderMaterial()\l+ InsertRenderMaterialDelete\lInsertMaterial()\l+ setTrackingEnabled()\l}",
height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
Node3 [label=<
<TABLE CELLBORDER="0" BORDER="0">
<TR><TD COLSPAN="2" CELLPADDING="1" CELLSPACING="0">FClass</TD></TR>
<HR/>
<TR><TD VALIGN="top" CELLPADDING="1" CELLSPACING="0">#</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="1" CELLSPACING="0">m_trackingEnabled</TD></TR>
<HR/>
<TR><TD VALIGN="top" CELLPADDING="0" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="0" CELLSPACING="0">FClass()</TD></TR>
<TR><TD VALIGN="top" CELLPADDING="0" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="LEFT" CELLPADDING="0" CELLSPACING="0">InsertRenderMaterial<BR ALIGN="LEFT"/>InsertRenderMaterial()</TD></TR>
<TR><TD VALIGN="top" CELLPADDING="0" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="0" CELLSPACING="0">InsertRenderMaterialDelete<BR ALIGN="LEFT"/>InsertMaterial()</TD></TR>
<TR><TD VALIGN="top" CELLPADDING="0" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="0" CELLSPACING="0">setTrackingEnabled()</TD></TR>
</TABLE>
>,height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
}
the resulting image (left original, right adjusted / test):
Problems:
original
in case of splitting the line (second and third "Insert") the new line starts at the beginning. This is logical as we have just one string, but far from nice in our case.
adjusted
indentation of splitted lines is depending on the length
(minor) horizontal ruler should be stretch full box
Note:
I used here Helvetica as font, but the user can choose any font he likes so just adding some spaces in the original doesn't give the right result (unless....)
the initial character of the description will be one of +, #, -, *, ~.
Any solution / suggestions for improvement?
Small changes to both record & html versions:
to record:
added 3 non-breaking spaces ( ) after \l line break to shift right (align)
to html:
added <BR ALIGN="LEFT"/> to the end of every line segment (seems to apply to preceeding text)
set html node shape to plain to extend HR to edges
set cellpadding="1" (just because)
digraph "Class" {
bgcolor="transparent";
edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10];
node [fontname=Helvetica,fontsize=10,shape=record,height=0.2,width=0.8];
//
// added 3 non-breaking spaces ( ) after \l line break to shift right (align)
//
Node2 [label="{FClass\n|# m_trackingEnabled\l|+ FClass()\l+ InsertRenderMaterial\l InsertRenderMaterial()\l+ InsertRenderMaterialDelete\l InsertMaterial()\l+ setTrackingEnabled()\l}",
height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
//
// added <BR ALIGN="LEFT"/> to the end of every line segment (seems to apply to preceeding text)
// set html node shape to plain to extend HR to edges
// set cellpadding="1" (just because)
//
Node3 [shape=plain label=<
<TABLE CELLBORDER="0" BORDER="0" CELLPADDING="1" >
<TR><TD COLSPAN="2" CELLPADDING="1" CELLSPACING="0">FClass</TD></TR>
<HR/>
<TR><TD VALIGN="top" CELLPADDING="1" CELLSPACING="0">#</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="1" CELLSPACING="0">m_trackingEnabled</TD></TR>
<HR/>
<TR><TD VALIGN="top" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left" CELLSPACING="0">FClass()</TD></TR>
<TR><TD VALIGN="top" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="LEFT" CELLSPACING="0">InsertRenderMaterial<BR ALIGN="LEFT"/>InsertRenderMaterial()<BR ALIGN="LEFT"/></TD></TR>
<TR><TD VALIGN="top" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left" CELLSPACING="0">InsertRenderMaterialDelete<BR ALIGN="LEFT"/>InsertMaterial()<BR ALIGN="LEFT"/></TD></TR>
<TR><TD VALIGN="top" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left" CELLSPACING="0">setTrackingEnabled()</TD></TR>
</TABLE>
>,height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
}
Giving:
i need to add image to html label, any sugestions how can i do that?
St1_U41 [
shape=plaintext
label=<
<table border='1' cellborder='1'>
//i need image right here
<tr><td colspan="10">St1, U41</td></tr>
<tr><td colspan="10">Huawei</td></tr>
<tr><td port='34'>34</td><td port='36'>36</td><td port='38'>38</td><td port='37'>37</td><td port='40'>40</td><td port='39'>39</td><td port='47'>47</td><td port='48'>48</td><td port='49'>49</td><td port='51'>51</td></tr>
</table>
>];
added a <TD and <IMG (see http://www.graphviz.org/doc/info/shapes.html#images-example)
graph 1 {
St1_U41 [
shape=plaintext
label=<
<table border='1' cellborder='1'>
<tr><td colspan="10"><IMG SRC="HELLO.png"/></td></tr>
<tr><td colspan="10">St1, U41</td></tr>
<tr><td colspan="10">Huawei</td></tr>
<tr><td port='34'>34</td><td port='36'>36</td><td port='38'>38</td><td port='37'>37</td><td port='40'>40</td><td port='39'>39</td><td port='47'>47</td><td port='48'>48</td><td port='49'>49</td><td port='51'>51</td></tr>
</table>
>];
}
Giving:
Using graphviz I want to generate the following graph (manually written in tikz for now):
I currently succeeded in writing a dot file giving me the following result (there is a single node using html for the Pile table on the top, and one node also using html for every grey box):
But unfortunately I was not able to keep the layout of grey boxes that I like AND to have the grey boxes on the right of the Pile table. I read carefully this related question and tried things with rank, subgraphs and rankdir without success.
Is there any hope to reach my goal with dot ?
EDIT: here is the complete dot file I have currently
digraph structs {
node [shape=plaintext]
subgraph stack {
label = STACK;
stack [label=<
<TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0" BGCOLOR="white">
<TR><TD><i>Nom</i></TD><TD><i>Type</i></TD><TD><i>Portée</i></TD><TD><i>Valeur</i></TD></TR>
<TR><TD BGCOLOR="chartreuse">list2</TD><TD BGCOLOR="chartreuse">référence</TD><TD BGCOLOR="chartreuse">main</TD><TD PORT="port_140407657518560" BGCOLOR="chartreuse">0x7f
b334a23ac0</TD></TR>
<TR><TD BGCOLOR="chartreuse">list1</TD><TD BGCOLOR="chartreuse">référence</TD><TD BGCOLOR="chartreuse">main</TD><TD PORT="port_140407657518032" BGCOLOR="chartreuse">0x7f
b334a23ac0</TD></TR>
</TABLE>
>
];
}
subgraph heap {
label = HEAP;
struct_140407658920640 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD COLSPAN="6">0x7fb334a23ac0</TD></TR>
<TR><TD COLSPAN="6"><u>list</u></TD></TR>
<TR><TD PORT="port_child0">0x955e80</TD>
<TD PORT="port_child1">0x956360</TD>
<TD PORT="port_child2">0x956040</TD>
<TD PORT="port_child3">0x7fb3348cbbb0</TD>
<TD PORT="port_child4">0x7fb3348cbc30</TD>
<TD PORT="port_child5">0x7fb3348cbc70</TD>
</TR>
</TABLE>>];
struct_9789056 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x955e80</TD></TR>
<TR><TD><u>int</u></TD></TR>
<TR><TD>3</TD></TR>
</TABLE>>];
struct_140407658920640:port_child0 -> struct_9789056;
struct_9790304 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x956360</TD></TR>
<TR><TD><u>int</u></TD></TR>
<TR><TD>42</TD></TR>
</TABLE>>];
struct_140407658920640:port_child1 -> struct_9790304;
struct_9789504 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x956040</TD></TR>
<TR><TD><u>int</u></TD></TR>
<TR><TD>17</TD></TR>
</TABLE>>];
struct_140407658920640:port_child2 -> struct_9789504;
struct_140407657511856 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x7fb3348cbbb0</TD></TR>
<TR><TD><u>str</u></TD></TR>
<TR><TD>"go"</TD></TR>
</TABLE>>];
struct_140407658920640:port_child3 -> struct_140407657511856;
struct_140407657511984 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x7fb3348cbc30</TD></TR>
<TR><TD><u>str</u></TD></TR>
<TR><TD>"feu"</TD></TR>
</TABLE>>];
struct_140407658920640:port_child4 -> struct_140407657511984;
struct_140407657512048 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x7fb3348cbc70</TD></TR>
<TR><TD><u>str</u></TD></TR>
<TR><TD>"partez"</TD></TR>
</TABLE>>];
struct_140407658920640:port_child5 -> struct_140407657512048;
}
stack:port_140407657518560 -> struct_140407658920640;
stack:port_140407657518032 -> struct_140407658920640;
}
Minor changes
changed subgraphs to clusters (see https://www.graphviz.org/pdf/dotguide.pdf)
added invisible edge to drive cluster positioning
digraph structs {
node [shape=plaintext]
subgraph cluster_stack { // changed to cluster
graph [peripheries=0] // no box around this cluster
label = STACK;
stack [label=<
<TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0" BGCOLOR="white">
<TR><TD><i>Nom</i></TD><TD><i>Type</i></TD><TD><i>Porté?e</i></TD><TD><i>Valeur</i></TD></TR>
<TR><TD BGCOLOR="chartreuse">list2</TD><TD BGCOLOR="chartreuse">ré?fé?rence</TD><TD BGCOLOR="chartreuse">main</TD><TD PORT="port_140407657518560" BGCOLOR="chartreuse">0x7f
b334a23ac0</TD></TR>
<TR><TD BGCOLOR="chartreuse">list1</TD><TD BGCOLOR="chartreuse">ré?fé?rence</TD><TD BGCOLOR="chartreuse">main</TD><TD PORT="port_140407657518032" BGCOLOR="chartreuse">0x7f
b334a23ac0</TD></TR>
</TABLE>
>
];
}
subgraph cluster_heap { // changed to cluster
label = HEAP;
struct_140407658920640 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD COLSPAN="6">0x7fb334a23ac0</TD></TR>
<TR><TD COLSPAN="6" port="myport"><u>list</u></TD></TR>
<TR><TD PORT="port_child0">0x955e80</TD>
<TD PORT="port_child1">0x956360</TD>
<TD PORT="port_child2">0x956040</TD>
<TD PORT="port_child3">0x7fb3348cbbb0</TD>
<TD PORT="port_child4">0x7fb3348cbc30</TD>
<TD PORT="port_child5">0x7fb3348cbc70</TD>
</TR>
</TABLE>>];
struct_9789056 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x955e80</TD></TR>
<TR><TD><u>int</u></TD></TR>
<TR><TD>3</TD></TR>
</TABLE>>];
struct_140407658920640:port_child0 -> struct_9789056;
struct_9790304 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x956360</TD></TR>
<TR><TD><u>int</u></TD></TR>
<TR><TD>42</TD></TR>
</TABLE>>];
struct_140407658920640:port_child1 -> struct_9790304;
struct_9789504 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x956040</TD></TR>
<TR><TD><u>int</u></TD></TR>
<TR><TD>17</TD></TR>
</TABLE>>];
struct_140407658920640:port_child2 -> struct_9789504;
struct_140407657511856 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x7fb3348cbbb0</TD></TR>
<TR><TD><u>str</u></TD></TR>
<TR><TD>"go"</TD></TR>
</TABLE>>];
struct_140407658920640:port_child3 -> struct_140407657511856;
struct_140407657511984 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x7fb3348cbc30</TD></TR>
<TR><TD><u>str</u></TD></TR>
<TR><TD>"feu"</TD></TR>
</TABLE>>];
struct_140407658920640:port_child4 -> struct_140407657511984;
struct_140407657512048 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR><TD>0x7fb3348cbc70</TD></TR>
<TR><TD><u>str</u></TD></TR>
<TR><TD>"partez"</TD></TR>
</TABLE>>];
struct_140407658920640:port_child5 -> struct_140407657512048;
}
edge [constraint=false] // do not use next two edges to position nodes/clusters
stack:port_140407657518560 -> struct_140407658920640:myport
stack:port_140407657518032 -> struct_140407658920640
// add invisible edge & use to position nodes/clusters
edge [constraint=true style=invis]
stack:port_140407657518032 -> struct_9789056
}
Giving:
I have this input:
graph {
"1" -- "11"
"11" -- "111"
"1" -- "12"
"12" -- "121"
"12" -- "122"
}
Which will produce this graph
Is it possible to add labels to the left and right side of nodes so the output will be something like this?
No need to use strictly graphviz/DOT
It is possible with a little graphviz "hack" using labels of edges from and to the same node, but hiding the edge (penwidth=0):
graph {
edge [penwidth=0];
"1":w -- "1":w [taillabel="1"]
"1":e -- "1":e [taillabel="12"]
"11":n -- "11":w [taillabel="21"] // north - west
"11":e -- "11":e [taillabel="21"]
"12":w -- "12":w [taillabel="1"]
"12":e -- "12":e [taillabel="6"]
"111":w -- "111":w [taillabel="1"]
"111":e -- "111":e [taillabel="6"]
"121":w -- "121":w [taillabel="1"]
"121":e -- "121":e [taillabel="6"]
"122":w -- "122":w [taillabel="1"]
"122":e -- "122":e [taillabel="6"]
edge [penwidth=1];
"1" -- "11"
"11" -- "111"
"1" -- "12"
"12" -- "121"
"12" -- "122"
}
If you are flexible as to node shape, here is a solution using html-like nodes https://www.graphviz.org/doc/info/shapes.html#html. A little verbose, but easy to produce programmatically.
graph {
graph [splines=false]
node [shape=plaintext]
N1 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD BORDER="0">1</TD><TD PORT="p1">1</TD><TD BORDER="0">12</TD>
</TR>
</TABLE>>];
N2 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD BORDER="0">21</TD><TD PORT="p2">11</TD><TD BORDER="0">21</TD>
</TR>
</TABLE>>];
N3 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD BORDER="0">1</TD><TD PORT="p3">12</TD><TD BORDER="0">6</TD>
</TR>
</TABLE>>];
N4 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD BORDER="0">1</TD><TD PORT="p4">11</TD><TD BORDER="0">6</TD>
</TR>
</TABLE>>];
N5 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD BORDER="0">1</TD><TD PORT="p5">121</TD><TD BORDER="0">6</TD>
</TR>
</TABLE>>];
N6 [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD BORDER="0">1</TD><TD PORT="p6">122</TD><TD BORDER="0">6</TD>
</TR>
</TABLE>>];
N1:p1--N2:p2
N1:p1--N3:p3
N2:p2--N4:p4
N3:p3--N5:p5
N3:p3--N6:p6
}
Giving:
I'm using a record node in graphviz to make a simple table, but it looks wrong:
digraph g {
node [shape = record,height=.08];
node1[label = "{DBAT|{ 0|1|2|3|4|5|6|7}|{8|9|10|11|12|13|14|15}|...|{248|249|250|251|252|253|254|255}}"];
}
Is there any way to get the subrecords to line up?
HTML-formatted nodes will probably make this easier. See http://www.graphviz.org/doc/info/shapes.html#html for details. Tables are supported.
In your case, it's impossible to do with only record labels, you should try HTML-like syntax.
https://graphviz.org/doc/info/shapes.html#html
Online Editor
digraph g {
node2[shape="none" label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="6" COLUMNS="*">
<TR><TD COLSPAN="8">DBAT</TD></TR>
<TR>
<TD>0</TD>
<TD>1</TD>
<TD>2</TD>
<TD>3</TD>
<TD>4</TD>
<TD>5</TD>
<TD>6</TD>
<TD>7</TD>
</TR>
<TR>
<TD>8</TD>
<TD>9</TD>
<TD>10</TD>
<TD>11</TD>
<TD>12</TD>
<TD>13</TD>
<TD>14</TD>
<TD>15</TD>
</TR>
<TR><TD COLSPAN="8">...</TD></TR>
<TR>
<TD>248</TD>
<TD>249</TD>
<TD>250</TD>
<TD>251</TD>
<TD>252</TD>
<TD>253</TD>
<TD>254</TD>
<TD>255</TD>
</TR>
</TABLE>>];
}