Please consider the following code:
digraph G {
node [shape=plaintext]
a [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD ID="first" BGCOLOR="gray">first</TD></TR>
<TR><TD ID="second" PORT="f1">second</TD></TR>
<TR><TD ID="third" PORT="f2">third</TD></TR>
</TABLE>>];
b [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD ID="first" BGCOLOR="gray">first</TD></TR>
<TR><TD ID="second" PORT="f1">second</TD></TR>
<TR><TD ID="third" PORT="f2">third</TD></TR>
</TABLE>>];
a:first -> b:first;
}
I get a fair amount of warnings:
laci#nitehawk ~ $ dot records.gv -T pdf > records.pdf
Warning: Illegal attribute ID in <TD> - ignored
Warning: Illegal attribute ID in <TD> - ignored
Warning: Illegal attribute ID in <TD> - ignored
in label of node a
Warning: Illegal attribute ID in <TD> - ignored
Warning: Illegal attribute ID in <TD> - ignored
Warning: Illegal attribute ID in <TD> - ignored
in label of node b
Warning: node a, port first unrecognized
Warning: node b, port first unrecognized
According to the documentation the ID attribute of TD should be legal. What am I missing?
How can I reference individual cells and create edges between them?
For completeness sake here's the full source that actually works:
digraph G {
node [shape=plaintext]
a [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="c" BGCOLOR="gray">first</TD></TR>
<TR><TD PORT="d">second</TD></TR>
<TR><TD PORT="e">third</TD></TR>
</TABLE>>];
b [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="c" BGCOLOR="gray">first</TD></TR>
<TR><TD PORT="d">second</TD></TR>
<TR><TD PORT="e">third</TD></TR>
</TABLE>>];
a:c -> b:c;
}
You can simply use PORT instead of ID and then use the edge definition as in your example.
<TD PORT="first" BGCOLOR="gray">first</TD>
ID's purpose is downstream use, so unless you're using SVG output and reuse the id's elsewhere, they are probably not really useful.
As to the warnings, I do not get them with graphviz 2.28. If you use an older version of graphviz, I suggest to update.
Related
Is there any way to create a node in Graphviz that looks like the below?
(Placing a hexagon and text side by side inside the node instead of just placing text inside box)
You can't easily embed nodes within other nodes, but you can insert images into nodes. Create an image (or images) with the polygon shape(s) and insert them into an HTML-style node (record-style would probably also work).
Like so:
digraph i{
{rank=same
n1 [shape=plaintext,label=<
<TABLE CELLSPACING="0" CELLPADDING="0" BORDER="1" cellborder="0">
<TR><TD FIXEDSIZE="true" height="20" width="20"><IMG SRC="cow.png" scale="true"/></TD><TD>some text</TD></TR>
</TABLE>
>
]
n2 [shape=plaintext,label=<
<TABLE CELLSPACING="0" CELLPADDING="0" BORDER="1" cellborder="0" >
<TR><TD colspan="2" bgcolor="green1">Step</TD></TR>
<TR><TD FIXEDSIZE="true" height="20" width="20"><IMG SRC="cow.png" scale="true"/></TD><TD>some text</TD></TR>
</TABLE>
>
]
n1 -> n2
}
}
Giving:
I'm wondering if it's possible to create something like this usint graphviz, where an arrow points from a token/word to the other, instead of a node.
It is possible to simulate (a lot of things) with tables, though it's usually very ugly in source code:
digraph {
node [shape=plain]
node1 [
label=<
<table cellspacing="0" bgcolor="#d0e2f2" cellborder="0">
<tr><td></td></tr>
<tr><td port="label">foo bar</td></tr>
<tr><td></td></tr>
</table>>
]
node2 [
label=<
<table cellspacing="0" bgcolor="#d0e2f2" cellborder="0">
<tr><td></td></tr>
<tr><td port="label">baz qux</td></tr>
<tr><td></td></tr>
</table>>
]
node1:label:n -> node2:label:n [constraint=false]
}
Result:
What I did here:
I used a plain node shape and HTML-like label syntax to create a table:
node [shape=plain]
node1 [
label=<>
]
I added 3 rows for my table, first and last one being empty:
<tr><td></td></tr>
<tr><td port="label">foo bar</td></tr>
<tr><td></td></tr>
The middle row contains the actual label. Also, to be able to point an edge to specific cell I've added a port to it: <td port="label">foo bar</td>.
Finally when defining an edge I've specified the ports to be connected (documentation on ports):
node1:label:n -> node2:label:n
I'm trying to use dot notation and set the order of the items. in the example below I would like FLIP/FLOPA to be on top and FLIP/FLOPB on the bottom. It would also be good to line everything up.
I'm a bit confused how invisible edges might work?
this is where im at:
digraph G {
graph [pad ="1", rankdir = LR, splines=ortho];
size = "16.66,8.33!"; // 1200x600 at 72px/in, "!" to force
ratio = "fill";
node[shape=record];
flipa[label="FLIPA", height=3];
flopa[label="FLOPA", height=3];
flipb[label="FLIPB", height=3];
flopb[label="FLOPB", height=3];
source1[shape=rarrow];
source2[shape=rarrow];
sink1[shape=rarrow];
sink2[shape=rarrow];
source1 -> flipa;
flipa -> flopa [label="red" color=red,penwidth=3.0];
flipa -> flopa [label="blue" color=blue,penwidth=3.0];
flopa -> sink1;
source2 -> flipb;
flipb -> flopb [label="red" color=red,penwidth=3.0];
flipb -> flopb [label="blue" color=blue,penwidth=3.0];
flopb -> sink2;
label="Graph";
labelloc=top;
labeljust=left;
}
Thanks in advance
Neil
The order in which you mention nodes in layout is important.
If you have horizontal layout (rankdir=LR), the nodes appear in your layout from bottom to top, look at this, for example:
digraph {
rankdir=LR
node1
node2
node3
}
This results in:
Now if we reverse the order:
digraph {
rankdir=LR
node3
node2
node1
}
We get this:
PS: I don't recommend using ortho splines, they may cause all sorts of artifacts, including very poor handling of edge labels. You problems with lining up may be caused by them. Even though when I compile your code on my machine, the nodes are lined up correctly.
To answer your question in the comments:
How to implement parallel edges without splines=ortho
But let me warn you, it is very ugly.
In graphviz you can use HTML-like syntax to define some structures, most important of them being tables. Any old enough frontender will tell you that you can design almost anything using tables. I use them a lot when work with graphviz.
What you can do in your situation: instead of your plain rectangular nodes place a table with three rows. Top row and bottom row are going to be empty. The middle one will contain your label: FLIPA or FLOPA.
Next you assign port attribute to all cells. This way you will be able to connect specific rows of tables together using the headport and tailport (or their synonims, the colon-syntax, which I used in example below).
Here's the example:
digraph G {
graph [pad ="1", rankdir = LR];
size = "16.66,8.33!"; // 1200x600 at 72px/in, "!" to force
ratio = "fill";
node[shape=record];
flipb[
shape=plain
label=<
<table border="1" cellspacing="0" cellborder="0">
<tr>
<td height="80" port="upper"> </td>
</tr>
<tr>
<td height="80" port="middle">FLIPB</td>
</tr>
<tr>
<td height="80" port="bottom"> </td>
</tr>
</table>
>
];
flopb[
shape=plain
label=<
<table border="1" cellspacing="0" cellborder="0">
<tr>
<td height="80" port="upper"> </td>
</tr>
<tr>
<td height="80" port="middle">FLOPB</td>
</tr>
<tr>
<td height="80" port="bottom"> </td>
</tr>
</table>
>
];
flipa[
shape=plain
label=<
<table border="1" cellspacing="0" cellborder="0">
<tr>
<td height="80" port="upper"> </td>
</tr>
<tr>
<td height="80" port="middle">FLIPA</td>
</tr>
<tr>
<td height="80" port="bottom"> </td>
</tr>
</table>
>
];
flopa[
shape=plain
label=<
<table border="1" cellspacing="0" cellborder="0">
<tr>
<td height="80" port="upper"> </td>
</tr>
<tr>
<td height="80" port="middle">FLOPA</td>
</tr>
<tr>
<td height="80" port="bottom"> </td>
</tr>
</table>
>
];
source1[shape=rarrow];
source2[shape=rarrow];
sink1[shape=rarrow];
sink2[shape=rarrow];
source1 -> flipa;
flipa:upper -> flopa:upper [label="red" color=red,penwidth=3.0];
flipa:bottom -> flopa:bottom [label="blue" color=blue,penwidth=3.0];
flopa -> sink1;
source2 -> flipb;
flipb:upper -> flopb:upper [label="red" color=red,penwidth=3.0];
flipb:bottom -> flopb:bottom [label="blue" color=blue,penwidth=3.0];
flopb -> sink2;
label="Graph";
labelloc=top;
labeljust=left;
}
Result:
How can I remove the space between the border of the table and the edge ?
The node seems to have a margin outside of the table.
The definition of the graph in dot:
strict digraph {
rankdir=RL;
node [shape=none, style=filled, fillcolor=aliceblue, fontname=verdana];
Model [shape=none, label=<<table border="0" cellspacing="0">
<tr><td border="1" bgcolor="lightblue">Model</td></tr>
<tr><td border="1" align="left">Name</td></tr>
<tr><td border="1" align="left">Description</td></tr>
<tr><td border="1" align="left">Universe</td></tr>
</table>>];
Universe [shape=none, label=<<table border="0" cellspacing="0">
<tr><td border="1" bgcolor="lightblue">Universe</td></tr>
<tr><td border="1" align="left">Name</td></tr>
<tr><td border="1" align="left">Description</td></tr>
</table>>];
Model -> Universe
}
The resulting png is:
Using graphviz version 2.38.0.
Any comment much appreciated.
Employ the margin keyword:
node [shape=none, style=filled, fillcolor=aliceblue, fontname=verdana, margin=0];
That'll reduce that aliceblue area around the tables to nothing and make the arrows really connect the tables.
I have the following dot sample. I would like to give the first section in each record (the table name) a different background and foreground colour. I can't find any examples of how to do this for a record. Basically I want the table name in the sql query schema diagram to stand out. Can anyone help?
digraph G {
rankdir=LR;
node [shape=record];
corpus_language [label="corpus_language|<id> id\len\l|<name> name\lEnglist\l|<sentence_count> sentence_count\l1027686\l"];
corpus_sentence [label="corpus_sentence|<id> id\l1241798\l|<text> text\lBaseball is a sport\l|<creator_id> creator_id\l10859\l|<created_on> created_on\l2006-11-14 17:58:09.303128\l|<language_id> language_id\len\l|<activity_id> activity_id\l11\l|<score> score\l124\l"];
corpus_language:id -> corpus_sentence:language_id [arrowhead=normal label=language_id];
}
I'm pretty sure that it's not possible. Instead you should use HTML-style labels, that are a more developped form of record nodes. You can define your node using the <table> tag, and set the color using bgcolor="your_color". A list of available colors is available here: http://www.graphviz.org/doc/info/colors.html (you also have a RGBA way of doing it, as described here: http://www.graphviz.org/doc/info/attrs.html#k:color)
With HTML labels, your example becomes as follows:
digraph G
{
rankdir = LR;
node1
[
shape = none
label = <<table border="0" cellspacing="0">
<tr><td port="port1" border="1" bgcolor="red">corpus_language</td></tr>
<tr><td port="port2" border="1">id: en</td></tr>
<tr><td port="port3" border="1">name: Englist</td></tr>
<tr><td port="port4" border="1">sentence_count: 1027686</td></tr>
</table>>
]
node2
[
shape = none
label = <<table border="0" cellspacing="0">
<tr><td port="port1" border="1" bgcolor="blue">corpus_sentence</td></tr>
<tr><td port="port2" border="1">id: 1241798</td></tr>
<tr><td port="port3" border="1">text: Baseball is a sport</td></tr>
<tr><td port="port4" border="1">creator_id: 10859</td></tr>
<tr><td port="port5" border="1">created_on: 2006-11-14 17:58:09.303128</td></tr>
<tr><td port="port6" border="1">language_id: en</td></tr>
<tr><td port="port7" border="1">activity_id: 11</td></tr>
<tr><td port="port8" border="1">score: 124</td></tr>
</table>>
]
node1:port2 -> node2:port6 [label="language_id"]
}
Here is the result: