public class SelfLoopRouter extends AbstractLayoutStage
SelfLoopRouter
routes the self-loops (reflexive edges) of a graph.
core layout algorithm
. This layout algorithm only handles the paths of
self-loops.
Self-loops are routed either orthogonal
or with rounded
corners. The layout algorithm places the self-loops in the least crowded quadrant around a node.
Small graph with self-loops
SelfLoopRouter
can either be used as a ILayoutStage
wrapping a layout algorithm
which cannot handle self-loops. Then it will hide the self-loops from this core layout algorithm
and take over the routing of them.
If no core layout algorithm
is specified, SelfLoopRouter
can work
alone. It will route only the self-loops and keep the remaining graph unchanged.
When all self-loops already have a suitable layout, this layout algorithm can
keep the self-loop paths
. It will just hide the self-loops
before invoking the core layout algorithm, such that they are not altered by it.
To only exclude some self-loops from routing, a IDataProvider
registered with KEEP_SELF_LOOP_LAYOUT_DPKEY
can be used for marking those self-loops.
MultiStageLayout
Modifier and Type | Field and Description |
---|---|
static EdgeDpKey<Boolean> |
KEEP_SELF_LOOP_LAYOUT_DPKEY
A
DataProvider key for determining which self-loops should keep their current path
If no IDataProvider is registered with this key, all self-loops will be routed. |
Constructor and Description |
---|
SelfLoopRouter()
Creates a new
SelfLoopRouter with an optional
core layout algorithm . |
SelfLoopRouter(ILayoutAlgorithm coreLayouter)
Creates a new
SelfLoopRouter with an optional
core layout algorithm . |
Modifier and Type | Method and Description |
---|---|
void |
applyLayout(LayoutGraph graph)
Delegates the arrangement of nodes and edges to the
core layout algorithm
and routes the self-loops. |
int |
getCornerApproximationPointsCount()
Gets the number of points that are used for rounding the corners of the self-loops.
|
SelfLoopStyle |
getLayoutStyle()
Gets the layout style of the self-loops.
|
double |
getLineDistance()
Gets the distance between two self-loops incident to the same node.
|
boolean |
isKeepingAllSelfLoopRoutesEnabled()
Gets whether or not this algorithm should keep all self-loop routes.
|
boolean |
isSmartSelfLoopPlacementEnabled()
Gets whether or not the algorithm chooses the side of the self-loop depending on the incident edges.
|
protected void |
layoutSelfLoops(LayoutGraph graph)
Calculates the routes of the self-loops in the given graph.
|
void |
setCornerApproximationPointsCount(int value)
Sets the number of points that are used for rounding the corners of the self-loops.
|
void |
setKeepingAllSelfLoopRoutesEnabled(boolean value)
Sets whether or not this algorithm should keep all self-loop routes.
|
void |
setLayoutStyle(SelfLoopStyle value)
Sets the layout style of the self-loops.
|
void |
setLineDistance(double value)
Sets the distance between two self-loops incident to the same node.
|
void |
setSmartSelfLoopPlacementEnabled(boolean value)
Sets whether or not the algorithm chooses the side of the self-loop depending on the incident edges.
|
applyLayoutCore, getCoreLayout, setCoreLayout
public static final EdgeDpKey<Boolean> KEEP_SELF_LOOP_LAYOUT_DPKEY
DataProvider
key for determining which self-loops should keep their current path
If no IDataProvider
is registered with this key, all self-loops will be routed.
public SelfLoopRouter()
SelfLoopRouter
with an optional
core layout algorithm
.public SelfLoopRouter(ILayoutAlgorithm coreLayouter)
SelfLoopRouter
with an optional
core layout algorithm
.coreLayouter
- The core layout algorithm.public void applyLayout(LayoutGraph graph)
core layout algorithm
and routes the self-loops.applyLayout
in interface ILayoutAlgorithm
applyLayout
in class AbstractLayoutStage
graph
- the input graphpublic int getCornerApproximationPointsCount()
For rounded corners, the number of points should be at least
2
. All smaller values will produce one bend and, therefore, an orthogonal path.
The number of points for a corner must be at least 1
.
IllegalArgumentException
- if the specified point count is less than 1
SelfLoopStyle.ROUNDED
is used.setLayoutStyle(SelfLoopStyle)
,
SelfLoopStyle.ROUNDED
,
setCornerApproximationPointsCount(int)
public SelfLoopStyle getLayoutStyle()
IllegalArgumentException
- if the specified style is unknownSelfLoopStyle.ROUNDED
setLayoutStyle(SelfLoopStyle)
public double getLineDistance()
The distance needs to be a non-negative value.
IllegalArgumentException
- if the specified distance is negativeSelfLoopStyle.ROUNDED
.SelfLoopStyle.ROUNDED
,
setLineDistance(double)
public boolean isKeepingAllSelfLoopRoutesEnabled()
When enabled, no self-loop will be routed, instead the existing self-loop layout will be moved with its node.
IDataProvider
registered with
KEEP_SELF_LOOP_LAYOUT_DPKEY
. Self-loops that were not marked will still not be routed.false
. Self-loops get a new route.true
if all self-loops should keep their routes, false
otherwisesetKeepingAllSelfLoopRoutesEnabled(boolean)
public boolean isSmartSelfLoopPlacementEnabled()
If this option is enabled, self-loops are placed on one of the four corners of the corresponding node. For the choice of the corner, the algorithm considers all incident edges. Otherwise, self-loops are always placed at the upper left corner of the corresponding node.
true
. The corner of the nodes where self-loops are placed is chosen considering incident edges.true
if self-loops are placed smartly, false
otherwisesetSmartSelfLoopPlacementEnabled(boolean)
protected void layoutSelfLoops(LayoutGraph graph)
This method will only change the routes of self-loops that are not marked to be
kept
.
This method is called by applyLayout(LayoutGraph)
after the core layout algorithm
has arranged the graph and all self-loops have been reinserted into the graph. It may be overridden to introduce custom
self-loop styles.
graph
- the input graphpublic void setCornerApproximationPointsCount(int value)
For rounded corners, the number of points should be at least
2
. All smaller values will produce one bend and, therefore, an orthogonal path.
The number of points for a corner must be at least 1
.
IllegalArgumentException
- if the specified point count is less than 1
SelfLoopStyle.ROUNDED
is used.value
- the number of bends that are inserted to round the corners of self-loopssetLayoutStyle(SelfLoopStyle)
,
SelfLoopStyle.ROUNDED
,
getCornerApproximationPointsCount()
public void setKeepingAllSelfLoopRoutesEnabled(boolean value)
When enabled, no self-loop will be routed, instead the existing self-loop layout will be moved with its node.
IDataProvider
registered with
KEEP_SELF_LOOP_LAYOUT_DPKEY
. Self-loops that were not marked will still not be routed.false
. Self-loops get a new route.value
- true
if all self-loops should keep their routes, false
otherwiseisKeepingAllSelfLoopRoutesEnabled()
public void setLayoutStyle(SelfLoopStyle value)
IllegalArgumentException
- if the specified style is unknownSelfLoopStyle.ROUNDED
value
- the layout style for self-loopsgetLayoutStyle()
public void setLineDistance(double value)
The distance needs to be a non-negative value.
IllegalArgumentException
- if the specified distance is negativeSelfLoopStyle.ROUNDED
.value
- the distance between the self-loopsSelfLoopStyle.ROUNDED
,
getLineDistance()
public void setSmartSelfLoopPlacementEnabled(boolean value)
If this option is enabled, self-loops are placed on one of the four corners of the corresponding node. For the choice of the corner, the algorithm considers all incident edges. Otherwise, self-loops are always placed at the upper left corner of the corresponding node.
true
. The corner of the nodes where self-loops are placed is chosen considering incident edges.value
- true
if self-loops are placed smartly, false
otherwiseisSmartSelfLoopPlacementEnabled()