Number: 2168
Title: Text on self-edges of a node is poorly placed
Submitter: David Claughton
Date: 10 Apr 2011
Subsys: dot
Version: Reported against 2.26.3, confirmed with recent snapshots.
System: Debian GNU/Linux SID
Severity: minor
Problem:
Hi,

eddy@opera.com has reported the following bug to the debian BTS (#620801) ...

I'm making a digraph showing state-transitions for the terrain in freeciv; a simple dot file has done very nicely for the transitions between states; irrigation (blue arcs) turns forest into plains, mining converts back, etc. When I try to add arcs indicating 'internal' state transitions - irrigating hills doesn't change the fact that they're hills but does improve their food output - I run up against a limitation on the placement of text on such self-arrows.

By default, all the self-arrows come out on the right; when there are several on a node, each self-edge's loop goes round the last one's label and nodes are moved apart enough to make room for these edges and labels. This is all readable but aesthetically messy; it would look nicer if self-edges protruded in different directions so as not to push one another further from the node to which they relate. I can set the headport and tailport to move the edges around, but it turns out that the placement of their text labels is then messed up.

If I put an edge :nw->:nw or :sw->:sw, its text gets placed exactly as if the edge were :w->:w (and in a position sensible for this port but not for nw or sw). So I can only put one label (hence one edge) on the left. Fortunately (!) this is asymmetric: :se->:se and :ne->:ne are placed differently than one another and :e->:e (the default).

Sadly, however, even then I see a more severe problem, also present for the left-side self-loops: node, edge and label positions are not adjusted to make space for the labels of non-default-port self-loops.

While I may be able to concoct some abomination of a way to stretch labelangle and labeldistance to work round this, the default clearly does take account of label texts when placing the rest of the graph and its labels, so it's a shame that setting an edge's ports breaks that. Example small dot file [see below] showing all symptoms described above:

Note that the graph-drawing *does* take account of the self-edges, it's only the labels that are left out of consideration; and the :e->:e edge's label, unlike all others, *is* correctly provided for (delete its line to see Left and Right move closer together, causing West to overlap Left instead of East), even when its ports are specified explicitly as :e (where the default isn't actually representable by specifying port; it's sort of :ene->ese; remove the :e specifiers to see the edge loop open up a bit without the nodes or labels moving).

Some of the problems are alleviated if I use different ports for head and tail; but, even then, some label texts overlap other label texts.

I normally emit the image as SVG using /usr/bin/dot -Tsvg (automated by a .htaccess hack and a cgi-bin script in my local web-server) but see exactly the same result when running dot -Tpng manually. (For my reference: http://vortex/~eddy/img/misc/graphviz-label-placement-bug.dot is my local copy.)
Input:

digraph BugExample {
  /* Trivial graph: */
  "Left" -> "Bottom" [label="Down Right"];
  "Right" -> "Bottom" [label="Down Left"];
  /* Two left self-edge labels collide: */
  "Left":nw -> "Left":nw [label="North-West"];
  "Left":sw -> "Left":sw [label="South-West"];
  /* Self-edge labels collide with normal edge label ("Down Right"): */
  "Left":se -> "Left":se [label="South-East"];
  "Bottom":ne -> "Bottom":ne [label="North-East"];
  /* Labels over-lap one another and nodes */
  "Right":w -> "Right":w [label="West"];
  /* Skip this last to see "West" overlap "Left" instead of "East": */
  "Left":e -> "Left":e [label="East"];
}
Owner: *
Status: *