paint-brush
Here's Why You Shouldn't Use Graphviz for DAGs: What You Should Use Insteadby@s0l0ist
1,127 reads
1,127 reads

Here's Why You Shouldn't Use Graphviz for DAGs: What You Should Use Instead

by Nick AngelouJanuary 24th, 2024
Read on Terminal Reader
Read this story w/o Javascript

Too Long; Didn't Read

tl;dr: Use Vizdom.dev to render DAGs written in the DOT language and experience speedups of up to 30x
featured image - Here's Why You Shouldn't Use Graphviz for DAGs: What You Should Use Instead
Nick Angelou HackerNoon profile picture


Spoiler: Use Vizdom.dev to render DAGs written in the DOT language


As a software dev, I’ve occasionally worked with DAGs — most of which involve visualizing them. In many cases, I found it difficult to get a quick rendering and found myself looking for tooling.


Fortunately, there’s the trusty Graphviz tool that can render graphs written in the DOT language — Perfect!


Except…

  • It doesn’t work well on the web*
  • I need to install it
  • It doesn’t manage DOT/GV files online

Considerations

*Okay, technically Graphviz can be compiled to WebAssembly, and a few talented folks managed to build a few neat projects such as dreampuf’s editor, nikeee’s edotor.net, and magjac’s editor — each with its own twist. I still struggle to embed these renderings without exporting them to an SVG (or other medium).


For example, I want to store my graph in Notion.so by simply pasting a link that automatically renders the graph.


I could use MermaidJS which renders graphs pretty cleanly and works surprisingly well — it’s one of the many reasons why it has 64k+ starts on GitHub. I can also embed graphs in Notion/GitHub by using markdown, sweet!


Unfortunately, I have to translate DOT into the flavor of markdown that Mermaid requires. For smaller textual representations, I can use ChatGPT to convert them for me, but it frequently makes grammatical mistakes, and the graph will refuse to render — making it unreliable as a source of automation.


Then there is Terrastruct.com which is amazing for managing hand-built diagrams, but like my Mermaid woes, I cannot convert DOT to D2 reliably. I suppose if you’re going to be building diagrams by hand this is an acceptable, one-time cost. In general, it is a fantastic tool. Kudos!

The Problem

  • I want to render programmatically generated DOT outputs — none of the tooling seems to help me achieve that goal.


  • I want to embed links that render graphs.


  • I want to store the rendering online for updates or to visually compare it with other graphs.

The Solution

Yup — I built an app for that 🎉


…And it’s built entirely in Rust 🦀 with many thanks to Leptos


tl;dr — a simple, purpose-built app to render DAGs online, fast


Minimizing edge crossings in graph generation, a recognized NP-hard challenge is key to creating visually appealing graphs. The team at Terrastruct has published an outstanding blog post delving into this topic. Inspired significantly by the DagreJS layout algorithm(s) and the insightful paper “A Technique for Drawing Directed Graphs¹”, I developed a variant in Rust.


This version is particularly effective for rendering hierarchical graphs, leveraging the intricate complexities of this problem.


Rendering large DAGs (500+ nodes/edges) tends to be somewhat sluggish with Graphviz. Dagre + D3 (d3-graphviz and derivatives) end up quite a bit faster and offer great animations/styling customizations. Yet, I felt that they miss out on the features that DOT language provides — namely, the styling attributes are often only honored if you’re rending with Graphviz.


Vizdom will produce results very similar to Dagre but aligned more toward the DOT specification and style behaviors of Graphviz. However, it does not have feature parity with Graphviz, and statements/attributes that aren’t supported are simply ignored.


I believe it is a good compromise for the kinds of attributes programmatically generated DOT will consume.


Vizdom Features

  • 🚀 Blazing fast rendering
  • 💾 Store graphs in links
  • 0️⃣ Zero dependencies and no installation required

Rendering Speed

Well, it’s an apples-to-oranges comparison. Graphviz still produces great visualizations and supports more layout engines, so I am subjectively comparing Vizdom against Graphviz’s DOT engine, scoping it down to just DAGs, and even further scoping it down to a list of narrow features of the DOT language.


Yes, I know it’s terrible to compare years of experience and tooling around the 30+ year streak that is Graphviz, but for my narrow use-case, it is crazy fast. Here are some wall times on my M1 Macbook Pro for rendering a fairly large graph with ~400 nodes:


  • Native Graphviz: ~30 seconds
  • Chrome (WASM) Graphviz: crashes*
  • Chrome (Javascript) DagreJS: ~10 seconds
  • Chrome (WASM) Vizdom~1 second**


* It crashes because the emscripten flag, ALLOW_MEMORY_GROWTH=1, is not set, therefore limiting the total memory to 16MB. This can be fixed, but I have not found an online project that can handle the graph in question.


** The example graph is rendered by selecting Example 14 in the editor view. Refreshing the page will result in you refreshing the page and getting a 414 because the URI that persists in the graph is too large. I am working on a better solution to store larger graphs.


SVG rendering of Example 14

Store Graphs in Links

You’ll notice when you make any changes to the DOT file, the URL immediately updates a few query parameters to store the graph and layout options, allowing you to always reference a copy of your data just by storing the link!


There is a catch — large-ish graphs tend to make the URI too large for AWS (where Vizdom is currently hosted) and other load balancers.


I’m currently working on a solution to handle larger graphs, but in the meantime, I’ve included a few ways to persist and store graphs:


  • Copy an embeddable link that automatically renders a view that maximizes the graph.


  • Copy an iframe snippet to embed in any application that supports rendering them.


  • Or simply download the rendered SVG.


Here’s an example of what the editor view looks like of the pprof trace for deflate:

Go to the Editor View, and load Example 42


Diff View

Occasionally, I found myself trying to compare two graphs that I’ve generated, so while I was at it, I added a diff viewer to visually see changes between two different graphs.


Color Legend:

  • Red: Deleted
  • Orange: Modified
  • Green: Added


Here’s a few snaps:

Click me: changing a node ID from “e” to “f”


Click me: adding “cluster=true”


Future Direction

Vizdom is still a work in progress, and as it continues to evolve, I am aware that the journey of perfecting this tool is as dynamic as the field of graph visualization itself. While I am proud of what Vizdom has achieved so far, I am even more excited about its potential. That’s where you, the reader and potential user, come in.


If you have any feedback, please feel free to message me over on Gitter or Discord.


Thanks for reading — If you enjoyed this article, please follow!


[1]: E. R. Gansner, E. Koutsofios, S. C. North and K. . -P. Vo, “A technique for drawing directed graphs,” in IEEE Transactions on Software Engineering, vol. 19, no. 3, pp. 214–230, March 1993, doi: 10.1109/32.221135.


Also published here