This project wraps libavoid into an executable that can run in the background of an application to provide edge routing for graphs with fixed node positions.
The program listens for requests to standard input and writes results to standard output. Edge routing requests are separated with the character sequence
[CHUNK]
followed by a new line character (\n
). All other commands documented below must be written in separate lines as well.
A general layout option is applied using a line with the format
OPTION {id} {value}
where {id}
is the identifier of the layout option and {value}
is a value for that option. The following layout options are supported:
Note: The edgeRouting
option must be applied before all other configuration parameters.
An additional option that is not part of libavoid:
enableHyperedgesFromCommonSource
This option creates hyperedges for all edges that share a common source. This is a post-process step and therefore adds additional computation time to the original layout run.
A routing option is applied using a line with the format
ROUTINGOPTION {id} {value}
where {id}
is the identifier of the routing option and {value}
is a Boolean value to assign. The following routing option ids are available:
nudgeOrthogonalSegmentsConnectedToShapes
improveHyperedgeRoutesMovingJunctions
penaliseOrthogonalSharedPathsAtConnEnds
nudgeOrthogonalTouchingColinearSegments
performUnifyingNudgingPreprocessingStep
improveHyperedgeRoutesMovingAddingAndDeletingJunctions
Their meaning is documented in the libavoid documentation.
A routing penalty is applied using a line with the format
PENALTY {id} {value}
where {id}
is the identifier of the routing penalty and {value}
is a numeric value to assign. The following penalty ids are available:
segmentPenalty
anglePenalty
crossingPenalty
clusterCrossingPenalty
fixedSharedPathPenalty
portDirectionPenalty
shapeBufferDistance
idealNudgingDistance
Their meaning is documented in the libavoid documentation.
Once all parameters have been set, you start the graph definition with the line
GRAPH
and you end it with the line
GRAPHEND
Between the two lines delimiting the graph, a node is added using a line with the format
NODE {id} {x1} {y1} {x2} {y2} {incoming} {outgoing}
with the following placeholders:
{id}
– numeric (integer) identifier of the node{x1}
– horizontal position of the top left corner{y1}
– vertical position of the top left corner{x2}
– horizontal position of the bottom right corner{y2}
– vertical position of the bottom right corner{incoming}
– number of incoming edges that are not connected to a port{outgoing}
– number of outgoing edges that are not connected to a port
A port is added to a node using a line with the format
PORT {port id} {node id} {side} {x} {y}
with the following placeholders:
{port id}
– numeric (integer) identifier of the port{node id}
– identifier of the node to which the port belongs{side}
– side of the node on which the port is placed, eitherNORTH
,EAST
,SOUTH
orWEST
{x}
– horizontal position of the port center{y}
– vertical position of the port center
An edge is added between two nodes or ports using a line with the format
{edge type} {edge id} {source node id} {target node id} {source port id} {target port id}
with the following placeholders:
{edge type}
–PEDGEP
for a port-to-port edge,PEDGE
for a port-to-node edge,EDGEP
for a node-to-port edge, orEDGE
for a node-to-node edge{edge id}
– numeric (integer) identifier of the edge{source node id}
– identifier of the source node (or the node containing the source port){target node id}
– identifier of the target node (or the node containing the target port){source port id}
– identifier of the source port (ignored if there is none){target port id}
– identifier of the target port (ignored if there is none)
Between the two lines delimiting the graph, a cluster is added using a line with the format
CLUSTER {id} {x1} {y1} {x2} {y2}
with the following placeholders:
{id}
– numeric (integer) identifier of the cluster{x1}
– horizontal position of the top left corner{y1}
– vertical position of the top left corner{x2}
– horizontal position of the bottom right corner{y2}
– vertical position of the bottom right corner
A cluster only allows edges to cross its borders if they have a source- or endpoint inside the cluster.
The output is written to stdout. It starts with the line
LAYOUT
and ends with the line
DONE
The actual content of the output is written between the two delimiter lines mentioned above. An edge layout has the format
EDGE {id}={route}
with the following placeholders:
{id}
– identifier of the edge{route}
– space-separated list of points specifying the route; each point is a pair of x/y positions
Input:
OPTION edgeRouting ORTHOGONAL
PENALTY segmentPenalty 10.0
PENALTY anglePenalty 0.0
PENALTY crossingPenalty 0.0
PENALTY clusterCrossingPenalty 4000.0
PENALTY fixedSharedPathPenalty 0.0
PENALTY portDirectionPenalty 100.0
PENALTY shapeBufferDistance 4.0
PENALTY idealNudgingDistance 0.0
PENALTY reverseDirectionPenalty 0.0
ROUTINGOPTION nudgeOrthogonalSegmentsConnectedToShapes false
ROUTINGOPTION improveHyperedgeRoutesMovingJunctions true
ROUTINGOPTION penaliseOrthogonalSharedPathsAtConnEnds false
ROUTINGOPTION nudgeOrthogonalTouchingColinearSegments false
ROUTINGOPTION performUnifyingNudgingPreprocessingStep true
ROUTINGOPTION improveHyperedgeRoutesMovingAddingAndDeletingJunctions true
ROUTINGOPTION nudgeSharedPathsWithCommonEndPoint true
GRAPH
NODE 1 0.0 0.0 0.0 0.0 0 0
NODE 2 0.0 0.0 0.0 0.0 0 0
NODE 3 0.0 0.0 0.0 0.0 0 0
NODE 4 0.0 0.0 0.0 0.0 0 0
NODE 5 20.0 20.0 50.0 50.0 0 0
PORT 5 5 EAST 32.5 12.5
PORT 6 5 EAST 32.5 22.5
NODE 6 80.0 20.0 110.0 50.0 0 0
PORT 7 6 WEST -2.5 14.5
NODE 7 150.0 30.0 180.0 60.0 0 0
PORT 8 7 WEST -2.5 14.5
PEDGEP 1 5 6 5 7
PEDGEP 2 5 7 6 8
GRAPHEND
Output:
LAYOUT
EDGE 1=50 32.5 65 32.5 65 34.5 80 34.5
EDGE 2=50 42.5 65 42.5 65 54 130 54 130 44.5 150 44.5
DONE
This project is licensed under Eclipse Public License v2.0. The libavoid library is licensed under GNU Lesser General Public License v2.1 and its source code is available at mjwybrow/adaptagrams.