I’d like to suggest an alternate approach. When creating these types of diagrams, or domain maps, taxonomies, etc. I feel the osage
layout is superior to dot
for this use case. Osage will allow you to nest clusters, control top/bottom/left/right alignment, and control the order of the node placement.
Unfortunately most people don’t know how to use osage
. osage
draws the graph recursively. At each level, there will be a collection of nodes and a collection of cluster subgraphs. The internals of each cluster subgraph are laid out, then the cluster subgraphs and nodes at the current level are positioned relative to each other, treating each cluster subgraph as a node.
The secret is to use packmode
attributes to describe how the clusters should be nested, and sortv
attributes to specify the order in which clusters and nodes should be emitted.
I’m assuming you are trying to create a diagram similar to this one I found through a Google image search:
Source: https://images.app.goo.gl/8Tsu7q3TVb1Qgta88
Using the osage
layout instead of dot
allowed me to create a very similar diagram, with full-width headings which you desire:
The source for the diagram is as follows:
strict digraph "main"
{
layout=osage;
splines=ortho;
pad="0.5,0.5"
node[ shape=rect height=0.75 width=1.25 fixedsize=True fillcolor=White fontname=Arial fontsize=10 style="filled,rounded" penwidth=0.5 label="" ];
edge[ fontname=Arial fontsize=10 arrowsize=0.5 ];
subgraph cluster_1 { packmode=array_rtu4 color=transparent label=""
subgraph cluster_2 { sortv=1000 packmode=array_tu1 label=""
subgraph cluster_3 { sortv=1100 packmode=array_tu1 label=""
plan [ shape=rect height=0.1875 width=5.5 fillcolor=LightYellow penwidth=0.5 fontname=Arial fontsize=10 style="filled" labelloc=top label=<<b>PLAN</b>> ];
}
subgraph cluster_4 { sortv=1200 packmode=array_rtu3 label=""
subgraph cluster_5 { sortv=1210 packmode=array_rtru1 label=""
4 [ shape=rect height=0.75 width=1.75 fillcolor=LightYellow penwidth=0.5 fontname=Arial fontsize=10 style="rounded,filled" labelloc=top pad="0.25,0.25" sortv=0 label=<<u><b>Clause 4</b></u><br/><br/>Context of the <br/>organization> ];
4.1 [ sortv=1 label="4.1 Understanding\nthe organization\nand its context" ];
4.2 [ sortv=2 label="4.2 Understanding\nthe needs and\nexpectations\nof interested parties" ];
4.3 [ sortv=3 label="4.3 Determining the\nscope of the QMS" ];
4.4 [ sortv=4 label="4.4 Quality\nmanagement\nsystem & its\nprocesses" ];
}
subgraph cluster_6 { sortv=1220 packmode=array_rtu1 label=""
5 [ shape=rect height=0.75 width=1.75 fillcolor=LightYellow penwidth=0.5 fontname=Arial fontsize=10 style="rounded,filled" labelloc=top pad="0.25,0.25" sortv=0 label=<<u><b>Clause 5</b></u><br/><br/>Leadership> ];
5.1 [ sortv=1 label="5.1 Leadership and\ncommitment" ];
5.2 [ sortv=2 label="5.2 Quality Policy" ];
5.3 [ sortv=3 label="5.3 Organizational\nroles,\nresponsibilities and\nauthorities" ];
}
subgraph cluster_7 { sortv=1230 packmode=array_rtu1 label=""
6 [ shape=rect height=0.75 width=1.75 fillcolor=LightYellow penwidth=0.5 fontname=Arial fontsize=10 style="rounded,filled" labelloc=top pad="0.25,0.25" sortv=0 label=<<u><b>Clause 6</b></u><br/><br/>Planning> ];
6.1 [ sortv=1 label="6.1 Actions to\naddress risks and\nopportunities" ];
6.2 [ sortv=2 label="6.2 Quality\nobjectives and\nplanning to achieve\nthem" ];
6.3 [ sortv=3 label="6.3 Planning of\nchanges" ];
}
}
}
subgraph cluster_8 { sortv=2000 packmode=array_tu1 label=""
subgraph cluster_9 { sortv=2100 packmode=array_tu1 label=""
do [ shape=rect height=0.1875 width=3.55 fillcolor=LightGreen penwidth=0.5 fontname=Arial fontsize=10 style="filled" labelloc=top label=<<b>DO</b>> ];
}
subgraph cluster_10 { sortv=2200 packmode=array_rtu2 label=""
subgraph cluster_11 { sortv=2210 packmode=array_rtu1 label=""
7 [ shape=rect height=0.75 width=1.75 fillcolor=LightGreen penwidth=0.5 fontname=Arial fontsize=10 style="rounded,filled" labelloc=top pad="0.25,0.25" sortv=0 label=<<u><b>Clause 7</b></u><br/><br/>Support> ];
7.1 [ sortv=1 label="7.1 Resources" ];
7.2 [ sortv=2 label="7.2 Competence" ];
7.3 [ sortv=3 label="7.3 Awareness" ];
7.4 [ sortv=4 label="7.4 Communication" ];
7.5 [ sortv=5 label="7.5 Documented\nInformation" ];
}
subgraph cluster_12 { sortv=2220 packmode=array_rtu1 label=""
8 [ shape=rect height=0.75 width=1.75 fillcolor=LightGreen penwidth=0.5 fontname=Arial fontsize=10 style="rounded,filled" labelloc=top pad="0.25,0.25" label=<<u><b>Clause 8</b></u><br/><br/>Operation> ];
8.1 [ sortv=1 label="8.1 Operational\nplanning and\ncontrol" ];
8.2 [ sortv=2 label="8.2 Requirements\nfor products &\nservices" ];
8.3 [ sortv=3 label="8.3 Design & \nDevelopment of\nproducts & services" ];
8.4 [ sortv=4 label="8.4 Control of\nexternally provided\nprocesses, products\nand services" ];
8.5 [ sortv=5 label="8.5 Production and\nservice provision" ];
8.6 [ sortv=6 label="8.6 Release of\nproducts and\nservices" ];
8.7 [ sortv=7 label="8.7 Control of\nnonconformity\nproducts" ];
}
}
}
subgraph cluster_13 { sortv=3000 packmode=array_rtu1 label=""
subgraph cluster_14 { sortv=3100 packmode=array_rtu1 label=""
check [ shape=rect height=0.1875 width=1.75 fillcolor=LightBlue penwidth=0.5 fontname=Arial fontsize=10 style="filled" labelloc=top label=<<b>CHECK</b>> ];
}
subgraph cluster_15 { sortv=3200 packmode=array_rtu1 label=""
subgraph cluster_16 { sortv=3210 packmode=array_rtu1 label=""
9 [ shape=rect height=0.75 width=1.75 fillcolor=LightBlue penwidth=0.5 fontname=Arial fontsize=10 style="rounded,filled" labelloc=top pad="0.25,0.25" sortv=0 label=<<u><b>Clause 9</b></u><br/><br/>Performance<br/>Evaluation> ];
9.1 [ sortv=1 label="9.1 Monitoring,\nmeasurement,\nanalysis and\nevaluation" ];
9.2 [ sortv=2 label="9.2 Internal Audit" ];
9.3 [ sortv=3 label="9.3 Management\nReview" ];
}
}
}
subgraph cluster_17 { sortv=4000 packmode=array_rtu1 label=""
subgraph cluster_18 { sortv=4100 packmode=array_rtu1 label=""
act [ shape=rect height=0.1875 width=1.75 fillcolor=Mistyrose penwidth=0.5 fontname=Arial fontsize=10 style="filled" labelloc=top label=<<b>ACT</b>> ];
}
subgraph cluster_19 { sortv=4200 packmode=array_rtu1 label=""
subgraph cluster_20 { sortv=4210 packmode=array_rtu1 label=""
10 [ shape=rect height=0.75 width=1.75 fillcolor=Mistyrose penwidth=0.5 fontname=Arial fontsize=10 style="rounded,filled" labelloc=top pad="0.25,0.25" sortv=0 label=<<u><b>Clause 10</b></u><br/><br/>Improvement> ];
10.1 [ sortv=1 label="10.1 General" ];
10.2 [ sortv=2 label="10.2 Nonconformity\nand corrective\nactions" ];
10.3 [ sortv=3 label="10.3 Continual\nimprovement" ];
}
}
}
}
edge[ fontname=Arial fontsize=10 arrowsize=0.5 ];
4 -> 5;
5 -> 6;
6 -> 7;
7 -> 8;
8 -> 9;
9 -> 10;
10 -> 4;
edge[ color="CadetBlue" penwidth=0.5 dir=none fontname=Arial fontsize=10 ];
4 -> 4.1;
4 -> 4.2;
4 -> 4.3;
4 -> 4.4;
5 -> 5.1;
5 -> 5.2;
5 -> 5.3;
6 -> 6.1;
6 -> 6.2;
6 -> 6.3;
7 -> 7.1;
7 -> 7.2;
7 -> 7.3;
7 -> 7.4;
7 -> 7.5;
8 -> 8.1;
8 -> 8.2;
8 -> 8.3;
8 -> 8.4;
8 -> 8.5;
8 -> 8.6;
8 -> 8.7;
9 -> 9.1;
9 -> 9.2;
9 -> 9.3;
10 -> 10.1;
10 -> 10.2;
10 -> 10.3;
}
iso9001.gv (7.3 KB)
Nesting clusters can be a little confusing. Each time you wish to change the number of columns you must create another cluster with a new packmode
attribute. Inside that cluster can be more clusters, or just nodes. sortv
values always refer the the most recent packmode
in scope.
Here is the same diagram altered to show the cluster borders, and the packmode
and sortv
values used:
packmode=array Tutorial
How do packmode=array
values affect the output?
The mode array(_flag)?(%d)?
indicates that the components (clusters or nodes) should be packed at the graph level into an array of graphs. By default, the components are in row-major order, with the number of columns roughly the square root of the number of components.
The integer suffix specifies the number of columns for row-major. Thus, the mode array_r4
indicates array packing, with 4 columns per row, starting in the upper left and going across the first row, then to the second row, etc., until all components are used.
If a graph is smaller than the array cell it occupies, it is centered (left, right, top, and bottom) by default. The optional flags may contain t
, b
, l
, or r
, indicating that the graphs should be aligned along the top, bottom, left or right, respectively. The flags may also be combined such as tl
for top left, tr
for top right, bl
for bottom left, or br
for bottom right.
If the optional flags contains u
, the order of elements is determined by user-supplied values. Each component can specify its sort value by a non-negative integer using the sortv
attribute. Components are inserted in order, starting with the one with the smallest sort value. If no sort value is specified, zero is used.
Here are some examples:
Example 1: Default Behavior
packmode=array
Notice that the components are packed roughly in the square root of the 5 components.
Example 2: Align Right
packmode=array_r
is causing right alignment of node 4.4 with the larger node above it.
Example 3: Specify Sort Order
packmode=array_ru
says to use the sortv
attribute to place the nodes in numerical order specified.
Example 4: One Column, Sort Order
packmode=array_u1
says to use one column, and insert the components in the order specified by sortv
. The components are centered by default.
Example 5: One Column, Sort Order Specified, Right-aligned
packmode=array_ru1
says to use one column.
Example 6: One Column, Sort Order Specified, Left-aligned
packmode=array_lu1
says to use one column, and left-align the contents of the column.
Example 7: Three Columns, Sort Order Specified
packmode=array_ru3
says to have 3 columns. Note that each column is a transparent cluster. By default the clusters are aligned in the center top-to-bottom.
Example 8: Three Columns, Sort Order Specified, Top-aligned
packmode=array_rtu3
says to have 3 columns, and align the contents top-to-bottom.
Example 9: Three Columns, Sort Order Specified, Bottom-aligned
Likewise, we can align the contents to the bottom of the cluster with packmode=array_rbu3