Search this API

y.layout
Class SelfLoopLayouter

java.lang.Object
  extended by y.layout.AbstractLayoutStage
      extended by y.layout.SelfLoopLayouter
All Implemented Interfaces:
Layouter, LayoutStage

public class SelfLoopLayouter
extends AbstractLayoutStage

A SelfLoopLayouter routes the self-loops (reflexive edges) of a graph.

Layout Style

The nodes and normal edges are arranged by the 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

Concept

Self-loops are handled in four steps:

  1. Remove all self-loops of the input graph
  2. Invoke the core layout algorithm on the now self-loops free graph
  3. Reinsert all formerly removed self-loops
  4. Route the self-loops of the input graph

Features

SelfLoopLayouter can either be used as a LayoutStage 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, SelfLoopLayouter 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 DataProvider registered with KEEP_SELF_LOOP_LAYOUT_DPKEY can be used for marking those self-loops.

See Also:
CanonicMultiStageLayouter
 

Field Summary
static java.lang.Object KEEP_SELF_LOOP_LAYOUT_DPKEY
          A DataProvider key for determining which self-loops should keep their current path If no DataProvider is registered with this key, all self-loops will be routed.
static byte STYLE_ORTHOGONAL
          Self-loop style specifier which defines that the routes of self-loops are orthogonal.
static byte STYLE_ROUNDED
          Self-loop style specifier which defines that the routes of self-loops are rounded.
 
Fields inherited from interface y.layout.Layouter
EDGE_ID_DPKEY, NODE_ID_DPKEY, NODE_TYPE_DPKEY, SELECTED_EDGES, SELECTED_NODES
 
Constructor Summary
SelfLoopLayouter()
          Creates a new SelfLoopLayouter instance with default settings.
SelfLoopLayouter(Layouter coreLayouter)
          Creates a new SelfLoopLayouter using the given core layout algorithm.
 
Method Summary
 boolean canLayout(LayoutGraph graph)
          Accepts all graphs that can be handled by the core layout algorithm after removing all self-loops.
 void doLayout(LayoutGraph graph)
          Delegates the arrangement of nodes and edges to the core layout algorithm and routes the self-loops.
 int getCornerApproximationPointsCount()
          Returns the number of points that are used for rounding the corners of the self-loops.
 byte getLayoutStyle()
          Returns the layout style of the self-loops.
 double getLineDistance()
          Returns the distance between two self-loops incident to the same node.
 boolean isKeepAllSelfloopLayoutsEnabled()
          Returns whether or not this algorithm should keep all self-loop routes.
 boolean isSmartSelfloopPlacementEnabled()
          Returns 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 cornerApproximationPointsCount)
          Specifies the number of points that are used for rounding the corners of the self-loops.
 void setKeepAllSelfloopLayoutsEnabled(boolean keepAllSelfloopLayouts)
          Specifies whether or not this algorithm should keep all self-loop routes.
 void setLayoutStyle(byte layoutStyle)
          Specifies the layout style of the self-loops.
 void setLineDistance(double distance)
          Specifies the distance between two self-loops incident to the same node.
 void setSmartSelfloopPlacementEnabled(boolean smartSelfloopPlacementEnabled)
          Specifies whether or not the algorithm chooses the side of the self-loop depending on the incident edges.
 
Methods inherited from class y.layout.AbstractLayoutStage
canLayoutCore, doLayoutCore, getCoreLayouter, setCoreLayouter
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

KEEP_SELF_LOOP_LAYOUT_DPKEY

public static final java.lang.Object KEEP_SELF_LOOP_LAYOUT_DPKEY
A DataProvider key for determining which self-loops should keep their current path

If no DataProvider is registered with this key, all self-loops will be routed.

See Also:
setKeepAllSelfloopLayoutsEnabled(boolean)

STYLE_ORTHOGONAL

public static final byte STYLE_ORTHOGONAL
Self-loop style specifier which defines that the routes of self-loops are orthogonal.

The routes consist of an alternating sequence of horizontal and vertical line segments.

See Also:
setLayoutStyle(byte), Constant Field Values
Sample Graph:

Orthogonal path

STYLE_ROUNDED

public static final byte STYLE_ROUNDED
Self-loop style specifier which defines that the routes of self-loops are rounded.

The distance between incident self-loops and rounding of the corners can be customized for rounded self-loops.

See Also:
setLayoutStyle(byte), setLineDistance(double), setCornerApproximationPointsCount(int), Constant Field Values
Sample Graph:

Corners are rounded with 5 bends
Constructor Detail

SelfLoopLayouter

public SelfLoopLayouter()
Creates a new SelfLoopLayouter instance with default settings.


SelfLoopLayouter

public SelfLoopLayouter(Layouter coreLayouter)
Creates a new SelfLoopLayouter using the given core layout algorithm.

Parameters:
coreLayouter - the core layout algorithm
Method Detail

getCornerApproximationPointsCount

public int getCornerApproximationPointsCount()
Returns the number of points that are used for rounding the corners of the self-loops.

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.

 
This option is only considered when style STYLE_ROUNDED is used.
Returns:
the number of bends that are inserted to round the corners of self-loops
See Also:
setCornerApproximationPointsCount(int), setLayoutStyle(byte), STYLE_ROUNDED

setCornerApproximationPointsCount

public void setCornerApproximationPointsCount(int cornerApproximationPointsCount)
Specifies the number of points that are used for rounding the corners of the self-loops.

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.

 
This option is only considered when style STYLE_ROUNDED is used.
Default Value:
The default value is 2.
Parameters:
cornerApproximationPointsCount - the number of bends that are inserted to round the corners of self-loops
Throws:
java.lang.IllegalArgumentException - if the specified point count is less than 1
See Also:
setLayoutStyle(byte), STYLE_ROUNDED
Sample Graphs:

2

5

setLineDistance

public void setLineDistance(double distance)
Specifies the distance between two self-loops incident to the same node.

The distance needs to be a non-negative value.

 
This value is only considered for layout style STYLE_ROUNDED.
Default Value:
The default value is 5.
Parameters:
distance - the distance between the self-loops
Throws:
java.lang.IllegalArgumentException - if the specified distance is negative
See Also:
STYLE_ROUNDED
Sample Graphs:

5

50

getLineDistance

public double getLineDistance()
Returns the distance between two self-loops incident to the same node.

The distance needs to be a non-negative value.

 
This value is only considered for layout style STYLE_ROUNDED.
Returns:
the distance between the self-loops
See Also:
setLineDistance(double), STYLE_ROUNDED

isSmartSelfloopPlacementEnabled

public boolean isSmartSelfloopPlacementEnabled()
Returns whether or not the algorithm chooses the side of the self-loop depending on the incident edges. 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.

Returns:
true if self-loops are placed smartly, false otherwise
See Also:
setSmartSelfloopPlacementEnabled(boolean)

setSmartSelfloopPlacementEnabled

public void setSmartSelfloopPlacementEnabled(boolean smartSelfloopPlacementEnabled)
Specifies whether or not the algorithm chooses the side of the self-loop depending on the incident edges. 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.

Default Value:
The default value is true. The corner of the nodes where self-loops are placed is chosen considering incident edges.
Parameters:
smartSelfloopPlacementEnabled - true if self-loops should be placed smartly, false otherwise
Sample Graphs:

false

true

getLayoutStyle

public byte getLayoutStyle()
Returns the layout style of the self-loops.

Returns:
the layout style for self-loops
See Also:
setLayoutStyle(byte)

setLayoutStyle

public void setLayoutStyle(byte layoutStyle)
Specifies the layout style of the self-loops.

Default Value:
The default value is STYLE_ROUNDED
Parameters:
layoutStyle - the layout style for self-loops
Throws:
java.lang.IllegalArgumentException - if the specified style is unknown

doLayout

public void doLayout(LayoutGraph graph)
Delegates the arrangement of nodes and edges to the core layout algorithm and routes the self-loops.

Parameters:
graph - the input graph
See Also:
Layouter.canLayout(LayoutGraph)

canLayout

public boolean canLayout(LayoutGraph graph)
Accepts all graphs that can be handled by the core layout algorithm after removing all self-loops.

If there is no core layout algorithm, all graphs are accepted.

Parameters:
graph - the input graph
Returns:
true if there is no core layout algorithm or the core layout algorithm accepts the graph, false otherwise
See Also:
Layouter.doLayout(LayoutGraph)

layoutSelfLoops

protected void layoutSelfLoops(LayoutGraph graph)
Calculates the routes of the self-loops in the given graph.

This method will only change the routes of self-loops that are not marked to be kept.

This method is called by doLayout(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.

Parameters:
graph - the input graph

isKeepAllSelfloopLayoutsEnabled

public boolean isKeepAllSelfloopLayoutsEnabled()
Returns whether or not this algorithm should keep all self-loop routes.

When enabled, no self-loop will be routed, instead the existing self-loop layout will be moved with its node.

 
Enabling this option will override the information in the DataProvider registered with KEEP_SELF_LOOP_LAYOUT_DPKEY. Self-loops that were not marked will still not be routed.
Returns:
true if all self-loops should keep their routes, false otherwise
See Also:
setKeepAllSelfloopLayoutsEnabled(boolean)

setKeepAllSelfloopLayoutsEnabled

public void setKeepAllSelfloopLayoutsEnabled(boolean keepAllSelfloopLayouts)
Specifies whether or not this algorithm should keep all self-loop routes.

When enabled, no self-loop will be routed, instead the existing self-loop layout will be moved with its node.

 
Enabling this option will override the information in the DataProvider registered with KEEP_SELF_LOOP_LAYOUT_DPKEY. Self-loops that were not marked will still not be routed.
Default Value:
The default value is false. Self-loops get a new route.
Parameters:
keepAllSelfloopLayouts - true if all self-loops should keep their routes, false otherwise

© Copyright 2000-2022,
yWorks GmbH.
All rights reserved.