DOT reference
This page is the complete vocabulary. The tables describe every attribute the importer reads; the generated lists at the end enumerate every legal value and are pinned to the application's own catalogs by a test — when a shape or connector type is added to Drawbridge, this page fails the build until it is regenerated to match.
Device attributes
Set on a node statement: id [attr=value, …].
| Attribute | Value | Becomes |
|---|---|---|
kind |
a shape kind (list below) or a palette display name ("Wi-Fi AP", "L3 switch") |
The tile's shape and icon. Unknown values import as a neutral shape and are reported as adjusted. |
label |
text | The display name. Without it, the id is shown. Either way the id is what edges wire against. |
mgmtIp |
text | Inspector asset field |
serial |
text | Inspector asset field. A Fortinet-serial id (FG100FTK…, S448DFTF…) fills this automatically, and a FortiGate/FortiWiFi model is derived where the serial encodes one. |
model |
text | Inspector asset field |
location |
text | Inspector asset field |
notes |
text | Inspector asset field |
link |
a URL, or data:page/id,<pageId> |
Inspector asset field — the device's Link. On a node it is the URL; on an edge link= is the connector type, which is a different attribute on a different statement. |
color |
hex only — "#0ea5e9", "#e11d48" |
The tile accent. Named colors (red, grey) are ignored by design — Graphviz files use them decoratively, and the FortiLink dump sets color = grey on everything. |
labelpos |
inside, below, above, left, right |
Where the tile's name sits. Unknown values are reported as adjusted. |
pos |
"x,y" or "x,y!" — the tile's centre, points, y up (Graphviz's own) |
The tile's position. Honored all-or-nothing: unless every device carries one, positions are ignored (reported) and the import lays out afresh. The export writes them. |
width / height |
inches — width="1.333333" |
The tile's size (×72 to pixels, clamped up to a visible tile). Read with or without pos. |
cidr |
"10.1.2.0/24" |
Subnet annotation on a zone (also on a zone travelling as a node). |
group |
any string | Devices sharing a value become one group (task 2.44); groupcollapsed=true collapses it. Each import mints a fresh group. |
groupname |
text — groupname="DWDM-A" |
What the group is called, on every member beside group=, and ignored without one. An unnamed group is titled for what it is — Group · 3, Stack · 4, Optical · 3, MC-LAG. |
groupkind / stackside |
mclag / stack / optical · start |
What the group IS: an MC-LAG pair (two devices), a stack (two or more) or an optical shelf (two or more, its channel plan read from the wavelength= on the cables inside it), and the side a stack's ring runs on. A kind the members cannot be is reported and imports plain. |
detached |
true |
Excluded from geometric containment: the zone, rack or context it stands in does not own it and leaves it behind when it moves. Export-written; absent = a member. |
layer |
a layer name — layer=Overlay |
The device lands on that named layer, created if the page does not have it. |
fontsize / align / boxed / leaderto |
number · left/center/right · true · "x,y" |
Free-text and callout styling (kind=text / kind=callout); leaderto is the callout leader target, same units/axes as pos. |
imagedata |
a data:image/… URL |
The bitmap of a kind=image node. |
variant / rackrear / rackdepth |
unit · true · half/full |
Rack hardware: a rack-mounted unit strip, a rack rear elevation, a unit depth. |
portmap |
"C1:C21:LINE;C2:C23:LINE" |
One optical device’s own channel plan (task 17.75): client:channel:line per row, ; between rows. Read only on kind=dwdm-terminal and kind=transponder; the box becomes a site in Tables › Channels and its client cables show their channel. |
Link attributes
Set on an edge statement: a -> b [attr=value, …].
| Attribute | Value | Becomes |
|---|---|---|
label |
text | The link's caption |
speed |
text — "10G", "1G", "100M" |
The speed tag |
link |
a connector type (list below) | The line style. Unknown values are reported as adjusted. |
medium |
a cable medium (list below) | What the cable IS — drives the optics count. Paints nothing. Unknown values are ignored. |
wavelength |
text — "1310 nm", "C21" |
Optical wavelength or WDM channel; part of the part name in the optics count. Ignored on copper and direct-attach. |
vlan |
text — "10,20,30 native 1", "access 40" |
What the link carries, drawn as a quiet second caption line. Free text; nothing parses it. |
fromip / toip |
text — "10.0.0.1/30", "dhcp" |
The address at each end, drawn under that end's port label. Free text; written tail-first, like taillabel. |
circuit / provider |
text — "SE-12345" · "Telia" |
The carrier's reference for the service, and the carrier. Drawn as the caption of a WAN link that has no label; providers become legend rows. |
length |
text — "3 m" |
How long the cable is. Printed on the schedule; a DAC, AOC or copper lead is ordered by it in the transceiver count. |
installed |
true |
The cable is ticked as run on the cable schedule. Written only when ticked; anything else reads as not ticked. |
bundle |
a name — po1, ha |
Links sharing a name draw as one aggregate ring (LAG, HA bond) |
color |
hex only | The stroke color — same hex-only rule as devices |
taillabel |
text | Port label at the arrow's tail (the from end); wins over the port form |
headlabel |
text | Port label at the arrow's head (the to end); wins over the port form |
fromdir / todir |
n, s, e, w |
Attachment side at each end; wins over the compass form |
id |
any string — e7 |
Tells parallel cables apart: two identical A -> B lines with distinct ids are two cables; without ids the repeat is dropped and reported. The export writes one on every edge. |
router |
direct, arc, custom |
How the cable is drawn; absent/auto = the routed orthogonal default |
waypoints |
"x1,y1 x2,y2" — same units/axes as pos |
Interior points for custom/arc cables; read only when positions are honored |
arcbulge |
a number | Arc bow height for router=arc |
labelalong / labelside / labelfollow |
start/middle/end · above/on/below · true |
Caption placement along, beside and rotated with the cable |
labelt / labelgap |
a fraction 0–1 · px |
A dragged caption: how far along the cable it sits, and how far off the line. labelt wins over labelalong; labelside still says which side. Export-written. |
fromportside / toportside / fromportfollow / toportfollow |
above/on/below · true |
Port-label placement per end |
Endpoint syntax
| Form | Meaning |
|---|---|
fw1:port1 -> sw1:ge1 |
Port names become the two endpoint labels |
fw1:e -> fw2:w |
Cardinal compass points become attachment sides (east out, west in) |
fw1:ne -> fw2 |
Diagonals have no side — reported as adjusted and ignored |
a -> b -> c |
A chain: one link per hop |
core -> {a1 a2 a3} |
A fan-out: one link per member; attributes after the group apply to every link it created |
a -- b (in graph {}) |
Undirected: imports fine; with no arrows, tiers follow write order |
Structure
| Construct | Meaning |
|---|---|
digraph name { … } / graph { … } |
One topology block; strict is accepted; the name is optional and unused |
| several blocks in one paste | All import; a device named in more than one block merges into one tile |
| text outside the blocks | Skipped silently — CLI chrome around a FortiLink dump is expected, not an error |
{rank=same; A B} |
Declares same-tier peers: their link is drawn but never stacks them (one-node groups are no-ops) |
node [attr=…] / edge [attr=…] |
Defaults for everything declared after them — positional, exactly like Graphviz |
subgraph cluster_x { purdue="N" … } |
Declares a Purdue level: the backdrop is drawn behind the topology and the cluster's members seat into band N (5…0, the model's numbering) |
subgraph cluster_x { kind=zone … } |
A container box (task 11.82): kind= zone/rack/vcontext, label=, cidr=, labelplace= (top-center, top-right, bottom-left, bottom-center or bottom-right — where a zone writes its name; unset is top-left), rackrear=, layer=, and its rect as bb="llx,lly,urx,ury" — placed at the rect when positions are honored, else wrapped around its members |
zonecollapsed=true on a zone |
A folded zone (task 17.77): one tile that says what it holds, cables merged per device. The export writes it |
page="HQ" on a zone |
The zone and all in it go on a page of their own (task 17.66); this page shows it as one tile linking there |
subgraph cluster_x { … } |
Without kind= or purdue=: its devices import, the grouping itself does not (reported as adjusted) |
// …, /* … */ |
Comments, read past |
rankdir=… |
Read but not obeyed — the import is always drawn top-down; LR/RL/BT are reported |
inputscale=… |
The units pos= is written in, exactly as neato reads it (72 = points). Absent = points, which is what dot -Tdot output and our export use |
newrank=true |
Export-written, for Graphviz's benefit rather than ours: without it dot deletes any device that is both in a {rank=same} row and inside a cluster from that cluster, and then drops the emptied cluster (task 11.84) |
purdue_bb="llx,lly,urx,ury" |
The Purdue backdrop's rectangle (export-written); with positions honored, the backdrop returns at this exact rect instead of being re-derived |
speedcolors="{JSON}" |
The document's speed→color overrides, one JSON object (export-written); applied on import |
digraph NAME { … } |
Importing into an empty page adopts NAME as the page title |
How a paste is recognised
A paste is treated as DOT when a line-starting digraph/graph (optionally strict, optionally named) opens a brace block. The FortiLink flavor is detected by the dump's CLI header or by a red-filled node whose id is a FortiGate serial — that flavor turns the fillcolor defaults into roles (red = FortiGate, blue = tier 1, green = tier 2+). Everything else imports as generic DOT. There is no format picker anywhere; the preview names what was detected.
Limits
- An import link (
#import=…) carries at most 2 MB of decoded text; bigger topologies arrive by paste or CLI. - A cable can be in several rings at once —
bundle="po1 spine_a", space-separated, one ring per name. - Positions are honored all-or-nothing: a file where only some devices carry
pos=is laid out afresh, with one adjusted line saying so — a half-pinned layout is never produced. - Maps are not importable — the preview says so when a paste contains them. Zones, racks and virtual contexts import as real containers when their cluster names a
kind=; Purdue levels viapurdue="N". A cable to a Purdue frame is not drawn — the frame is a backdrop, and the editor gives one no cables either — and the preview lists that edge as skipped. - Still home-only: the legend (derived, regenerable), map backdrops — except a map a cable is drawn to, which is written as
kind=worldso the cable keeps both its ends, its view (region, frame, cities) staying home — hidden layers and their content (a layer you turned off cannot leave the app), layer lock flags, ring color/position styling, and fine z-order beyond boxes-behind-devices.
Every value, generated
The lists below are generated from the app's own catalogs and pinned by app/src/manual/api-reference.test.ts — they are the application's truth, not prose.
Or browse them in the app. The icon palette is the same catalog with the pictures attached, which is usually the faster way in when you know what a device looks like but not what it is called. Hover any shape and its kind= name appears in the tooltip, with a small copy button in the tile's corner that puts the bare id on your clipboard. The search box matches these ids too, hyphens included — typing l3- finds L3 switch — so you can go the other way as well, from an id in a file to the picture it draws.
Shape kinds (kind=) — 116 in all, by family:
- security:
firewallproxyvpn-gatewayipswafnacauth-serversiemsaseendpoint-managerdata-diodejump-hostpamattackerinfected-laptopmalicious-filemalicious-websitevdomvsys - network:
routerswitchl3-switchload-balancerwifi-apwlcsd-wancellular-routercpenetwork-tapvoice-pbxpatch-panelconsole-serverdwdm-terminalmux-demuxtransponderinternetwanmanwlanpstnhomebranchcampusdatacenterplantlanbusvrf - compute:
serverweb-servermail-serverdns-servervmcontainercontainer-hostclean-fileclean-website - data:
databasedirectorystoragenas - cloud:
cloudcloud-vpccloud-computecloud-storagecloud-function - ot:
plcsafety-plcrturemote-iovfdhmiengineering-workstationscada-serverhistorianprotocol-gatewaycameraupspdudoor-controlleriot-sensorsubstationprotection-relaysolar-pvwind-turbinehvacfire-panelrobotfield-cabinet - people:
useruser-grouplaptopdesktopmobileendpointmanaged-endpointprinter - annotation:
unknown-fileunknown-websitetextcalloutflowzonevcontextworldpurduerackgenericrectellipsediamondtrianglehexagonstarnoteline
Connector types (link=): ipsec, trunk, lag, wan, mgmt, wireless, conduit, fieldbus, ha.
Cable media (medium=): rj45, dac, aoc, mmf, smf, smf-long, bidi, cwdm, dwdm, breakout-dac, breakout-mpo, rj45-sfp.
Attachment sides (compass points, fromdir=/todir=): n, s, e, w.
Asset fields (device attributes): mgmtIp, serial, chassis, model, location, notes, link.
Formats the importer detects: Cisco CDP neighbours · Cisco CDP neighbours (detail) · LLDP neighbours · Cisco LLDP neighbours (detail) · Junos LLDP neighbours · Arista EOS LLDP neighbours · Arista EOS LLDP neighbours (detail) · Huawei VRP LLDP neighbours (brief) · Huawei VRP LLDP neighbours (detail) · HPE Comware LLDP neighbours (list) · HPE Comware LLDP neighbours (verbose) · PAN-OS LLDP neighbours · MikroTik IP neighbours · FortiOS LLDP neighbours · FortiSwitch LLDP neighbour summary · Aruba CX LLDP neighbours · Aruba CX LLDP neighbours (detail) · ArubaOS-Switch LLDP remote devices · EtherChannel / port-channel summary · Containerlab topology · Meraki link-layer topology · UniFi device export · FortiGate HA status · Interface descriptions · Graphviz DOT · FortiLink topology (Graphviz DOT) · Mermaid flowchart · Mermaid architecture-beta · Prefix list — subnets · Ansible inventory (INI) · Ansible inventory (YAML) · CSV — devices · CSV — links · CSV — devices and links.
CLI export formats (--export): svg, png, drawio, dot, csv, netbox.csv, netbox-devices.csv, describe.json, clab.yml.