public class OrthogonalPatternEdgeRouter extends AbstractLayoutStage
OrthogonalPatternEdgeRouter
routes edges orthogonally such that the resulting layout of the edges consists only
of vertical and horizontal segments.
Note that the location and size of the nodes in a diagram remains unchanged.
The edge router will not try to find a perfect route from source to edge (unlike to what EdgeRouter
does) but chooses the best path out of a set of fixed paths. The best path out of these possible paths is determined by
its cost. The costs may be influenced by setting several cost factors. The distance that an edge will have from its
source and target node is determined by MinimumDistance
.
The edges whose paths have to be routed can be defined registering a IDataProvider
with key
DEFAULT_AFFECTED_EDGES_DPKEY
.
Modifier and Type | Field and Description |
---|---|
static EdgeDpKey<Boolean> |
DEFAULT_AFFECTED_EDGES_DPKEY
A
DataProvider key for determining which edges are routed.
|
Constructor and Description |
---|
OrthogonalPatternEdgeRouter()
Creates a new instance of
OrthogonalPatternEdgeRouter with default settings. |
Modifier and Type | Method and Description |
---|---|
void |
applyLayout(LayoutGraph graph)
Routes the edges of the given graph orthogonally.
|
protected double |
calculateBendCost(Edge edge,
YList path,
PortCandidate spc,
PortCandidate tpc)
Calculates the costs for all bends of the given path.
|
protected double |
calculateCost(Edge edge,
YList path,
PortCandidate spc,
PortCandidate tpc)
Calculates the edge cost of a possible edge path, in order to determine which path is the best, i.e., the cheapest.
|
protected double |
calculateCrossingCosts(Edge edge,
YList path,
PortCandidate spc,
PortCandidate tpc)
Calculates the overall crossing costs of the given path, including edge crossings, edge overlaps and node crossings.
|
protected double |
calculateEdgeLength(Edge edge,
YList path,
PortCandidate spc,
PortCandidate tpc)
Calculates the costs for the length of the given path.
|
protected double |
calculatePortCandidateCost(Edge edge,
YList path,
PortCandidate spc,
PortCandidate tpc)
Calculates the costs for the chosen
PortCandidate s. |
protected double |
calculateSelfLoopSelfSidePenaltyCost(Edge edge,
YList path,
PortCandidate spc,
PortCandidate tpc)
Calculates the extra penalty that is added to the path's cost if the edge is a self-loop and source and target ports
have the same direction.
|
protected void |
checkNodeSize(LayoutGraph g)
Checks the sizes of the nodes to be non-zero.
|
Object |
getAffectedEdgesDpKey()
Gets the key to register a
IDataProvider which determines the edges that shall be routed by this algorithm. |
double |
getBendCost()
Gets the costs for creating a bend on the edge's path.
|
double |
getEdgeCrossingCost()
Gets the costs for a crossing between two edges.
|
double |
getEdgeOverlapCost()
Gets the costs for overlapping edge paths.
|
YPoint |
getGridOrigin()
Gets the origin of the grid.
|
double |
getGridSpacing()
Gets the spacing of the grid on which edges are routed.
|
double |
getMinimumDistance()
Gets the minimum distance that an edge will maintain from its source and target node.
|
MonotonicPathRestriction |
getMonotonicPathRestriction()
Gets the monotonic path restriction that should be applied.
|
double |
getNodeCrossingCost()
Gets the costs for edges that cross nodes.
|
boolean |
isGridRouting()
Gets whether or not to route the edges on a grid.
|
void |
setAffectedEdgesDpKey(Object value)
Sets the key to register a
IDataProvider which determines the edges that shall be routed by this algorithm. |
void |
setBendCost(double value)
Sets the costs for creating a bend on the edge's path.
|
void |
setEdgeCrossingCost(double value)
Sets the costs for a crossing between two edges.
|
void |
setEdgeOverlapCost(double value)
Sets the costs for overlapping edge paths.
|
void |
setGridOrigin(YPoint value)
Sets the origin of the grid.
|
void |
setGridRouting(boolean value)
Sets whether or not to route the edges on a grid.
|
void |
setGridSpacing(double value)
Sets the spacing of the grid on which edges are routed.
|
void |
setMinimumDistance(double value)
Sets the minimum distance that an edge will maintain from its source and target node.
|
void |
setMonotonicPathRestriction(MonotonicPathRestriction value)
Sets the monotonic path restriction that should be applied.
|
void |
setNodeCrossingCost(double value)
Sets the costs for edges that cross nodes.
|
applyLayoutCore, getCoreLayout, setCoreLayout
public OrthogonalPatternEdgeRouter()
OrthogonalPatternEdgeRouter
with default settings.public void applyLayout(LayoutGraph graph)
applyLayout
in interface ILayoutAlgorithm
applyLayout
in class AbstractLayoutStage
graph
- the input graphprotected double calculateBendCost(Edge edge, YList path, PortCandidate spc, PortCandidate tpc)
This method is called by calculateCost(Edge, YList, PortCandidate, PortCandidate)
. The default implementation
multiplies the number of bends with the according
costs
. It may be overridden to change the calculation of these costs.
edge
- the edge for which the costs are calculatedpath
- the path of the given edgespc
- the source PortCandidate
for this edgetpc
- the target PortCandidate
for this edgeprotected double calculateCost(Edge edge, YList path, PortCandidate spc, PortCandidate tpc)
This method is called by applyLayout(LayoutGraph)
in order to decide which path is the best. The default
implementation considers the edge length, the number of bends, edge crossings,
PortCandidate
s and monotonic path restrictions. It may be overridden to apply a different set of costs or a
different weighting.
edge
- the edge whose costs to calculatepath
- the edge's pathspc
- the source PortCandidate
for this edgetpc
- the target PortCandidate
for this edgeprotected double calculateCrossingCosts(Edge edge, YList path, PortCandidate spc, PortCandidate tpc)
This method is called by
calculateCost(Edge, YList, PortCandidate, PortCandidate)
. The default implementation will determine
overlaps and crossings between edge segments and nodes and sum up the costs. It may be overridden to use a different
combination of costs.
edge
- the edge for which the costs are calculatedpath
- the path of the given edgespc
- the source PortCandidate
for this edgetpc
- the target PortCandidate
for this edgeprotected double calculateEdgeLength(Edge edge, YList path, PortCandidate spc, PortCandidate tpc)
This method is called by calculateCost(Edge, YList, PortCandidate, PortCandidate)
. The default implementation
returns costs between 0
for short paths and 1
for long paths. Hence, it has relatively little impact on
the overall costs. The method may be overridden to introduce a different weighting of the edge length.
edge
- the edge for which the costs are calculatedpath
- the path of the given edgespc
- the source PortCandidate
for this edgetpc
- the target PortCandidate
for this edgeprotected double calculatePortCandidateCost(Edge edge, YList path, PortCandidate spc, PortCandidate tpc)
PortCandidate
s.
This method is called by calculateCost(Edge, YList, PortCandidate, PortCandidate)
. The default implementation
will return the
candidates' costs
. It may be overridden to change the calculation of these costs.
edge
- the edge for which the costs are calculatedpath
- the path of the given edgespc
- the source PortCandidate
for this edgetpc
- the target PortCandidate
for this edgePortCandidate
sprotected double calculateSelfLoopSelfSidePenaltyCost(Edge edge, YList path, PortCandidate spc, PortCandidate tpc)
This method is called by
calculateCost(Edge, YList, PortCandidate, PortCandidate)
. The default implementation adds costs for another
bend if source and target ports share the same node side. In this manner, paths with different source and target
directions are cheaper and thus preferred. The method may be overridden to change the calculation of this penalty.
edge
- the edge for which the costs are calculatedpath
- the path of the given edgespc
- the source PortCandidate
for this edgetpc
- the target PortCandidate
for this edgeprotected void checkNodeSize(LayoutGraph g)
g
- The graph to check.public Object getAffectedEdgesDpKey()
IDataProvider
which determines the edges that shall be routed by this algorithm.IllegalArgumentException
- if the specified IDataProvider
key is null
DEFAULT_AFFECTED_EDGES_DPKEY
IDataProvider
which determines the edges to be routedsetAffectedEdgesDpKey(Object)
public double getBendCost()
These costs are used for finding the best path out of the predefined paths from which the router can choose.
The costs need to be non-negative.
IllegalArgumentException
- if the specified costs are negativesetBendCost(double)
public double getEdgeCrossingCost()
These costs are used for finding the best path out of the predefined paths from which the router can choose.
The costs need to be non-negative.
IllegalArgumentException
- if the specified costs are negativesetEdgeCrossingCost(double)
public double getEdgeOverlapCost()
These costs are used for finding the best path out of the predefined paths from which the router can choose.
The costs need to be non-negative.
IllegalArgumentException
- if the specified costs are negativeOrthogonalPatternEdgeRouter
is used stand-alone, one can determine a higher cost to prevent edge
overlaps.OrthogonalPatternEdgeRouter
is used in conjunction with a
OrthogonalSegmentDistributionStage
. Hence, edge overlaps are desired and
thus should not cause any costs.setEdgeOverlapCost(double)
public YPoint getGridOrigin()
IllegalArgumentException
- if the specified point is null
minimum distance
. Thus, it is possible that edges are not routed on the grid if
there is not enough space between two borders.grid routing is enabled
.YPoint.ORIGIN
setGridRouting(boolean)
,
setGridOrigin(YPoint)
public double getGridSpacing()
The spacing between two grid lines must be at least 2
.
IllegalArgumentException
- if the specified grid spacing is less than 2
grid routing is enabled
.setGridRouting(boolean)
,
setGridSpacing(double)
public double getMinimumDistance()
The distance needs to be non-negative.
IllegalArgumentException
- if the specified distance is negativesetMinimumDistance(double)
public MonotonicPathRestriction getMonotonicPathRestriction()
IllegalArgumentException
- if the specified path restriction is unknownMonotonicPathRestriction.NONE
setMonotonicPathRestriction(MonotonicPathRestriction)
public double getNodeCrossingCost()
These costs are used for finding the best path out of the predefined paths from which the router can choose.
The costs need to be non-negative.
IllegalArgumentException
- if the specified costs are negativesetNodeCrossingCost(double)
public boolean isGridRouting()
The grid can be defined using methods GridOrigin
and
GridSpacing
.
PortConstraint
s or assign coordinates that already lie on the grid for these ports if grid routing is
desired.false
. Edges are not routed on a grid.true
if edges are routed on grid, false
otherwisesetGridOrigin(YPoint)
,
setGridSpacing(double)
,
setGridRouting(boolean)
public void setAffectedEdgesDpKey(Object value)
IDataProvider
which determines the edges that shall be routed by this algorithm.IllegalArgumentException
- if the specified IDataProvider
key is null
DEFAULT_AFFECTED_EDGES_DPKEY
value
- the key to register a IDataProvider
which determines the edges to be routedgetAffectedEdgesDpKey()
public void setBendCost(double value)
These costs are used for finding the best path out of the predefined paths from which the router can choose.
The costs need to be non-negative.
IllegalArgumentException
- if the specified costs are negativevalue
- the costs for edges crossing nodesgetBendCost()
public void setEdgeCrossingCost(double value)
These costs are used for finding the best path out of the predefined paths from which the router can choose.
The costs need to be non-negative.
IllegalArgumentException
- if the specified costs are negativevalue
- the costs for an edge crossinggetEdgeCrossingCost()
public void setEdgeOverlapCost(double value)
These costs are used for finding the best path out of the predefined paths from which the router can choose.
The costs need to be non-negative.
IllegalArgumentException
- if the specified costs are negativeOrthogonalPatternEdgeRouter
is used stand-alone, one can determine a higher cost to prevent edge
overlaps.OrthogonalPatternEdgeRouter
is used in conjunction with a
OrthogonalSegmentDistributionStage
. Hence, edge overlaps are desired and
thus should not cause any costs.value
- the costs for overlapping edge segmentsgetEdgeOverlapCost()
public void setGridOrigin(YPoint value)
IllegalArgumentException
- if the specified point is null
minimum distance
. Thus, it is possible that edges are not routed on the grid if
there is not enough space between two borders.grid routing is enabled
.YPoint.ORIGIN
value
- the origin of the gridsetGridRouting(boolean)
,
getGridOrigin()
public void setGridRouting(boolean value)
The grid can be defined using methods GridOrigin
and
GridSpacing
.
PortConstraint
s or assign coordinates that already lie on the grid for these ports if grid routing is
desired.false
. Edges are not routed on a grid.value
- true
if edges are routed on grid, false
otherwisesetGridOrigin(YPoint)
,
setGridSpacing(double)
,
isGridRouting()
public void setGridSpacing(double value)
The spacing between two grid lines must be at least 2
.
IllegalArgumentException
- if the specified grid spacing is less than 2
grid routing is enabled
.value
- the spacing between two grid linessetGridRouting(boolean)
,
getGridSpacing()
public void setMinimumDistance(double value)
The distance needs to be non-negative.
IllegalArgumentException
- if the specified distance is negativevalue
- the minimum distance between the edge and its source and target nodegetMinimumDistance()
public void setMonotonicPathRestriction(MonotonicPathRestriction value)
IllegalArgumentException
- if the specified path restriction is unknownMonotonicPathRestriction.NONE
value
- one of the valid monotonic path restrictionsgetMonotonicPathRestriction()
public void setNodeCrossingCost(double value)
These costs are used for finding the best path out of the predefined paths from which the router can choose.
The costs need to be non-negative.
IllegalArgumentException
- if the specified costs are negativevalue
- the costs for edges crossing nodesgetNodeCrossingCost()