I want to rewire my house and home lab. That require some planning as it will be expanded a bit. Having looked around, I found a few solutions, but none that really satisfy me fully. I wanted something free & opensource other that libreoffice (by the way, there’s a set of network icons for it !). It has to be scriptable so I can update it automatically. Other applications include MS Visio and Dia.
First, let’s look at the diagrams online.


drawthe.net : Online drawing, quick, use cisco icons. Based/similar on graphviz ? A bit limited, there’s a docker image on github.
tikz : Was inspired by graphviz, but greatly enhanced. Used with tex to generate book/professionnal graphics. I would like to use it, but the learning curve is a bit harder and I don’t have the time for it now. The good thing is that it can import graphviz files and add custom procedures afterwards. Definitely the best control/look !
Graphviz : The original graph visualization tool. My current pick. There’s a python engine, but I just use the dot files for now. The draw back is that you don’t have fine control on the rendering (or that I’m not well experienced).
There’s also netraph, but I wanted to stick to the original graphviz.

Getting started with Graphviz
I only found one online example. Thanks to this example, I got to try graphviz !
That’s why I wanted to document this to share back to the comunity, specially /r/homelab.
My first try didn’t go really well. I used nodes for ports on my switch. I restarted by using html tables, it’s quick and you don’t have node (ports) misplacement. Also changing the drawing orientation from top-bottom to left right doesn’t screw the graphic !


- Left-right orientation (rankdir=LR)
I am also working on my network. I have the unfinished current state and what I ultimately want it to look like.


Coding the dot file
There are a few must have open tabs to get started ! First is the GraphViz reference page and second is google ! As you can find quite a few questions on stackoverflow and others ! See references at bottom. Awesom-graphviz is also a great resource !
The dot language
It’s quite simple and is not a scripting language, it’s just a descriptive language. For diagram, we use the digraph declaration and a few nodes. Also, check this online quick visualizer ! Let’s start with it’s example :
digraph G {
“Welcome” -> “To”
“To” -> “Web”
“To” -> “GraphViz!”
}

digraph G {
First
Second
Third
FourthFirst->Second
Second->Third
Third->Fourth
}

digraph G {
First
Second
Third
FourthFirst->Second
Second->Third
Third->Fourth
Third->Back->To->First
}

To fix it, use rank=same or prevent arrows from affecting the rank.
digraph G {
First
Second
Third
FourthFirst->Second
Second->Third
Third->Fourth
Third->Back->To->First
{rank=same Third Back}
{rank=same Second To}
}

digraph G {
First
Second
Third
FourthFirst->Second
Second->Third
Third->Fourth
Third->Back->To->First [constraint=false]
}

That’s the basic of it. I’ll not go into a in-depth tutorial as I am not so much proficient with it (been playing with it a few hours at best). Let’s go to html code and work on my wiring.
Simple wall plate for Ethernet cabling

There are many ways to translate this in dot language. The first would be creating a cluster of six nodes as :
digraph P {
rankdir=LR;
subgraph cluster_0 {
label=”Living room plate”;c_lr_r1 [label=”iptv”];
c_lr_r2 [label=”xbox”];
c_lr_r3 [label=”wifi”];
c_lr_r4 [label=”2e”];
c_lr_r5 [label=”spare1″];
c_lr_r6 [label=”spare2″];c_lr_r1->c_lr_r2[style=invis];
c_lr_r3->c_lr_r4[style=invis];
c_lr_r5->c_lr_r6[style=invis];}
}

But now refer to previous image. That’s not the way I choosed to do it. Let’s get to html tables :
wallplate_office [
shape=plaintext
color=blue
fontsize=”10″
label=<
<table border=”1″ cellborder=”1″ cellspacing=”0″ align=”center” cellpadding=”0″>
<tr> // Fix width size with this line and name the plate
<td colspan=”2″ border=”1″ align=”center” valign=”middle” height=”20″ width=”100″ fixedsize=”true”><font point-size=”12″><b>Office</b></font></td>
</tr>
<tr>
<td border=”2″ port=”port1″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port2″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
</tr>
<tr>
<td border=”2″ port=”port3″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port4″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
</tr>
<tr>
<td border=”2″ port=”port5″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port6″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
</tr>
</table>
>];

Great, let’s make a switch :
switch_aruba_a[
shape=plaintext
color=blue
fontsize=”10″
label=<
<table border=”1″ cellborder=”1″ cellspacing=”0″ align=”center” cellpadding=”0″>
<tr> // Fix width size with this line and name the plate
<td colspan=”28″ border=”1″ align=”center” valign=”middle” height=”20″ width=”100″ fixedsize=”true”><font point-size=”12″><b>Switch Aruba</b></font></td>
</tr>
<tr>
<td border=”2″ port=”port1″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port2″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port3″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port4″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port5″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port6″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port7″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port8″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port9″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port10″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port11″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port12″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port13″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port14″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port15″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port16″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port17″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port18″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port19″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port20″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port21″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port22″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port23″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port24″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ colspan=”4″></td>
</tr>
<tr>
<td border=”2″ port=”port25″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port26″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port27″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port28″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port29″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port30″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port31″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port32″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port33″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port34″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port35″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port36″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port37″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port38″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port39″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port40″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port41″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port42″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port43″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port44″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port45″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port46″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port47″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port48″><img src=”clipart-rj-45-female-ed05.png” scale=”true” /></td>
<td border=”2″ port=”port_sfp1″><img src=”sfp128.png” scale=”true” /></td>
<td border=”2″ port=”port_sfp2″><img src=”sfp128.png” scale=”true” /></td>
<td border=”2″ port=”port_sfp3″><img src=”sfp128.png” scale=”true” /></td>
<td border=”2″ port=”port_sfp4″><img src=”sfp128.png” scale=”true” /></td></tr>
</table>
>];
Now we can link a port on the wall plate to the panel and add some extra information:
wallplate_secondfloor:port1->switch_aruba_a:port1:n [constraint=false, penwidth=5, color=gray, headlabel=””, taillabel=””, label=<<font size=”18″><b> 30ft</b></font>>, labeldistance=5, fontsize=18];
You can adress a port with :portX when declared in the td table and an orientation on where the arrow should come/go :n for north, :s for south.
That should get you working
Adding computers
There are also multiple ways to add computers. You can do simple nodes, html tables or just a record.
digraph structs {
node [shape=record, border=0];
rankdir=LRstruct6 [width=”5″,label=”<name>TOP6 |{ {<icon> SERVER ICO} | {<eth0>eth0:|<eth1>eth1:|<eth2>eth2:} |{<ip1>192.168.2.1|<ip2>192.172.0.1|<ip3>10.0.0.1}}| CFG | {Location:|<location>RK} “];
struct1 [label=”<f0> top|<f1> middle|<f2> right”];struct6->struct1[style=invis];
struct1:f1 -> struct6:eth0;
struct1:f2 -> struct6:ip2;
struct1:f0 -> struct6:name:n;
}
But I went for html tags again 🙂
Todo :
- Make it more pretty : add gradient box around clusters.
References :
Net:
- netgraphp
- Graphviz (dot) examples
- HTML-like labels: vertical alignment of nested tables · Issue #25 · ellson/MOTHBALLED-graphviz
- graphviz / graphviz · GitLab
- how to align decimal value with dot in table using css and java script? – CodeProject
- Graphviz Subgraph Examples / Brian Stringfellow / Observable
- Network topology with graphviz | itsecworks
- The Systems Engineer organized chaos: Physical network diagram generated from dot config language
- Creating Alignment Maps with Graphviz – LarsBarkman.com
- gmamaladze/d3-dot-graph: This module provides D3js compatible library to parse and load files in graphviz DOT (.dot) (graph description language) format.
- Awesome GraphViz | awesome-graphviz
Stackoverflow:
- graphics – GraphViz – How to connect subgraphs? – Stack Overflow
- Display labels in line with the edge when using Graphviz – Stack Overflow
- Making a Legend/Key in GraphViz – Stack Overflow
- ruby – complicated graphviz tree structure – Stack Overflow
- Graphviz outputs a mess – Stack Overflow
- dot – Creating Straight Edges in Graphviz – Stack Overflow
- networkx – Labelling nodes in Graphviz using python dictionary and agraph – Stack Overflow
- Creating lines connecting each possible pair of points in PostGIS? – Geographic Information Systems Stack Exchange
- Dot file viewer for live updates from python (Through GraphViz) – Stack Overflow
- graphviz – How to influence layout of graph items? – Stack Overflow