A bit of light must be shed on long-running (endless?) feature “native rendering”.

SiebenApp was inspired mostly by GraphViz. GraphViz uses Sugiyama framework to draw graphs. So, SiebenApp tries too.

This method consists of several steps. Some of them are already implemented in SiebenApp, some not.

  • Cycle removal. At the very beginning we must remove all loops from graph, making it acyclic. Since SiebenApp allows to create only acyclic goal graphs by logical reasons, this step may be considered to be done automatically.
  • Layer assignment. Each vertex (goal) must be assigned to a level. This was implemented quite recently using “Minimum width” algorithm. This algorithm restricts a number of goals assigned to a level, which makes it more suitable to the limited window width comparing to implementation in dot. With limited width you don’t need to scroll window content left and right all the time. As a tradeoff, resulting graph has greater height and longer edges. I hope to improve this situation later.
  • Vertex ordering. On each layer, goals are sorted in order to reduce edge intersections. This step is important because it greatly reduces chaos in graph. Currently, I’m fighting with this stage. I cannot consider task finished until I get some kind of goal sorting.
  • Coordinate assignment. After all, goals should be properly placed on a layer. In current implementation this is made by some kind of “hack”. I just use QGridLayout to place goals in a row. This looks quite ugly but was easy to implement. Sometimes in future I’ll have to fix this.

Currently, it looks like this:

goals intersected with edges

As you can see, a number of edge-edge and edge-goal intersections is big. This is the main reason why I haven’t switched rendering to the native implementation yet.

But! Despite of its uglyness, it’s already working on any desktop platform that supports Qt and doesn’t require GraphViz.

So I hope, someone may find it interesting or even useful. As for myself, I use it almost every day :)