Draw text in corners with graphviz - graphviz

I have a very simple graph:
digraph {
node [shape=rect];
rankdir=LR;
A -> B
}
It outputs as I expect:
However, I need to place unique numbers in each corner of both A and B. I am currently only aware of xlabel, but from what I gather can only be used once and cannot be specified in a particular region. So how can I accomplish writing numbers in each corner?

Newest versions of Graphviz support HTML styling of nodes, including tables ("newer than mid-November 2003", that is). So you can make a 3x3 table like this:
Source:
digraph {
node [shape=rect];
rankdir=LR;
A [shape=none label=<
<TABLE BORDER="0" CELLBORDER="0">
<TR><TD>1</TD><TD></TD><TD>2</TD></TR>
<TR><TD COLSPAN="3" BORDER="1">A</TD></TR>
<TR><TD>3</TD><TD></TD><TD>4</TD></TR>
</TABLE>
>];
A -> B
}
Tested with http://sandbox.kidstrythisathome.com/erdos/; it also works with my local installed version (2.38.0).
See Graphviz: Node Shapes for the full set of supported HTML, and examples.

Related

Half-circle graphviz nodes

Is it possible to have graphviz/dot render a node as a circle that is split in the middle horizontally, with a top and bottom text content? Something like a record, but the final shape should be a circle. Currently I'm using Mrecord, but that's only a rounded rectangle, not a circle shape.
I searched for ways to increase the border radius of Mrecord (to make it a quasi-circle) but that did not work. I also tried Mcircle, which is not what I was looking for.
Not directly, but you can create a circle-shaped node, divided in half with the wedged attribute and in the HTML-like label write a HTML <TABLE> without borders which will place text on top of the node.
Script:
digraph {
nodepie [shape = "circle"
style = "wedged"
fillcolor="white;0.5:white"
label=<<TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0">
<TR>
<TD>one</TD>
</TR>
<TR>
<TD>two</TD>
</TR>
</TABLE>>];
}
Result:
Not directly, but you can create an image (svg, png, ...) that looks exactly like you want, using any drawing program, & then include that image in your Graphviz graph.

Add image or text to border of rectangle or cluster - graphviz

I have a code that allows me to perform a cluster. i want to move the label to the border of the cluster in the output. I have tried labelloc=l and other options but i am unable to make it work. attached is the one i got from graphviz while the other one is what i was expecting. is there a way to modify the code, add plugin or gvpr to get the desired output?
digraph AlignmentMap {
/*
/*
Author: Lars Barkman
Created: 2015-08-25
Changelog: See version control system
This is an example of an Alignment Map visualized with the help of Graphviz.
This solution depends on either generation or maintaining a .dot file and from that generating a image or document.
Personally, I think that editing the file by hand should be fine if the naming conventions used are intuitive.
Alignment maps first came to my attention on Martin Fowlers blog (http://martinfowler.com/bliki/AlignmentMap.html).
*/
// General layout of the graph
rankdir=LR; // Direction of the graph Left to Right
node [style="rounded,filled",color=black,shape=box,fillcolor=white]; // Defines the default layout of the nodes
graph [style=filled, splines=line]; // Fills the subgraphs and defines the layout of the connections
rank = same; // Makes sure that nodes are properly aligned even without a connection
// Column for Business Outcomes
subgraph cluster_business_outcome {
label="Business Outcomes"
graph [color=pink];
business_outcome_Customer_Acquisition [label="Customer\nAcquisition"];
business_outcome_Customer_Retention [label="Customer\nRetention"];
business_outcome_Cost_of_Operations [label="Cost of\nOperations"];
}
// Column for IT Outcomes
subgraph cluster_IT_outcome {
label=< <table>
<tr><td fixedsize="true" width="50" height="50"><img src="./Azure-PlantUML-master/dist/Identity/AzureActiveDirectory.svg" /></td></tr>
<tr><td>Active Directory</td></tr>
</table>
>
graph [color=mistyrose2];
IT_outcome_Platform_Unbundling [label="Platform\nUnbundling"];
IT_outcome_Site_Ux [label="Site Ux"];
IT_outcome_Site_Performance [label="Site\nPerformance"];
IT_outcome_Site_Scalability [label="Site\nScalability"];
}
// Column for IT Initiatives
subgraph cluster_IT_initiatives {
label="IT Initiatives"
graph [color=papayawhip];
IT_initiatives_API [label="API"];
IT_initiatives_Pluginize [label="Pluginize"];
IT_initiatives_Responsive_Rewrite [label="Responsive\nRewrite"];
IT_initiatives_Catalog_Performance [label="Catalog\nPerformance"];
IT_initiatives_Sharding [label="Sharding"];
}
// Column for Action Items
subgraph cluster_action_items {
label="Action Items"
graph [color=darkseagreen1];
action_items_0 [label="..."];
action_items_1 [label="..."];
action_items_App_X [label="App X"];
action_items_Search_In_One [label="Search-\nIn-One"];
action_items_4 [label="..."];
}
// Connections between nodes in the different columns
// business_outcome_* -> IT_outcome_Platform_*
business_outcome_Customer_Acquisition -> IT_outcome_Platform_Unbundling;
business_outcome_Customer_Acquisition -> IT_outcome_Site_Ux;
business_outcome_Customer_Retention -> IT_outcome_Site_Ux;
business_outcome_Customer_Retention -> IT_outcome_Site_Performance;
business_outcome_Cost_of_Operations -> IT_outcome_Site_Performance;
business_outcome_Cost_of_Operations -> IT_outcome_Site_Scalability;
// IT_outcome_* -> IT_initiatives_*
IT_outcome_Platform_Unbundling -> IT_initiatives_API;
IT_outcome_Platform_Unbundling -> IT_initiatives_Pluginize;
IT_outcome_Site_Ux -> IT_initiatives_Responsive_Rewrite;
IT_outcome_Site_Performance -> IT_initiatives_Catalog_Performance;
IT_outcome_Site_Scalability -> IT_initiatives_Sharding;
// IT_initiatives_* -> action_items_*
IT_initiatives_API -> action_items_0;
IT_initiatives_Pluginize -> action_items_1;
IT_initiatives_Responsive_Rewrite -> action_items_App_X;
IT_initiatives_Catalog_Performance -> action_items_Search_In_One;
IT_initiatives_Sharding -> action_items_4;
}
The one on right is graphviz and left is what i expect
(sorry, I misunderstood the request)
Here is a gvpr "fix".
run dot -Tdot to position the nodes, edges, clusters
run that result through gvpr (program below) to remove the label and replace it with a (new) node
run that (modified) result through neato -n2 -Tsvg (see https://graphviz.org/faq/#FaqDottyWithCoords)
[note that I had to tweak the html to remove borders:]
label=< <table BGCOLOR="transparent" BORDER="0" CELLBORDER="0" CELLSPACING="0">
<tr><td fixedsize="true" width="50" height="50"><img src="image_dir/Face-smile.svg" /></td></tr>
<tr><td>Active Directory</td></tr>
</table>
>
commandline:
dot -Tdot myfile.gv|gvpr -c -f moveLabel.gvpr | neato -n2 -Tsvg >myfile.svg
moveLable.gvpr:
BEGIN{
string saveLbl, saveX, saveY, workS;
graph_t theG;
node_t newNode;
}
BEG_G{
print("// ONE");
theG=subg($G, "cluster_IT_outcome");
saveLbl=theG.label;
// next 3 steps get the left X coordinate of the cluster
workS=llOf(theG.bb);
workS=xOf(workS);
saveX=(float)workS;
// now get Y coordinate of label
workS=yOf(theG.lp);
saveY=(float)workS;
theG.label=""; // remove label from cluster
}
END_G{
// create new node to replace cluster label
newNode=node($G, "__myNewNode");
newNode.pos=sprintf("%.2f,%.2f", saveX, saveY);
newNode.shape="plain";
newNode.fillcolor="none";
newNode.label=html($G, saveLbl);
}

invisible edges layout issues

I have a dense dot graph with many edges and a node that has connections to nearly any other node.
For example:
digraph TEST
{
rankdir=LR;
node [shape=plaintext];
graph [compound=true];
A[label=<<table border="0" cellspacing="0" cellborder="1" >
<tr><td >A</td></tr>
<tr><td port='a1'>a1</td></tr>
<tr><td port='a2'>a2</td></tr>
</table>>];
B;
C;
D;
E;
F;
G;
H;
I;
A:a1:e->B:w;
A:a1:e->C:w;
A:a1:e->D:w;
A:a1:e->E:w;
A:a1:e->F:w;
A:a1:e->G:w;
A:a1:e->H:w;
A:a1:e->I:w;
A:a2:e->B:w;
B:e->C:w;
C:e->D:w;
D:e->E:w;
E:e->F:w;
E:e->G:w;
E:e->H:w;
F:e->I:w
G:e->I:w
H:e->I:w
}
I would like to hide the a1 connections and add some kind of jump labels to keep the information available for the reader.
E.g.:
A:a1:e->{a1_out[label="a1"]};
{a1_Bin[label="a1"]}->B:w;
{a1_Cin[label="a1"]}->C:w;
{a1_Din[label="a1"]}->D:w;
{a1_Ein[label="a1"]}->E:w;
{a1_Fin[label="a1"]}->F:w;
{a1_Gin[label="a1"]}->G:w;
{a1_Hin[label="a1"]}->H:w;
{a1_Iin[label="a1"]}->I:w;
Adding the attribute [style=invis] to the a1-connections just does not render them, but keeps the layout as it would be with them. with the result that the placement of the nodes and labels looks strange because of empty spaces and dense connections in other places.
Removing the connections completely does change the semantics of the graph and the ranks of the graph nodes (not in this example but it will in other ones).
So I am looking for a way to provide dot the information to correctly calculating all the dependencies between the nodes on the one side and to advise it, not to draw render and draw these connections on the other side.
An approach to clean up the edges in such a graph could be to use
concentrate=true
According to the documentation, this will
... merge multiedges into a single edge and cause partially parallel
edges to share part of their paths

graphviz: Arrow "through" boxes, not "from - to" box

I would like to have arrows go "through" a box, not from box to box. Is there a way to accomplish this (see below) in graphviz?
(Why am I asking: I have some data flow diagrams where multiple outputs from an entity are going through the same entity to be passed to the last entity, and the graphviz output looks like this:
eg., I find this not nice and not recognizable.)
This doesn't exist in graphviz.
How about simply omitting the arrow heads in the edges from A/B to C ?
digraph G {
node[shape=box];
{A;B} -> C [arrowhead=none];
C -> D;
C -> D;
}
Edit: unless, you really want to do that ...
... then you could use HTML-like labels for the node which should have edges crossing through, define ports within the label to attach edges to (in this case, "ww" and "ee"), and have an edge going to the port without an arrow head, as well as an edge leaving from the port with an arrow head, creating the illusion of a single arrow crossing through the port (which isn't visible as such).
digraph G {
node[shape=box];
C[label=<
<TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD port="ww"></TD>
<TD></TD>
<TD port="ee"></TD>
</TR>
<TR>
<TD></TD>
<TD CELLPADDING="5">C</TD>
<TD></TD>
</TR>
</TABLE>
>];
A -> C:ww:n [arrowhead=none];
B -> C:ee:n [arrowhead=none];
C:ww:s -> D;
C:ee:s -> D;
}
In order to have nices arrow curves, I also defined compass points for the edges - compass points are n/e/s/w and determine from which side an edge is supposed to enter/leave.

Graphviz - how to constrain edges to only connecting to east or west faces of a node?

I am pretty new to Graphviz and needing to try to constrain connections to only the left or right (or east or west) faces of a node. So far my DOT scripting efforts result in the output shown in attached image.
Any suggestions most appreciated.
Using ports (https://www.graphviz.org/doc/info/attrs.html#k:portPos) will probably solve this problem.
digraph i{
t [shape=plaintext,label=<
<TABLE CELLSPACING="2" CELLPADDING="2" BORDER="1">
<TR><TD PORT="one_l">one left</TD><TD PORT="one_r">one right</TD></TR>
<TR><TD PORT="l2">one left</TD><TD PORT="xyz">one right</TD></TR>
</TABLE>
>
]
x -> t:one_l:w
t:xyz:e -> XX
}
Giving:

Resources