ericg
ericg

Reputation: 8722

how to define a graph with graphviz without overlapping labels

The follow dot file demonstrates the issue I am trying to resolve:

digraph G {
    splines=line;
    rankdir=LR;
    A -> B [label="a long label"];
    A -> C [label="a long label"];
    A -> A [label="a very long label"];
    A -> A [label="a very long label"];
    A -> D [label="a long label"];
}

It generates the follow the graph:

Result Graph

The labels are poorly positioned, nearly overlapping.

What can be done to improve the look of this graph?

I would define improve by saying (1) labels do not overlap with each other, (2) labels do not overlap edges, and (3) optionally / ideally labels are drawn along the edge. #3 may not be possible, but #1 and #2 should be sufficient. Using ortho splines would always provide an edge where a which a label could be drawn along and still be read normally, but this I know is not currently supported by graphviz.

Upvotes: 1

Views: 1880

Answers (2)

ericg
ericg

Reputation: 8722

There does not appear to be any supported solution in GraphViz that meet the desired criteria for edge labels. My work around is to split the edges between two nodes and insert another node containing the text of the edge label. The new node is styled to distinguish it from regular nodes.

The GraphViz layout algorithm does a good job of keep nodes separated and not allowing edges to overlap nodes.

Updating the test case with this workaround, I have the following dot file:

digraph G {
    splines=ortho;
    rankdir=LR;

    AA1 [label="a very long label", shape="box", style = "filled", fillcolor = "#E6E6E6", color = "#FFFFFF" ] 
    AA2 [label="a very long label", shape="box", style = "filled", fillcolor = "#E6E6E6", color = "#FFFFFF" ] 
    AB1 [label="a long label", shape="box", style = "filled", fillcolor = "#E6E6E6", color = "#FFFFFF" ] 
    AC1 [label="a long label", shape="box", style = "filled", fillcolor = "#E6E6E6", color = "#FFFFFF" ] 
    AD1 [label="a long label", shape="box", style = "filled", fillcolor = "#E6E6E6", color = "#FFFFFF" ] 

    A   -> AA1 [arrowhead = "none" ];
    AA1 -> A 
    A   -> AA2 [arrowhead = "none" ];
    AA2 -> A 

    A   -> AB1 [arrowhead = "none" ];
    AB1 -> B

    A   -> AC1 [arrowhead = "none" ];
    AC1 -> C

    A   -> AD1 [arrowhead = "none" ];
    AD1 -> D
}

which produces this graph

Upvotes: 1

sroush
sroush

Reputation: 6763

"Improve" is in the eye of the beholder, but this uses ports, headlabels, spaces and newlines to rearrange the labels.

digraph G {
    splines=line;
    rankdir=LR;
    // use ports to rearrange edges 
    // then headlabel, spaces, and newlines (\n)
    A:n -> A:w [headlabel="a very long label    "];  
    A:s -> A:w [headlabel="a very long label    "];  
    A -> B [label="a long label"];
    A -> C [label="a long label"];
    A -> D [label="\n\na long label"];
}

enter image description here

Upvotes: 2

Related Questions