System Diagrams

Why do we need System Diagram ?

We need these diagrams to communicate the design of the system or to understand the system in a more visual way. Worded documentation can be useful, but a picture conveys more information in a concise way.

System Diagram as a Graph problem ?

System diagram typically consists of drawing various components of the system and interconnecting them with lines & arrows. Conceptually these can be modelled as a Graph structure. Graphs can be used to represent various components of the system(nodes) and the relationship between them (edges). Then the problem becomes a matter of graph visualization.

Graphviz - A graph visualization tool

Often times drawing pictures manually can be time-consuming or creatively demanding. Tools like Graphviz popularize the notion of: diagrams as code/text It enables one to draw these diagrams in a much faster way.

Following are some of the tools in this space:

Author of Pikchr describes it much better here:

The objective is to convey truth, not feeling

Here, we shall explore system-diagram generation through Graphviz.

Graphviz

Think of Graphviz as a DSL for graph-visualization. The syntax is somewhat JSON/HCL like. We can draw both directed/undirected graphs. We will go with directed-graphs as they are more common here.

In Graphviz, there are three main objects:

Graphviz code is expressed in DOT language

Let’s go through a simple example to understand it better:

digraph app1 {

      // edges are represented by an `arrow` symbol
      A -> { B -> C}  // `A` has an edge to both `B` & `C`
      B -> D

      // optionally nodes can have style-attributes 
      A[shape="box"]
      B[shape="circle"]
      C[shape="box3d"]
}

To generate an image we can use one of the many online editors (https://edotor.net) or command-line tool (https://graphviz.org/download/). Save the above code to a file with .dot extension. Run this command:

 dot -Tsvg file-name.dot > output.svg

It generates the following image below:

App1-Graphviz

Next, lets take a slightly more complex example:

digraph webapp { // directed graph
    
    // left-to-right layout
    rankdir="LR";   
    
    // graph properties
    graph [label="Sample WebApp Diagram", nodesep=1, splines=ortho, bgcolor="#eeeeee"] 
    
    // node default attributes
    node[shape=box3d]  
    
    // edge default properties 
    edge[] 
    

       // nodes with properties
       // format: node-name[attr1=value1, attr1=value2]
       WebServer [label="NGINX", fontsize=11, fontcolor=white, fillcolor="#000080", style=filled]  
       ELB [label="Load Balancer", fillcolor="#391463", fontcolor=white, style=filled]
       DB [label="MySQL", shape=cylinder, style=filled, fillcolor="#6495ED"]
       
       // subgraphs logically group related nodes
       // subgraphs starting with name `cluster` get a border
       // subgraphs can be nested
       subgraph cluster_1 {
           label = "Client"
           style=filled; fillcolor="#1FAFF0";
           rank=same // assigns same rank to all nodes in the cluster
          
           Mobile[URL="https://www.google.com" target="_graphviz"] 
           Browser
       }

       subgraph cluster_2 {
          rank=same
          label = "Server" 
          style=filled; fillcolor="#1FAFF0";
          
          Cache -> API[constraint=false, color=purple];
          API -> Cache[constraint=false, color="#777"];
       }

        // edges: connect the nodes with arrows
        Browser -> ELB; 
        Mobile -> ELB-> WebServer -> API -> DB;
}

The above dot example is commented for improved readability. It produces an image like below:

App2 image

As a programmer, it is good to add Graphviz to your toolkit. There are many tools & libraries which have graphviz bindings. Instead of writing in DOT if you want to write in your preferred language, it may be worth exploring.

Resources