2

I've been using Graphviz a little and just found out about PlantUML which is quite similar.

I make diagrams but later the processes or systems depicted by the diagrams might change so I need to make changes to the diagrams, hence it is important that code used to generate the diagrams is maintainable.

I was wondering if there are any best practices, conventions or guides to writing maintainable code in Graphviz and/or PlantUML. What approaches you have, and if you can share tips from your experiences.

Graphviz and PlantUML have support for comments, do these improve maintainability, and if so, what is important to comment?

How to structure the document? For example, I can declare all the nodes first and the declare the edges so all the nodes are in one place and all the edges in another place, or I can declare multiple groups where the nodes and edges are defined together. But the edges go to multiple nodes so it can be difficult to group them logically together.

2

3 Answers 3

4

Version control

Use a version control system (such as Git), this allows you collaborate with others, and go back in history and see when changes were made, what changes were made, why they were made and by who they were made by with the commit message explaining the rationale behind the decision.

Example commit messages:

  • Add composition edge from node Foo to Bar
  • Remove node Bar
  • Add dependency from Bar on Baz

Header documentation block

The diagram source can end up in different places and people may have an outdated version, or have some feedback or questions, so it might be a good idea to have a header documentation block containing some metadata. Graphviz supports C++-style comments: /* */ and //, it also considers lines starting with a # character to be output from C preprocessor and discarded. PlantUML supports comments using '.

If the diagram is a UML diagram the documentation can specify what type of UML diagram it is, example a class diagram, component diagram, or sequence diagram, etc.

It can include date of creation, date of last modification, and author along with contact information. It can contain a link to where the latest version of the diagram may be acquired.

It can include a SPDX license identifier, such as CC-PDDC for example.

It can include which version it is, if the diagram is for a particular software implementation it can use the same version as for that software, else semantic versioning is probably a bad idea, and you should consider using a sequentially-incremented integer or just a date instead.

Example:

' UML component diagram illustrating the architecture behind Acme Labs Project Z.
' The architecture derives from the earlier Project X.
' Designed by the Acme Technical Committee 1 (TC1) on August 2011.
'
' Author: Alice <[email protected]>
' Created on: 2011-10-01
' Last updated: 2020-12-12
' Website: https://www.example.com/diagrams/
' License: CC-PDDC

Graphviz

Use the .gv file extension. The MIME type is text/vnd.graphviz.

You can style nodes of same type together.

// Style first
node1, node2, node3 [shape="box", color="blue"]
node4, node5, node6 [shape="circle", color="red"]

// Declare the edges later
node1 -> node2 -> node3
node4 -> node5 -> node6

You can use the class attribute on nodes to use CSS classes from an external stylesheet file. Note, this only works when rendering as SVG.

alice [class="girl"]
bob [class="boy"]
clare [class="girl"]

alice -> bob -> clare

Use indention:

Good 👍️

subgraph { 
  rank = same; A; B; C; 
}

Bad 👎️

subgraph { 
rank = same; A; B; C; 
}

PlantUML

Use the .puml file extension.

You can nest structures in PlantUML, this allows you group them easier in one cohesive structure.

Good 👍️

@startuml
frame FrameA {
  component ComponentA {
    component Foo
  }
  component ComponentB {
    component Bar
  }

  ComponentA -> ComponentB
  Foo -> Bar
}
@enduml

Bad 👎️

@startuml
frame FrameA {
  component ComponentA {
    component Foo
  }
  component ComponentB {
    component Bar
  }
}
ComponentA -> ComponentB
Foo -> Bar
@enduml
2

PlantUML is a rendering engine with its own markup language. It has some support for basic loops and conditions, but it is a markup language first and foremost.

So treat it as such.

How do you maintain HTML? Markdown? LaTeX?

Most you can do is keep them short, keep them clean, reuse code by storing it in separate files, stick to the conventions you've came up with, and use human-readable identifiers.

Or, if you don't have these issues with regular programming languages, then you could write a simple wrapper for easy generation of PlantUML syntax.

2
  • A great way to write maintainanble HTML is to use indention and to avoid overusing the div element in favor of using semantic elements such as header, footer, main, nav, article and `section. Another way is to insert an empty blank line between major sections.
    – Fred
    Commented Dec 12, 2020 at 14:01
  • HTML, Markdown and LaTeX are for documents, hence written in a top-down manner which leaves little room for doing it many ways. With GraphViz and PlantUML you can do declarations of nodes first in one place, then create the edges, or you can declare the edges together with the nodes.
    – Fred
    Commented Dec 12, 2020 at 14:16
1

I was wondering if there are any best practices, conventions or guides to writing maintainable code in Graphviz and/or PlantUML. What approaches you have, and if you can share tips from your experiences.

I don't think there's any. You can follow the best practices suggested by PlantUML or Graphviz, but the ultimate test is often showing up the result to someone else. As we do with the source code.

I have been drawing with PlantUML for a while now. Some of the practices I have adopted over the years are:

1.One file per diagram.

Data View, Deployment View, Functional View, Class View, Package View, etc. All are implemented in different files. Diagrams should be simple and clean. Too many boxes, actors, nodes, arrows, links, etc will defeat the purpose of the diagram. If you need to delve into specific areas of the design or you need to represent the design from a different perspective, make a zoom in a different file.

  1. I don't follow programming best practices.

I'm not programming. Defining variables at the beginning of the file is a programming practice. Defining all the elements of the diagram at the beginning is a similar practice. It could be useful for certain diagrams but it's not a rule of thumb.

  1. I use aliases, which are unique in the file
element "name" as alias
// node "NODE 1" as node_1_alias 
// storage "File Storage" as file_storage_alias 
// db "DB Remote" as db_1 
// db "DB Local" as db_2 
// etc..
  1. I link elements by the alias
node_1_alias -0)- db_1
  1. I add additional info about the link.
node_1_alias -0)- db_1 : jdbc\n(connection string)
  1. I declare elements from outside in.

Once more, I'm not programming.

rectangle "Bluemix" <<IBM>> {

    rectangle "Cluster" <<UK>>{     

        rectangle "Services" <<Kubernetes>>{
            node "Router" as ROT
            node "Service" as SRV
            ROT <..> SRV
        }

        rectangle "Deployments" <<Kubernetes>>{
            node "app-web" <<Container>> as WEB
            note left: 256Mb RAM\nxxCPU
            node "api-rs" <<Container>> as RS               
            note left: 2GB RAM\nxxCPU
            node "aggregator" <<Container>> as AG               
            note right: 2GB RAM\nxxCPU
            
            WEB ..> RS
            WEB .down.> AG      
            
        }
        SRV <..down..> WEB
    }
}

As shown, I define elements within their respective boundary/scope. PlantUML is smart enough to find aliases already defined. Typos will result in duplicated elements with similar names.

  1. I define the relationships within the scope/context they belong to.

Not at the end of the file and out of context. Solving the relationships at the end of the file ends up with a list of links hard to reason about.

When I want to change a view, I look for the element to change and I expect all the info related to this element to be next (or close) to it. Scrolling up and down is tedious and impractical.

what is important to comment?

Look at the diagram. Is missing something important? Can you draw it? For example. Can you draw a backup policy? Can you draw the recommended size of the JVM, File Storage or DB? Can you draw what kind of DB (SQL, NoSQL, key-value, etc)?

If one element is not yet implemented (it depends on someone else), can you draw that? Ok, you fill it up with a different colour but, what does that colour mean?

Finally, as commented in other answers, using a version control system is a must. Not just for collaboration but change tracking and file versioning.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.