Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Notes per diagram kind

The general rules hold everywhere. This page lists where a diagram kind adds rules or bends them. Component, package and state diagrams share the layered layout and router. Sequence and activity diagrams have layouts of their own, built so that most line rules hold by construction.

Component diagrams

Flow right, and leave room for the wiring

Rule. Component diagrams flow right by default. A rank gap grows to fit a connector’s label, and an assembly or wired connector’s ball, socket and arrow.

Why. Interfaces and their names sit along horizontal runs, where they have room.

Source. DECISIONS.md, “UML 2.5.1 audit (stage 6a)”.

Status: enforced (edge_spec in the component layout).

Keep a delegation straight, and let the outer connector take the jog

Rule. A port’s position on its side follows the connectors inside the component first, so the delegation is straight. The connector outside takes any jog.

Why. Inner gaps are narrow, so a jog there crowds the contents. Outside there is room.

Source. DECISIONS.md, “Shape of the generic layout and routing APIs”.

Status: enforced, but it is a choice with a cost: 32 bends in the golden files are outer connectors jogging to a port that sits where the inner line wants it. Letting the outer line be straight when the inner one has room is a lever noted in the study.

Draw ball and socket clear of names

Rule. The ball, the socket and the interface name sit on a straight run of the connector, clear of other labels and names.

Why. The glyph is notation. A name over it hides what it says.

Source. UML 2.5.1, 11.2.4 and 10.4.4.

Status: enforced (draw_assembly and draw_wired choose a free straight run).

Package diagrams

Draw containment as one tree

Rule. When every member sits in the next rank, an owner’s members hang from one trunk with the circle-plus on the owner. Otherwise each branch is routed from that shared anchor.

Why. UML draws membership as branching lines from one circle-plus (12.2.4).

Source. UML 2.5.1, 12.2.4, p. 248.

Status: enforced.

Fold unrelated siblings into a block

Rule. Four or more siblings with no relations or hints between them fold into a roughly square block of rows.

Why. One long row of unrelated packages wastes width and suggests an order that is not there.

Source. DECISIONS.md, “Package diagrams (stage 2)”.

Status: enforced (wrap_constraints).

State diagrams

Reserve label room and keep labels on the flowing side

See Reserve room for labels and Put labels on a consistent side. State diagrams are where labels matter most (Castelló et al.), and where they currently cost the most bends: Never let a label force a bend.

Draw self-transitions as compact loops away from the flow

Rule. A self-transition is a small loop on the side of the state away from the flow, with its label beside it. A hidden box keeps the state centred in its rank.

Why. A loop on the flowing side would collide with the transitions in and out.

Source. DECISIONS.md, “State machine diagrams (stage 4)”.

Status: enforced.

Meet small symbols on their sides

Rule. A line into a final state, choice, junction or terminate symbol from a source that cannot line up with it meets the symbol’s facing side, as an L. Lines out of a choice fan from different corners.

Why. Lines meeting at one point of a small symbol merge into one ambiguous junction.

Source. UML 2.5.1, Figure 14.25; DECISIONS.md, “State pseudostates take lines on their sides”.

Status: enforced.

Tile regions across the flow

Rule. Orthogonal regions sit side by side across the flow, with equal extent along it, separated by dashed lines.

Why. This matches Figures 14.9 and 14.10, and lets each region keep the diagram’s direction.

Source. UML 2.5.1, 14.2.4.3 and Figures 14.9 and 14.10.

Status: enforced.

Sequence diagrams

Sequence diagrams use a timeline layout: lifelines are columns, events are rows on the 8px grid, and there is no router.

Never cross a lifeline with text

Rule. A message label stays within one lifeline gap, the gap nearest the sender that fits it, and the columns widen until it fits.

Why. Text across a lifeline is cut by it, and a reader cannot tell which side it belongs to.

diagram sequence "Labels between lifelines"

actor User as u
participant API as a
participant DB as db
u -> a : place order
a -> db : insert(order)
db --> a : id
a --> u : confirmation
Labels between lifelines User API DB place order insert(order) id confirmation

Source. DECISIONS.md, “Sequence diagrams (stage 3)”.

Status: enforced. The quality test counts any label within 2px of a lifeline: none in the goldens.

Keep labels off arrowheads and dots

Rule. A message label keeps 4px from the arrowhead it points at. A found or lost message’s stub is long enough to hold its label between the dot and the arrowhead, clear of both, and a creation message’s gap counts the new head’s half width.

Why. Text that touches the arrowhead reads as part of it, and the halo bites into the head.

Source. UML 2.5.1, 17.4.4.1 and Figure 17.11 (lost and found messages); DECISIONS.md, “Sequence and activity quality (stage 9)”.

Status: enforced since stage 9; the quality test counts labels within 2px of an arrowhead or dot.

Keep frame tabs and notes off execution bars

Rule. A fragment’s operator tab, or a note across lifelines, should not hide part of an execution bar.

Why. A bar cut by a tab or a note looks like an execution that stopped and started again.

Source. UML 2.5.1, 17.2.4 and 17.6.4.

Status: planned. Tabs sit at the frame’s corner, which is 12px left of the first lifeline’s bar, so a tab over an active bar hides a stretch of it; eleven such cases remain in the goldens and are counted.

Keep messages horizontal and time downward

Rule. Every message is a horizontal arrow, and later events are lower. Nested executions step right.

Why. That is the notation (17.4.4). Horizontal arrows keep the time order unambiguous.

Source. UML 2.5.1, clause 17.

Status: enforced. Consecutive one-line messages are 32px apart; the quality test counts any other gap between them with nothing drawn in between.

Activity diagrams

Activity diagrams use a structured-flow layout driven by the block tree, so lines are straight by construction and nothing is routed by search.

Keep the main flow on one axis

Rule. The flow that continues takes the straight axis. Side arms branch off and rejoin beside it, and a bypass runs on the right.

Why. The reader follows the main path down a straight line, and the exceptions read as detours. Below, the [no] arm stops, so Ship and Invoice stay on the axis.

diagram activity "Main flow straight"

start
action "Receive order"
if "in stock" {
  action "Ship"
} else "no" {
  action "Cancel"
  stop
}
action "Invoice"
stop
Main flow straight Receive order Ship Cancel Invoice [in stock] [no]

Source. DECISIONS.md, “Activity diagrams (stage 5)”; Ware et al. 2002 (continuity).

Status: partial. The axis stays straight, but the statement after a branch whose siblings stop waits below the tallest sibling, so the drop to Invoice is longer than the others. The quality test counts such drops as uneven gaps.

Space a straight flow evenly

Rule. Consecutive nodes in a straight flow are 32px apart. A guard beside a drop adds the room it needs.

Why. Even spacing makes a straight flow read as one sequence, and a longer gap then signals something.

Source. DECISIONS.md, “Sequence and activity quality (stage 9)”.

Status: partial. Exceptions in the goldens: a while loop’s merge and decision sit 24px apart and read as one test; a note rising over a decision lengthens the drop into it; a node with a taller note is centred in the note’s height; and the continuation after a branch whose siblings stop (above).

Rule. A note’s dashed link ends on the outline of the node it annotates.

Why. A link that stops short in white space does not say which node it means.

Source. UML 2.5.1, 7.4.4 (a note is attached by a dashed line); DECISIONS.md, “Sequence and activity quality (stage 9)”.

Status: enforced since stage 9: a note above a decision now reaches the diamond’s outline.

Put guards by the branch they guard

Rule. A guard sits at the start of its flow, by the corner where the flow leaves the decision. Arms that share one run keep their guard over their own drop.

Why. A guard read near the decision is matched to the right arm.

Source. UML 2.5.1, 15.2.4 (guards on outgoing flows); DECISIONS.md, “Activity diagrams (stage 5)”.

Status: enforced. The quality test counts guards touching a flow, node, divider or other label: none.

Draw a merge only where flows rejoin

Rule. A merge diamond or join bar is drawn only where at least two flows meet.

Why. A merge with one input is ink without meaning.

Source. UML 2.5.1, 15.3.3; DECISIONS.md, “Activity diagrams (stage 5)”.

Status: enforced.