How to use xlp attribute for positioning of external labels (xlabel)?

I have tried to apply xlabels on my graphs and position them using xlp. But the xlp attribute seems to have no effect,

and the xlabels are all attached to the top-left corner of nodes. Is it a bug or am I misusing it?

Here is a sample code:

digraph g {
forcelabels=true;
ranksep=0.25;
node [shape=point,height=0.1];
"1" [xlabel=<abc>,xlp="-1.0,1.0",fillcolor=yellow,height=0.2];
"2" [xlabel=<abc>,xlp="10.0,-10.0",fillcolor=dimgray,height=0.1];
"3" [xlabel=<abc>,xlp="1000.0,1000.0",fillcolor=dimgray,height=0.1];
"1" -> "2"[label=<A3:B4>,arrowsize=0.4];
"1" -> "3"[label=<C3:B4>,arrowsize=0.4];
}

After generating a pdf (attached), all 'abc' xlabels are placed in top-left corners of nodes. Whereas I would like to control their placement myself,

preferable by specifying the location relatively to the node.
Tags No tags attached.

AttachmentSize
xlabel.pdf9.05 KB

Interpreting the contents of pos for edge

I plan to draw only straight line segments for edges so I set splines=line; Then according to the description of spline, it consists of an end point, a start point, and some interior points. From a typical pos for spline=line;

pos="e,40.154,35.796 58.657,108.44 53.93,89.877 46.259,59.763 41.142,39.674"

it would appear that the first and second points represent the line endpoints. So the center point of the line would be the average of these two points, or 49.4,72.1 in this example. The xlabel offset for a straight line segment would then be from this center point.

The xlp attribute is only

The xlp attribute is only used to record position information in global coordinates; it is never used by the layout programs for input. What you want is a new feature.

However, you can get what you want now if you are willing to post-process the output. To do this, store the label positions as a different attribute, say, nlp, and to make things simple, use points as the unit. Suppose your file is lb.gv and contains the following:

digraph g {
forcelabels=true;
ranksep=0.25;
node [shape=point,height=0.1];
"1" [xlabel=<abc>,nlp="-9.0,9.0",fillcolor=yellow,height=0.2];
"2" [xlabel=<abc>,nlp="9.0,-9.0",fillcolor=dimgray,height=0.1];
"3" [xlabel=<abc>,nlp="9.0,9.0",fillcolor=dimgray,height=0.1];
"1" -> "2"[label=<A3:B4>,arrowsize=0.4];
"1" ->"3"[label=<C3:B4>,arrowsize=0.4];
}

Then run

    dot lb.gv | gvpr -c -f l.g | neato -Tpdf -n2 > xlabel.pdf

where the file l.g contains

N[$.nlp!=""]{
 double x, y, lx, ly;
 sscanf($.pos,"%f,%f",&x,&y);
 sscanf($.nlp,"%f,%f",&lx,&ly);
 $.xlp = sprintf("%.03f,%.03f",x+lx,y+ly);
}

Basically, the gvpr script replaces the xlabel positions generated by dot with the ones you want.

One caveat: When checking on this, I found a bug in neato. For the above to work, you'll need to upgrade your Graphviz to tomorrow's (15 Jan 2014) version. Or if you build from source, I can send you the patch.

 

 

Position xlabel relative to center of edge

The suggested fix to position xlabels relative to nodes works great. Now I would like to extend the fix to position xlabels relative to the center of edges. Problem is that dot generates different pos information for edges than for nodes, so a different conversion process is required for edges. I could probably modify the l.g file to handle edges if I could figure out what the pos numbers mean for edges.

Typical pos for node is
pos="62.876,126"

Typical pos for edge is
pos="e,40.154,35.796 58.657,108.44 53.93,89.877 46.259,59.763 41.142,39.674"

From these pos numbers for edge I'm guessing I can compute the center of the edge if not already there. Where can I locate the definition of these numbers?

I probably need to understand spline type:

splineType

spline ( ';' spline )*

where spline
=
(endp)? (startp)? point (triple)+

and triple
=
point point point

and endp
=
"e,%f,%f"

and startp
=
"s,%f,%f"

If a spline has points p1 p2 p3 ... pn, (n = 1 (mod 3)), the points correspond to the control points of a cubic B-spline from p1 to pn. If startp is given, it touches one node of the edge, and the arrowhead goes from p1 to startp. If startp is not given, p1 touches a node. Similarly for pn and endp.

Then perhaps pos depends on the particular spline type assigned to the edge?

 

Recent comments