49

By default in Graphviz, edge labels are placed just to the right of the edge. I'm looking for a way to place the labels OVER the edge, centred on the edge. (It'll still be readable because I'm changing the colour of the edge).

Any ideas?

l0b0
  • 55,365
  • 30
  • 138
  • 223
naught101
  • 18,687
  • 19
  • 90
  • 138

4 Answers4

23

If this was headlabel or taillabel, you could try setting labeldistance to zero to force the label to be drawn on the edge, but as I understand, you are referring to edge label (the one on the middle of the edge). Documentation quite clearly states that labeldistance only affects headlabel and taillabel labels, but you can try your luck.

One other thing you might want to try is to make a transparent, intermediary node with a label on it. It could look like you want... But if you heavily rely on node placement algorithm, it could be unacceptable to create those 'artificial' nodes. In that case, I encourage you to join graphviz developers and add the feature you need ;) Seriously, it is very satisfying.

If you find another solution, please post it. I will be facing a similar problem in the near future.

d-cubed
  • 1,034
  • 5
  • 30
  • 58
Paweł Polewicz
  • 3,711
  • 2
  • 20
  • 24
  • Yeah, looks like that's the whole of it at the moment. I will consider contributing to graphviz, but like you, my problem isn't going to be a problem for at leat another few months. – naught101 Nov 28 '10 at 23:11
  • did anyone ever end up add functionality to align labels along edges? I am new to graphviz, just installed 2.38, and would love to do that. – Riggster Dec 01 '19 at 22:58
6

Consider adding a few blank spaces after your label. That way you are avoiding overlap with your edge arrow since graphviz labels are right-aligned. This is not an elegant solution and I would love to see a proper label alignment but it might solve your problem.

1

Based on the previous two answers, here is my solution use taillabel/labeldistance, transparent edge and blank spaces.

If there is only one edge between two nodes, use a transparent edge. below is an example with the result.

digraph G {
    rankdir=BT;
    A -> B [label="               ", minlen=3, headlabel="A overlay text\non edge", labeldistance=8];
    B -> A [color=white];
}

overlay

If there are two edges between two nodes, no need to use transparent edge, just use blank spaces to adjust their relative position and make the text is truely overlay on top of edges.

digraph G {
    rankdir=BT;
    A -> B [label="                    ", minlen=3, headlabel="An overlay\ntext", labeldistance=6];
    B -> A [headlabel="       B to A", labeldistance=4];
}

overlay2

alijandro
  • 11,627
  • 2
  • 58
  • 74
1

This was recently discussed (by me) in the Graphviz forum (https://forum.graphviz.org/t/fun-with-edge-labels/1643). The discussion includes a link to a post-processor written in gvpr (https://www.graphviz.org/pdf/gvpr.1.pdf) (part of the Graphviz system) that will allow the user to reposition edge labels, including on-top-of the edge itself.
Below is an example of the input dot program and the result. Note that in many cases the label placement was intentionally not centered.
Not a general-purpose solution, but useful in many cases.

graph straight {
  splines=false
  edge [label="\T" labelOverlay=true color=purple]
  node [shape=rect style=filled fillcolor=lightblue]

    a1 -- b1
    c1 -- d1  [labelOverlay="15%" label=high]
    e1 -- f1  [label2node=true labelOverlay="75%" label=low]
    g1:sw -- h1:nw  
    g1:s -- h1:n  [labelOverlay="20%"]
    g1:se -- h1:ne  
    j1 -- k1  [ label2node=true]

  node[shape=square style=filled fillcolor=lightgreen]
    {rank=sink
    edge [fontcolor=red]
    Aaa -- B3  [labelOverlay="33%"]
    C98 -- D3  [labelOverlay="80%" label2node=true]
    Eee -- F6  [label="adjust me" labelAdjust="45,-25"]
    G12 -- H3  [label2node=true]
    node [shape=plain fontcolor=blue style=""]
    Lxx -- M123
    Noo -- Ooo [label2node=true]
    node [shape=oval fontcolor=blue style=""]
    P  -- Q
    }

    node[shape=circle style=filled fillcolor=pink]
    edge [label2node=true label="aeiou" labelOverlay="78%"]
    10 -- {11 12}
    10 -- 13 [labelOverlay="38%"]    
    10 -- 14 [labelOverlay="62%"]    
    edge [label="three"]
    node [shape=Mrecord]
    13 --  21
    edge [labelOverlay="55%" label="T\nh\nr\ne\ne\n \n33"] 13 -- 22
    edge [labelOverlay="60%"] 13 -- 23
}

enter image description here

sroush
  • 5,375
  • 2
  • 5
  • 11