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:
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 know there's \l for left aligned line breaks and also <I></I> for italic text in HTML labels, but how would I make left aligned italic labels?
Those escape strings for alignment seem to work only in regular labels. However, when using HTML-based strings for node labels, you may use the align attribute.
The following example shows the use of align for table cells td and within the text of a table cell using line breaks br:
digraph G {
n[shape=rect, label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD colspan="3">Very very wide text in the first line</TD></TR>
<TR>
<TD width="1" align="left"><i>one</i></TD>
<TD width="1" align="center">two</TD>
<TD width="1" align="right">three</TD>
</TR>
<TR><TD colspan="3">More wide text without meaning
<br/>
<i>four</i>
<br align="right" />
<i>five</i>
<br align="left" />
</TD>
</TR>
</TABLE>
>]
}
In case you're looking for a simple solution and aren't into HTML-like labels, and the entire label has to be italic, then you may also use an italic font:
graph {
n[width=2, label="left\l", fontname="times-italic"]
}
Your fontname may vary, depending on your system (see also fontname)
I could not figure out looking at the Graphviz docs if there is a way to specify different labels for each wedge in a circle with style=wedged. e.g. below node draws a circle divided into 3 wedges with three colors.
nodepie [shape = "circle" style = "wedged" fillcolor = "green:red:yellow"];
I want to put different numbers on each wedge.
Could anybody help?
Thanks for your help.
Sorry, but I don't think this is possible; I've tried before. Even using weird combinations of html labels I wasn't able to get a satisfactory result. There's nothing in the label documentation that even hints at a method for achieving this.
Sorry I don't have a more positive answer for you, but in the case I think it's "no." As you can see, alignment is a mess; it might be feasible if the pie had four wedges and the html label could be superimposed on top, two rows and two columns. But with three it's hard to imagine a layout that would delight:
digraph x{
nodepie [shape = "circle" style = "wedged" fillcolor = "green:red:yellow"
label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR><TD PORT="f0">one</TD><TD>two</TD></TR> </TABLE>>];
}
Workaround for three wedgets (of approximately same size);
digraph x{
nodepie [shape = "circle" style = "wedged" fillcolor = "green:red:yellow"
label=<
<TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0">
<TR>
<TD PORT="f0" ROWSPAN="2">one</TD>
<TD ROWSPAN="2"> </TD>
<TD>two</TD>
</TR>
<TR>
<TD PORT="f0">tree</TD>
</TR>
</TABLE>
>];
}
If you create a html-table with elements using the same colors as the WEDGE, you can have your labels next to the pie.
digraph structs {
p01 [shape = none
label = <<table border="0" cellspacing="0">
<tr><td bgcolor="blue">P01</td></tr>
<tr><td bgcolor="red">P02</td></tr>
<tr><td bgcolor="yellow">P03</td></tr>
<tr><td bgcolor="green">P04</td></tr>
</table>>]
node [shape=circle]
pie [label="wedged"
style=wedged
color=none
fillcolor="blue;0.4:red;0.1:yellow;0.2:green"
fontcolor=pink]
}
Result:
I am trying to achieve following matrix kind of layout:
TABLE1,1 TABLE1,2
CHART2,1 TABLE2,2
TABLE3 --> occupies whole row
CHART4 --> ocupies whole row
CHART5,1 CHART5,2
................. List goes on...
These components may span over multiple pages. What is the best way to have them side by side and still be able to view them in MigraDoc.
CHART5,1 could be a combination of 4 charts in one cell.
In HTML view I can use following analogy:
<TABLE>
<TR>
<TD>TABLE1,1</TD> <TD>TABLE1,2 </TD>
</TR>
<TR>
<TD>CHART2,1</TD> <TD>TABLE2,2 </TD>
</TR>
<TR>
<TD>TABLE3</TD colspan =2>
</TR>
<TR>
<TD>CHART4</TD colspan =2>
</TR>
<TR>
<TD>CHART5,1</TD> <TD>CHART5,2 </TD>
</TR>
</TABLE>
The MigraDoc equivalent for colspan=2 is MergeRight=1. This is a property of the Cell class.
Looking for a xpath node whose table row must fulfill several conditions
Searching for those node "col_functions" whose table row values is "John Wayne" from the table #class="table_list".
("col_functions", "col_firstname" and "col_lastname are sibling nodes and childs from the table)
<table class="table_list">
<tbody>
<tr>
<td class="col_firstname">John</td>
<td class="col_lastname">Lennon</td>
<td class="col_functions"></td>
</tr>
<tr>
<td class="col_firstname">John</td>
<td class="col_lastname">Wayne</td>
<td class="col_functions"></td> <=== looking for this node!!
</tr>
<tr>
<td class="col_firstname">Wayne</td>
<td class="col_lastname">John</td>
<td class="col_functions"></td>
</tr>
</tbody>
<table>
One option would be to check for class names all over the place:
//table[#class="table_list"]//tr[td[#class="col_firstname"] = "John" and td[#class="col_lastname"] = "Wayne"]/td[#class="col_functions"]/text()
Here we are basically checking all rows inside the table for cells with first name John and last name Wayne, getting the cell with col_functions as an output.
Using siblings it will be like that:
//table[#class='table_list']//td[#class='col_firstname'][text()='John']/following-sibling::td[#class='col_lastname'][text=()'Wayne']/following-sibling::td[#class='col_functions']