# Dot is no longer my friend. What can I do? (10h SVG Render Process)

**URL:** <https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062>\
**Category:** Help\
**Created:** [July 2, 2025, 11:09am UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062 "2025-07-02T11:09:21Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 2, 2025, 11:09am UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/1 "2025-07-02T11:09:21Z")

</div>

Long story short: Rendering [universe.gv](https://forum.graphviz.org/uploads/short-url/7x7V6g3QArpv7mSMSNBzYTSMduQ.gv) (721.8 KB) to SVG on my machine takes 10 hours (`dot -v5 -O -Tsvg universe.gv`). I would like to improve that, if possible.

I recently started a small project to help me build up timelines of events, and have those merged into a single, meaningful graph. I chose to render my data as GraphViz instructions, as I’ve had many great experiences with the tool stack in the past. The visualization of that graph is an important piece of the work, as it allows me to “scroll through” the events and place myself in the mindset of that time, by just visually parsing the context of the rendered image at a given location. For reference, a “low-fidelity” rendering (ortho splines, network simplex drastically limited) is generated in CI at [https://oliversalzburg.github.io/timeline/](https://oliversalzburg.github.io/timeline/).

When I looked into the subject, I came across:

- [Large graph builders - should Graphviz provide more help?](https://forum.graphviz.org/t/large-graph-builders-should-graphviz-provide-more-help/2097)
- [Where does generating the graph take most of the time?](https://forum.graphviz.org/t/where-does-generating-the-graph-take-most-of-the-time/668)

These posts already contained some very insightful information. I understand that DOT is not really suitable for graphs with the amount of nodes that I currently have. However, I believe that the properties of the output of this layout engine are the best fit for the output graph layout I see as fitting for my project. When I tried to switch layout engines, to see if that would result in quick relieve, I didn’t get any immediate results (within few minutes), and ended up aborting the rendering process. I’m happy to return to evaluating more alternatives now, if guided that way.

As mentioned in the intro, rendering the `.gv` currently takes about 10 hours to complete on my machine (Intel Xeon E5-2687W v4 @ 3.00GHz). The majority of time is consumed in the “network simplex” phase. I do not want to reduce the quality of the final output, just to make the process faster. I still want to end up with the most beautiful splines possible, and the least amount of crossings. As I also render the GV code itself, I am also free to approach the problems at any layer of the solution.

Feedback and guidance would be appreciated 🙂

---

<div class="post-metadata">

**Author:** ![mark](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/mark/32/84_2.png) [@mark](https://forum.graphviz.org/u/mark)\
**Post date:** [July 2, 2025, 12:08pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/2 "2025-07-02T12:08:53Z")

</div>

Fun prompt. First up, my actual advice: maybe shard your graph by year and then re-concatenate it?

But then let’s take this at face value. Why is it slow?

I ran this on my macbook pro M4 with dot installed from homebrew, profiling with [GitHub - mstange/samply: Command-line sampling profiler for macOS, Linux, and Windows](https://github.com/mstange/samply), cutting it off after 60 seconds:

```auto
$ dot --version
dot - graphviz version 13.1.0 (20250701.0955)
$ samply record --duration 60 dot ~/Downloads/universe.gv -Tsvg

```

I get this profile: [Firefox Profiler](https://profiler.firefox.com/public/et5v3kx0edh2hk8mfm1ffwnxxvfsjmffx4td6b8/flame-graph/). Width of bars corresponds to time.

It’s mostly `dfs_enter_inedge` or doing a depth first search. I try to remove recursion (right click on a frame and click collapse direct recursion) my browser hangs, lol. There’s so much recursion here that the profiler UI is struggling. At any rate, here’s `dfs_enter_inedge`: [lib/common/ns.c · main · graphviz / graphviz · GitLab](https://gitlab.com/graphviz/graphviz/-/blob/main/lib/common/ns.c#L247-267)

---

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 2, 2025, 12:19pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/3 "2025-07-02T12:19:45Z")

</div>

Interesting! I will look into that, and see if I can derive new actions. Thanks 🙂

Regarding the years, I actually have a feature to “cluster years” (places all events in the same year into a cluster), which I had much fun with initially. However, this led me to issues that would cause dot to abort the rendering process due to internal issues, so I dropped playing with that idea a while ago. However, I understand that you’re suggesting something different, and I will need to think about if I can utilize that idea somehow. Thanks.

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 2, 2025, 2:42pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/4 "2025-07-02T14:42:18Z")

</div>

You are misusing the **minlen** attribute ([minlen | Graphviz](https://www.graphviz.org/docs/attrs/minlen/)). **Minlen** should be an integer that expresses the _number of ranks_ (not inches or pixels) between tail & head for a specific edge.  
The result is that **dot** assigns **20703** ranks to the graph. This causes network simplex to run for as long as it does.  
By removing all the **minlen** references, we get **1748** ranks.  
And **dot** will complete in \<3 minutes. Yea!  
If you are not satisfied with the result without **minlen** , we can probably help.

p.s. Cool graph  
p.p.s. I was in college in 1969.

---

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 2, 2025, 4:46pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/5 "2025-07-02T16:46:07Z")

</div>

You’re definitely right in that I apparently misunderstood how to use `minlen`. I will have to tinker a bit to readjust my understanding of things.

My understanding of `minlen` was, if it is `>1`, then the node pointed to will be placed on a new rank. So my application calculates the time distance between two events, then calculates how that distance relates to the “base unit” of the graph - day, week, or month. If the base unit is “day”, and two events are more than 24h apart, the minlen should reflect that in being `>1`, so that the event on the new day is also on a new rank.

Similarly, when the base unit is “week”, all events within the time range of a week will share the same rank. This is an important property to receive a visual result that reflects time distances, and identical timestamps shared between individual data sets end up in the correct location in the output.

So, in my mind, the 20703 ranks were “correct”, because that is likely the number of discrete days in the graph (or at least closely related to that metric), which should also occupy distinct ranks.

That being said, I shall see if I can achieve a satisfying result, given this new information, and then I’ll return. Thanks a lot!

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 2, 2025, 5:07pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/6 "2025-07-02T17:07:25Z")

</div>

(I hope my understanding of the algorithm is correct)  
The “problem” is that **dot** creates (many) _virtual_ nodes along the long edges, and that causes the long run time. (see [https://www.graphviz.org/documentation/TSE93.pdf](https://www.graphviz.org/documentation/TSE93.pdf))  
However, maybe we can get the best of both worlds.  
Let me think about a post-processor that would “stretch” the 1748 rank version to recreate the desired distances.

---

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 2, 2025, 5:45pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/7 "2025-07-02T17:45:38Z")

</div>

I also had this feeling that my entire approach causes too much work, because I don’t prepare the data well enough. Ultimately, I know the time of the events, and I know the exact distance I want between any two events. This is pretty solid information that is not directly translated into useful constraints for dot to use (I believe). As long as the output was generated quickly, and the result looked right, I didn’t care that my approach might not be ideal. But I was wondering if it could be beneficial to try to use neato guided by pre-calculated `pos` attributes. Just another thing for me to evaluate though. 🙂

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 2, 2025, 6:15pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/8 "2025-07-02T18:15:56Z")

</div>

Do you want the events on a rank to appear in chronological order? (i.e. if a rank==1 week, should friday events always follow thursday events?)  
If so, then

- add an explicit timestamp attribute (e.g. … ts=xyz …)
- run `dot -Tdot -Gphase=1 universe.gv -o universe.dot`.  
This will give all the node heights & widths.
- then write a **gvpr** ([https://www.graphviz.org/pdf/gvpr.1.pdf](https://www.graphviz.org/pdf/gvpr.1.pdf)) or **python** or whatever program to do the **pos** calculations (in _points_)
- run that through `neato -n myfile` and neato will lay out the splines.

---

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 2, 2025, 9:42pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/9 "2025-07-02T21:42:06Z")

</div>

Thanks again for this very helpful guidance. I feel like I can now see my fundamental misunderstandings in terms of ranks and positioning. A lot of my naive observations seem to make sense now, which gets a lot of thoughts rolling.

I started to correct my `minlen` calculation to integer values. This also allowed me to finally fix carrying over fractional time parts into the next rank. Now the `minlen` also more clearly relates to the “base unit” of the graph, which is neat. However, this had no noticeable impact on rendering performance, of which there was no expectation.

The real suggestion was to drop `minlen` anyway, so I also did that. The result is surprisingly pleasing, given how much importance I placed on this detail of my graph. This is giving me food for thought. At the very least, this will be my new default _preview_ version to use while working on the data. Awesome!

Given this output, I can also better understand the suggestion to work from this version and just adjust the position according to time scale in a later step. This seems much more feasible than getting used to renderings taking in the area of days.

For clarity, the graph and the data sets on GitHub are only for public discussion of the project. There is a _real_ data set, with private information that details my own entire life, and that of people related to me, which is merged with the public data to create the _real_ image. In that version, the edges of the individual timelines also merge into single nodes, if timelines have shared entries that would result in duplicate nodes. The 10h benchmark is for the public data set. The private data set hasn’t been rendered in weeks. I assume it heavily outweighs the 20K ranks.

It was actually very hard for me to reproduce my problems with the public data set. For the longest time, it just would not work. Until I decided to add the start of the UNIX epoch as a world event the other day. I didn’t understand that fully at the time, but somehow realized that my private data set problems also started when I added the birth date of parents. This had already confused me, but I assumed it was somehow a result of the timestamps being negative, and me not handling time travel properly in my own code.

I now understand (hopefully) that the answer is simply the `minlen` forcing thousands of empty ranks at the start of the graph. Which also answers why another one of my performance boosts was the logarithmic scale for event spacing, as that just results in less empty ranks as well.

I hope I can get to remaining suggestion soon, but your help might have already enabled me to pile on more data again 😃

@steveroush If I may ask, was the singer “Oliver” a big deal in 69? I came across him the other day while “time traveling”, and looking for who might have inspired my own name. My senses tell me you mentioned that specific year, because you have required information to solve this side quest 😃

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 2, 2025, 10:29pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/10 "2025-07-02T22:29:33Z")

</div>

If you compute the node **pos** values (remember: in points) and feed the result to `neato -n`, the run time will be just a few seconds. But note that **neato** uses a somewhat different algorithm for laying out the splines. Probably OK, but give it a try.

Though I remember “Good Morning Starshine”, my 1969 comment referred to the 1st node - “Monty Python’s Flying Circus Season 1 … 05.10.1969”

---

<div class="post-metadata">

**Author:** ![smattr](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/smattr/32/85_2.png) [@smattr](https://forum.graphviz.org/u/smattr)\
**Post date:** [July 3, 2025, 10:09pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/11 "2025-07-03T22:09:52Z")

</div>

The `dfs_*` functions are the bottleneck of the vast majority of performance problems we get reported about Graphviz. I’m not aware of any remaining low hanging performance improvement opportunities there. Someone will probably have to consult the literature and come up with an algorithmic network simplex improvement.

Nevertheless, I’ve filed this as another perf test case for us to investigate: [10h SVG Render Process (#2702) · Issues · graphviz / graphviz · GitLab](https://gitlab.com/graphviz/graphviz/-/issues/2702)

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 3, 2025, 11:43pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/12 "2025-07-03T23:43:10Z")

</div>

Here is another [case](https://forum.graphviz.org/t/segfault-during-a-rendering-of-a-tree/2740) where (misused) **minlen** caused grief.  
Dot is challenged by graphs with many ranks (thousands, tens of thousands).  
Sometimes they are “real” ranks (many nodes & many of edges), sometimes “kind of real” ranks (virtual nodes added for edge labels), and sometimes “possibly avoidable?” ranks (virtual nodes & edges added just to pad out the **minlen** value) . As in the two graphs mentioned above.  
It would seem possible to remove “unnecessary” virtual nodes & edges for phase 3 (2nd network simplex) and then restore them afterwards.

Here is a tiny example of **minlen** gone bad (core dump):

```auto
/***
goal: - a graph that would calse phase=3 performance problems
***/
digraph tall{
  edge[minlen=50000]
  a -> {b c d e f}
  edge[minlen=50500]  
  b -> {g h i}
}

```

---

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 4, 2025, 11:17am UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/13 "2025-07-04T11:17:32Z")

</div>

This is all highly educational, and makes me feel like GraphViz was definitely the correct pick for this project. It’s highly versatile tooling that seems less magic the more I learn about it. Working with the distinct individual phases of the process is something I haven’t touched at all, yet. So far, I figured that most of my future work would happen exclusively on the SVG layer, after rendering.

After working more with the version that has no `minlen` properties, it grows on me. More density seems more aesthetically pleasing and impressive, than having to scroll through empty time-space. The latter also has its merits, but I feel like I will enjoy the journey ahead more if I ignore the spacing for the time being, and focus on other aspects of the work that have more short-term rewards. I will most definitely pick it up again though, for the included learning experience.

As soon as I end up with a working implementation of the remaining suggestion, I will definitely share it here for future readers.

---

<div class="post-metadata">

**Author:** ![scnorth](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/scnorth/32/89_2.png) [@scnorth](https://forum.graphviz.org/u/scnorth)\
**Post date:** [July 4, 2025, 11:41pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/14 "2025-07-04T23:41:58Z")

</div>

As an alternative, there’s this work on incremental or dynamic visual exploration of “hierarchical” or layered graphs, that’s been gestating for a long time (see [North Woodhull 2001](https://www.graphviz.org/documentation/NW01.pdf)) and looks great in [this demo](https://dc-js.github.io/dc.graph.js/explore.html?file=world.gv&layout=dynadag&expandedIn=3%7C4%7C11%7C26%7C38%7C42&expandedOut=4%7C26%7C43).

---

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 20, 2025, 10:46am UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/15 "2025-07-20T10:46:58Z")

</div>

Status update:

I’ve mostly abandoned the idea to force empty space into the graph to illustrate time. This provides very little long-term incentive to work on the project. What proved much more exciting is pouring in more and more data to increase the overall complexity and density. This, unsurprisingly, lead to the same performance issues I had with the forced ranks.

I didn’t want to get into stitching, but it still seemed like the right-long term approach to split the workload. As my dataset grew, and now spans 200 years, it made sense to split the work for user/developer experience reasons. Being able to produce defined slices as graphs is tremendously useful and opens up new paths of thinking.

I also had to build a viewer experience, to make navigation in the large SVG a bit easier. So attention is constantly being split up between several areas of development 🙂

---

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 26, 2025, 3:00pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/16 "2025-07-26T15:00:58Z")

</div>

Where can I read more about this “phase” setting?

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 26, 2025, 9:16pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/17 "2025-07-26T21:16:00Z")

</div>

- [This document](https://www.graphviz.org/documentation/TSE93.pdf) explains the _phases_, but uses the word _pass_.
- [This issue](https://gitlab.com/graphviz/graphviz/-/issues/2540) added debugging information to the output (if **-v** added to the command line)
- Here is [an issue](https://gitlab.com/graphviz/graphviz.gitlab.io/-/issues/75) to document the **phase** attribute - still a future item

Here is a Linux command line that uses **phase**. It provides run times for each phase (additive). The **stdout** files show how **dot** builds the final graph and the **stderr** files help one understand what fast & slow look like.

```auto
f=myFile.gv;
T=svg;
for P in 1 2 3 4 999;do # 999 means run completely
  F=${f%.*}.$P;
  echo -e "\n$F" >&2
  time -p dot -v -Gphase=$P $f -T$T -o$F.$T 2>$F.errs ;
done
```

---

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 27, 2025, 11:58am UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/18 "2025-07-27T11:58:45Z")

</div>

Amazing. Thank you so much.

I’ve now started to experiment with pre-calculated positions and using `neato -n`. It really only takes seconds to complete, even on my largest graphs. The amount of control is exciting, but I will have to think more about potential layouts now.

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 27, 2025, 3:15pm UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/19 "2025-07-27T15:15:25Z")

</div>

You can use `dot -Gphase=1 myfile.gv` to get node sizing & ranking. It usually runs in ~1 second.

---

<div class="post-metadata">

**Author:** ![oliversalzburg](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/oliversalzburg/32/2010_2.png) [@oliversalzburg](https://forum.graphviz.org/u/oliversalzburg)\
**Post date:** [July 28, 2025, 9:22am UTC](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062/20 "2025-07-28T09:22:29Z")

</div>

That’s what I started with to work on the earlier suggestion with precomputed positions. I also implemented the suggestion to add a `ts` property, then derive positions from that in the phase 1 output, and write back new `pos` coordinates. Once I got the layout collision-free, everything worked as suggested. The performance is excellent, but my layout is not nearly as pleasing as what dot would produce. It did inspire me to look into an alternative layout, where I order everything into fixed “lanes”, but this is only an idea so far.

Just being able to see these different phase outputs, having the ability to modify the instructions, and experiment with rendering the result, is extremely helpful to see additional potential.

Seeing the dot phase outputs, I was very quickly drawn to the stitching idea again. By now, I render 10year segments, which raise hardly any performance concerns. I want to add invisible control nodes to place stitching anchors at the top and bottom of the graph now. Then I want to experiment with applying different methods at individual stages to build the final document.

I allow myself to be distracted by any other area of the project. So I also spent considerable time to write a dot transformer that replaces emoji by embedded images, so Windows users in my family also see country flags in their Chromium browsers. This then had to be expanded again, because I needed to have historic flags also. The project also ignited the first ever reconstruction of our ancestor history, which we now have documented back 200 years in the graph. There’s a lot of history research going on now, and family members are actively waiting for the next update to the “time machine” being delivered. The project is a real pleasure that literally brings the family together. 🙂

[Next page](https://forum.graphviz.org/t/dot-is-no-longer-my-friend-what-can-i-do-10h-svg-render-process/3062.md?page=2)
