|
Search this API | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object y.layout.partial.ClearAreaLayouter
public class ClearAreaLayouter
This layout algorithm clears a specified area by moving intersecting elements, while trying to minimize the changes in the given layout.
The algorithm can be applied if it is necessary to make space within a specific region/area in an existing graph layout. It tries to keep the given layout style as much as possible. Ideally, only local changes in and around the marked area are made, such that the mental map for the user is preserved.
An example application is the use case that new nodes or a whole graph component were added
to the graph and should be placed in a specific region of an existing graph layout. The region can
then first be cleared using this algorithm such that afterwards the nodes or the component could be
inserted without overlaps with other elements. This specific case can conveniently be
implemented by defining a set of so-called area nodes, via AREA_NODES_DPKEY
.
Another, more general use case would be nodes that grow in size, including the case that a folder node
is expanded and converted to a larger group node. This case is easily realized by specifying
the expanded node via EXPANDED_NODE_DPKEY
.
An input sample - the area that must be cleared is visualized as a gray rectangle.
The result after clearing the area with this algorithm.
The area, which can be defined as a rectangle
or an
outline
, defines a region in the given input graph which must be cleared.
Clearing the area means no graph elements are allowed to intersect with it. This
includes nodes and, depending on settings isEdgeConsiderationEnabled()
,
isNodeLabelConsiderationEnabled()
and isEdgeLabelConsiderationEnabled()
also edges,
node labels and edge labels.
In order to clear the area, the graph elements must be moved. Moving an element often induces the necessity
to move further elements along with them. Thus, depending on where the area is located in the input
drawing, many elements may be moved to make the necessary space.
How elements are selected and how they are moved highly depends on the chosen
clearing strategy
.
For grouped graphs, the group nodes are also correctly handled by this algorithm. However, it is
important to note that there is always one so-called area group node. It is the group node
inside which the free space should be created and which may in consequence need to grow, see
AREA_GROUP_NODE_DPKEY
for more details.
When defining the free space via area nodes (see above), this group is automatically determined,
otherwise it must explicitly be specified. If not specified, the free space is created in the
top-level hierarchy.
The algorithm is able to consider a specified PartitionGrid
as long as there are no group nodes that
span multiple grid cells. Note that the cleared area is always allocated to a single cell of the grid, i.e.,
it is not possible that the area spans multiple cells.
For this feature to work properly it is required that the values of the properties
ColumnDescriptor.getOriginalPosition()
, RowDescriptor.getOriginalPosition()
ColumnDescriptor.getOriginalWidth()
and RowDescriptor.getOriginalHeight()
are correctly specified. This is usually automatically the case when executing the ClearAreaLayouter
as a
standalone algorithm via layout execution convenience methods (e.g. the values are taken from the table
visualization of the grid). However, if the ClearAreaLayouter
is applied as part of a more complex
layout pipeline it may be necessary to specify the values manually. For example, if another algorithm
previously computed the grid position values and stored them in the respective 'computed' properties
(e.g. ColumnDescriptor.getComputedPosition()
), and afterwards ClearAreaLayouter
should be applied, then the 'computed' values of the first algorithm should be written to the 'original'
values prior to the run of the ClearAreaLayouter
.
Field Summary | |
---|---|
static java.lang.Object |
AREA_GROUP_NODE_DPKEY
A DataProvider key for specifying the group node inside which the cleared area should be located
The area that is cleared of elements can be associated to one specific group node. |
static java.lang.Object |
AREA_NODES_DPKEY
A DataProvider key for specifying a set of nodes that define the area which should be cleared
These nodes define a sort of component from which the area that must be cleared is derived by
calling method createAreaOutline(LayoutGraph, NodeList, EdgeList) . |
static byte |
COMPONENT_ASSIGNMENT_STRATEGY_CLUSTERING
A component assignment strategy where the subgraph components correspond to the clusters computed by a clustering algorithm based on edge betweenness centrality . |
static byte |
COMPONENT_ASSIGNMENT_STRATEGY_CONNECTED
A component assignment strategy where the subgraph components correspond to the connected components of the graph. |
static byte |
COMPONENT_ASSIGNMENT_STRATEGY_CUSTOMIZED
A component assignment strategy where the subgraph components are defined by the user. |
static byte |
COMPONENT_ASSIGNMENT_STRATEGY_SINGLE
A component assignment strategy that assigns each node to a separate subgraph component. |
static java.lang.Object |
COMPONENT_ID_DPKEY
A DataProvider key for defining custom components whose elements should preferably not be separated
While the algorithm may move a whole component, it should preferably not move only a subset of
its elements. |
static byte |
EDGE_ROUTING_STRATEGY_AUTOMATIC
Automatically chooses a suitable routing strategy by analyzing the existing edge routes. |
static byte |
EDGE_ROUTING_STRATEGY_OCTILINEAR
A routing strategy that produces octilinear routes. |
static byte |
EDGE_ROUTING_STRATEGY_ORGANIC
A routing strategy that produces organic routes for partial edges and inter-edges. |
static byte |
EDGE_ROUTING_STRATEGY_ORTHOGONAL
A routing strategy that produces orthogonal routes. |
static byte |
EDGE_ROUTING_STRATEGY_STRAIGHTLINE
A routing strategy that produces straight-line routes. |
static java.lang.Object |
EXPANDED_NODE_DPKEY
A DataProvider key for marking the node that was expanded and, thus, defines the area that must be cleared
When an expanded node is provided, the area that must be cleared is directly derived from the size of the
expanded node. |
static java.lang.Object |
EXPANDED_NODE_ORIGINAL_BOUNDS_DPKEY
A DataProvider key for specifying the original, non-expanded bounds of the expanded node
When an expanded node is provided, the area that must be cleared is directly derived from the bounds of the
expanded node. |
static java.lang.Object |
EXPANDED_NODE_ORIGINAL_EDGE_PATH_DPKEY
A DataProvider key for associating original paths for edges connecting to the expanded node, including edges
that did so only when the node was not yet expanded
When an expanded node is provided, the area that must be cleared is directly derived from the bounds of the
expanded node. |
static byte |
ORIENTATION_AUTO_DETECTION
Layout orientation specifier where the orientation is automatically detected. |
static byte |
ORIENTATION_BOTTOM_TO_TOP
Layout orientation specifier which defines that the main layout orientation is from bottom to top. |
static byte |
ORIENTATION_LEFT_TO_RIGHT
Layout orientation specifier which defines that the main layout orientation is from left to right. |
static byte |
ORIENTATION_NONE
Layout orientation specifier where the layout orientation is completely ignored. |
static byte |
ORIENTATION_RIGHT_TO_LEFT
Layout orientation specifier which defines that the main layout orientation is from right to left. |
static byte |
ORIENTATION_TOP_TO_BOTTOM
Layout orientation specifier which defines that the main layout orientation is from top to bottom. |
static java.lang.Object |
ROUTE_EDGE_DPKEY
A DataProvider key for obtaining the edges that should be routed by the custom edge router
|
static byte |
STRATEGY_GLOBAL
A strategy that clears the area by globally partitioning the input into two parts and moving them apart. |
static byte |
STRATEGY_LOCAL
A strategy that clears the area by trying to minimize the number of moved nodes, changing the layout rather locally. |
static byte |
STRATEGY_LOCAL_UNIFORM
A strategy that clears the area by trying to minimize the number of moved nodes, changing the layout rather locally but moving all necessary nodes by a uniform offset. |
static byte |
STRATEGY_PRESERVE_SHAPES
A strategy that clears the area with the goal to preserve the shape of the existing edge paths, moving related elements in common. |
static byte |
STRATEGY_PRESERVE_SHAPES_UNIFORM
A strategy that clears the area with the goal to preserve the shape of the existing edge paths, moving related elements in common and also moving all elements by a uniform offset. |
Fields inherited from interface y.layout.Layouter |
---|
EDGE_ID_DPKEY, NODE_ID_DPKEY, NODE_TYPE_DPKEY, SELECTED_EDGES, SELECTED_NODES |
Constructor Summary | |
---|---|
ClearAreaLayouter()
Creates a new instance of ClearAreaLayouter with default settings. |
Method Summary | |
---|---|
boolean |
canLayout(LayoutGraph graph)
Accepts all general graphs. |
protected void |
configureEdgeRouter(Layouter edgeRouter)
This method is called each time when edges are rerouted with the given edge router. |
protected BorderLine[] |
createAreaOutline(LayoutGraph graph,
NodeList areaNodes,
EdgeList areaEdges)
Creates the outline that describes the shape of the given nodes and edges. |
void |
doLayout(LayoutGraph graph)
Clears the specified rectangular getArea() , the area defined via AREA_NODES_DPKEY or
EXPANDED_NODE_DPKEY by moving all other graph elements currently intersecting with it. |
YRectangle |
getArea()
Returns the rectangular area that must be cleared. |
BorderLine[] |
getAreaOutline()
Returns the outline describing the shape of the area that must be cleared. |
byte |
getClearAreaStrategy()
Returns the strategy applied for clearing the desired area. |
byte |
getComponentAssignmentStrategy()
Returns the strategy that assigns nodes to components whose elements should preferably not be separated. |
Layouter |
getEdgeRouter()
Returns the custom edge router instance that is applied to reroute edges. |
byte |
getEdgeRoutingStrategy()
Returns the routing strategy that is preserved while clearing the area and applied when rerouting edges. |
double |
getGridSpacing()
Returns the current grid spacing. |
byte |
getLayoutOrientation()
Returns the layout orientation that is considered during the clearing of the area. |
long |
getMaximumDuration()
Returns the time limit in milliseconds for the layout algorithm. |
double |
getSpacing()
Returns the spacing that is considered between elements when they are moved to clear the area. |
boolean |
isEdgeConsiderationEnabled()
Returns whether or not edges are considered when clearing the area such that
no segments intersecting the area are allowed. |
boolean |
isEdgeLabelConsiderationEnabled()
Returns whether or not the layout algorithm considers edge labels, moving them outside the area, if necessary. |
boolean |
isFixPorts()
Returns whether the ports of the input graph must be fixed or if they can be changed. |
boolean |
isNodeLabelConsiderationEnabled()
Returns whether or not the layout algorithm considers node labels, moving them outside the area, if necessary. |
void |
setArea(YRectangle area)
Specifies the rectangular area that must be cleared. |
void |
setAreaOutline(BorderLine[] areaOutline)
Specifies the outline describing the shape of the area that must be cleared. |
void |
setClearAreaStrategy(byte clearAreaStrategy)
Specifies the strategy applied for clearing the desired area. |
void |
setComponentAssignmentStrategy(byte componentAssignmentStrategy)
Specifies the strategy that assigns nodes to components whose elements should preferably not be separated. |
void |
setEdgeConsiderationEnabled(boolean edgeConsiderationEnabled)
Specifies whether or not edges are considered when clearing the area such that
no segments intersecting the area are allowed. |
void |
setEdgeLabelConsiderationEnabled(boolean edgeLabelConsiderationEnabled)
Specifies whether or not the layout algorithm considers edge labels, moving them outside the area, if necessary. |
void |
setEdgeRouter(Layouter edgeRouter)
Specifies the custom edge router instance that is applied to reroute edges. |
void |
setEdgeRoutingStrategy(byte edgeRoutingStrategy)
Specifies the routing strategy that is preserved while clearing the area and applied when rerouting edges. |
void |
setFixPorts(boolean fixPorts)
Specifies whether the ports of the input graph must be fixed or if they can be changed. |
void |
setGridSpacing(double gridSpacing)
Specifies the current grid spacing. |
void |
setLayoutOrientation(byte layoutOrientation)
Specifies the layout orientation that is considered during the clearing of the area. |
void |
setMaximumDuration(long maximumDuration)
Specifies the time limit in milliseconds for the layout algorithm. |
void |
setNodeLabelConsiderationEnabled(boolean nodeLabelConsiderationEnabled)
Specifies whether or not the layout algorithm considers node labels, moving them outside the area, if necessary. |
void |
setSpacing(double spacing)
Specifies the spacing that is considered between elements when they are moved to clear the area. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final java.lang.Object EXPANDED_NODE_DPKEY
DataProvider
key for marking the node that was expanded and, thus, defines the area that must be cleared
When an expanded node is provided, the area that must be cleared is directly derived from the size of the expanded node. Defining an expanded node is intended for the case that a node's size increased such that it might now overlap with other graph elements. This includes the use case of expanding a folder node.
It is strongly recommended to additionally provide the original (smaller) bounds of the expanded node
via EXPANDED_NODE_ORIGINAL_BOUNDS_DPKEY
. If the node has incident edges, it is also recommended
to provide the original paths of these edges via key EXPANDED_NODE_ORIGINAL_EDGE_PATH_DPKEY
, i.e. the
edge paths before the size of the node was changed (for example, before expanding a folder node). This includes
paths of edges that were only incident to the non-expanded node and are now incident to descendants of it.
Using this knowledge the algorithm clears the area occupied by the expanded node but also considers how the
layout looked before the change. This way the mental map may be preserved to a higher degree.
area nodes
and the
values of properties getArea()
and getAreaOutline()
are ignored.EXPANDED_NODE_ORIGINAL_BOUNDS_DPKEY
,
EXPANDED_NODE_ORIGINAL_EDGE_PATH_DPKEY
public static final java.lang.Object EXPANDED_NODE_ORIGINAL_BOUNDS_DPKEY
DataProvider
key for specifying the original, non-expanded bounds of the expanded node
When an expanded node is provided, the area that must be cleared is directly derived from the bounds of the
expanded node. The original, non-expanded (smaller) bounds of the expanded node are helpful to
preserve the mental map of the overall drawing to a higher degree than without the additional knowledge about
the previous layout. Note, however, that only strategies STRATEGY_PRESERVE_SHAPES
,
STRATEGY_PRESERVE_SHAPES_UNIFORM
and STRATEGY_GLOBAL
will significantly profit from it.
EXPANDED_NODE_DPKEY
,
EXPANDED_NODE_ORIGINAL_EDGE_PATH_DPKEY
public static final java.lang.Object EXPANDED_NODE_ORIGINAL_EDGE_PATH_DPKEY
DataProvider
key for associating original paths for edges connecting to the expanded node, including edges
that did so only when the node was not yet expanded
When an expanded node is provided, the area that must be cleared is directly derived from the bounds of the
expanded node. The original paths together with the original, non-expanded (smaller) bounds
(see EXPANDED_NODE_ORIGINAL_BOUNDS_DPKEY
) of the expanded node are helpful to preserve the mental map
of the overall drawing by providing knowledge about the previous layout state.
Note, however, that only strategies STRATEGY_PRESERVE_SHAPES
, STRATEGY_PRESERVE_SHAPES_UNIFORM
and STRATEGY_GLOBAL
will significantly profit from it.
Carefully observe that the original paths must correspond to the ones that were valid when the expanded node still had its original, non-expanded bounds. Thus, they should only be provided when the original bounds are provided too.
EXPANDED_NODE_DPKEY
,
EXPANDED_NODE_ORIGINAL_BOUNDS_DPKEY
public static final java.lang.Object COMPONENT_ID_DPKEY
DataProvider
key for defining custom components whose elements should preferably not be separated
While the algorithm may move a whole component, it should preferably not move only a subset of its elements. This means that the algorithm tries to move all elements of a component by the same offset (if at all). In order to achieve good results with this feature, the different components should not overlap in the initial drawing.
getComponentAssignmentStrategy()
is set to COMPONENT_ASSIGNMENT_STRATEGY_CUSTOMIZED
.
Furthermore, the components feature is only supported by clearing strategies
STRATEGY_PRESERVE_SHAPES
, STRATEGY_PRESERVE_SHAPES_UNIFORM
and STRATEGY_GLOBAL
.setComponentAssignmentStrategy(byte)
public static final java.lang.Object AREA_NODES_DPKEY
DataProvider
key for specifying a set of nodes that define the area which should be cleared
These nodes define a sort of component from which the area that must be cleared is derived by
calling method createAreaOutline(LayoutGraph, NodeList, EdgeList)
. This means that the
area will exactly be defined by the current locations of these nodes (including the edges among them)
such that after the algorithm execution there will not be any other elements intersecting with them.
Carefully observe that if group nodes are marked, all their descendants are treated as area nodes too.
The area group node
can not be defined manually, but the nearest
common ancestor of all area nodes will become the area group node. For group nodes other than
the area group either all their descendants including the group itself must be
area nodes or all their descendants including the group must not be area nodes. If the input
is not complete in this matter, the required nodes are internally automatically treated as area nodes too.
getArea()
and
getAreaOutline()
are ignored.createAreaOutline(LayoutGraph, NodeList, EdgeList)
public static final java.lang.Object AREA_GROUP_NODE_DPKEY
DataProvider
key for specifying the group node inside which the cleared area should be located
The area
that is cleared of elements can be associated to one specific group node. This
means that this group can grow because the free space must be created inside it. In consequence, all
ancestor nodes of the group may grow, too. Other groups are treated as fixed and must be moved
in order to avoid an overlap with the specified area.
If no group is specified, the free space will be created in the top-level hierarchy.
area
as the area group node.AREA_NODES_DPKEY
) or by means of a single expanded node (see EXPANDED_NODE_DPKEY
. In these
cases, the nearest common ancestor of the area nodes or the parent of the expanded node is automatically selected
as the group node that contains the free space.public static final java.lang.Object ROUTE_EDGE_DPKEY
DataProvider
key for obtaining the edges that should be routed by the custom edge router
DataProvider
must not be set by the user!
The key is used by this algorithm to temporarily add a DataProvider
that marks edges that should be routed
by the specified edge router, see setEdgeRouter(Layouter)
.setEdgeRouter(Layouter)
public static final byte EDGE_ROUTING_STRATEGY_ORTHOGONAL
A route of an edge is called orthogonal if it only consists of vertical and horizontal segments.
PartialLayouter.setEdgeRoutingStrategy(byte)
,
setEdgeRoutingStrategy(byte)
,
Constant Field Valuespublic static final byte EDGE_ROUTING_STRATEGY_STRAIGHTLINE
PartialLayouter.setEdgeRoutingStrategy(byte)
,
setEdgeRoutingStrategy(byte)
,
Constant Field Valuespublic static final byte EDGE_ROUTING_STRATEGY_AUTOMATIC
If, for example, all edges have orthogonal edge routes, edges that are rerouted are routed orthogonally, too.
PartialLayouter.setEdgeRoutingStrategy(byte)
,
setEdgeRoutingStrategy(byte)
,
Constant Field Valuespublic static final byte EDGE_ROUTING_STRATEGY_ORGANIC
PartialLayouter.setEdgeRoutingStrategy(byte)
,
setEdgeRoutingStrategy(byte)
,
Constant Field Valuespublic static final byte EDGE_ROUTING_STRATEGY_OCTILINEAR
A route of an edge is called octilinear if the slope of each
segment is a multiple of 45
degrees.
PartialLayouter.setEdgeRoutingStrategy(byte)
,
setEdgeRoutingStrategy(byte)
,
Constant Field Valuespublic static final byte COMPONENT_ASSIGNMENT_STRATEGY_SINGLE
PartialLayouter.setComponentAssignmentStrategy(byte)
,
setComponentAssignmentStrategy(byte)
,
FillAreaLayouter.setComponentAssignmentStrategy(byte)
,
Constant Field Valuespublic static final byte COMPONENT_ASSIGNMENT_STRATEGY_CONNECTED
PartialLayouter.setComponentAssignmentStrategy(byte)
,
setComponentAssignmentStrategy(byte)
,
FillAreaLayouter.setComponentAssignmentStrategy(byte)
,
Constant Field Valuespublic static final byte COMPONENT_ASSIGNMENT_STRATEGY_CLUSTERING
edge betweenness centrality
.
PartialLayouter.setComponentAssignmentStrategy(byte)
,
setComponentAssignmentStrategy(byte)
,
FillAreaLayouter.setComponentAssignmentStrategy(byte)
,
Constant Field Valuespublic static final byte COMPONENT_ASSIGNMENT_STRATEGY_CUSTOMIZED
PartialLayouter.setComponentAssignmentStrategy(byte)
,
setComponentAssignmentStrategy(byte)
,
FillAreaLayouter.setComponentAssignmentStrategy(byte)
,
Constant Field Valuespublic static final byte ORIENTATION_TOP_TO_BOTTOM
PartialLayouter.setLayoutOrientation(byte)
,
setLayoutOrientation(byte)
,
FillAreaLayouter.setLayoutOrientation(byte)
,
Constant Field Valuespublic static final byte ORIENTATION_BOTTOM_TO_TOP
PartialLayouter.setLayoutOrientation(byte)
,
setLayoutOrientation(byte)
,
FillAreaLayouter.setLayoutOrientation(byte)
,
Constant Field Valuespublic static final byte ORIENTATION_LEFT_TO_RIGHT
PartialLayouter.setLayoutOrientation(byte)
,
setLayoutOrientation(byte)
,
FillAreaLayouter.setLayoutOrientation(byte)
,
Constant Field Valuespublic static final byte ORIENTATION_RIGHT_TO_LEFT
PartialLayouter.setLayoutOrientation(byte)
,
setLayoutOrientation(byte)
,
FillAreaLayouter.setLayoutOrientation(byte)
,
Constant Field Valuespublic static final byte ORIENTATION_AUTO_DETECTION
PartialLayouter.setLayoutOrientation(byte)
,
setLayoutOrientation(byte)
,
FillAreaLayouter.setLayoutOrientation(byte)
,
Constant Field Valuespublic static final byte ORIENTATION_NONE
PartialLayouter.setLayoutOrientation(byte)
,
setLayoutOrientation(byte)
,
FillAreaLayouter.setLayoutOrientation(byte)
,
Constant Field Valuespublic static final byte STRATEGY_LOCAL
From the specified getArea()
, stripes running from the area border to the graph
border in all four directions are considered. The area is now cleared by simply moving all elements
inside the stripe in that direction, as far as necessary. If elements are not completely inside the
stripe but collide with moved elements, then they are moved along too. This way, the moving stripe can
quickly grow in some scenarios.
All edges where at least one node was moved are finally rerouted by the
routing algorithm
. This also applies for edges that cross the area
if property isEdgeConsiderationEnabled()
is enabled.
component assignment
setting.setClearAreaStrategy(byte)
,
Constant Field ValuesInput graph where the gray area must be cleared. | The result where the area was cleared with strategy STRATEGY_LOCAL . |
public static final byte STRATEGY_LOCAL_UNIFORM
This strategy basically works like STRATEGY_LOCAL
with the difference that nodes that
are required to move are moved uniformly, by the same location offset.
Therefore, compared to STRATEGY_LOCAL
this strategy preserves more of the initial relations.
On the other hand, results can become less compact. As nodes are uniformly moved, edges where both end nodes
were shifted do not need to be rerouted.
component assignment
setting.setClearAreaStrategy(byte)
,
Constant Field ValuesInput graph where the gray area must be cleared. | The result where the area was cleared with strategy STRATEGY_LOCAL_UNIFORM . |
public static final byte STRATEGY_PRESERVE_SHAPES
Preserving the shapes of the edge paths means that the direction of the edge segments is not changed and no new bends are created. The segment lengths may change in order to generate free space. The effect of this strategy is that the relative routes remain the same. The general aesthetics of a given layout are, ideally, preserved. The layout only becomes sparser to free up the desired space.
This strategy models all graph elements (nodes, edges, bends, labels) the same way and unifies related elements where appropriate. They are then moved in common in order to keep the relation among them as is.
STRATEGY_PRESERVE_SHAPES_UNIFORM
usually require less runtime
than the other strategies, because the number of edges that have to be rerouted
is smaller (rerouting is often very time consuming).STRATEGY_LOCAL
and STRATEGY_LOCAL_UNIFORM
,
this strategy usually needs to move a larger number of nodes to achieve its goal.setClearAreaStrategy(byte)
,
Constant Field ValuesInput graph where the gray area must be cleared. | The result where the area was cleared with strategy STRATEGY_PRESERVE_SHAPES . |
public static final byte STRATEGY_PRESERVE_SHAPES_UNIFORM
In addition to the related strategy STRATEGY_PRESERVE_SHAPES
, this one uses a uniform
offset for all elements that are moved. This way the relative locations between all elements in the
graph are preserved. On the other hand, unnecessary additional space may be generated.
Preserving the shapes of the edge paths means that the direction of the edge segments is not changed and no new bends are created. The segment lengths may change in order to generate free space. The effect of this strategy is that the relative routes remain the same. The general aesthetics of a given layout are, ideally, preserved. The layout only becomes sparser to free up the desired space.
This strategy models all graph elements (nodes, edges, bends, labels) the same way and unifies related elements where appropriate. They are then moved in common in order to keep the relation among them as is.
STRATEGY_PRESERVE_SHAPES
usually require less runtime
than the other strategies, because the number of edges that have to be rerouted
is smaller (rerouting is often very time consuming).STRATEGY_LOCAL
and STRATEGY_LOCAL_UNIFORM
,
this strategy usually needs to move a larger number of nodes to achieve its goal.setClearAreaStrategy(byte)
,
Constant Field ValuesInput graph where the gray area must be cleared. | The result where the area was cleared with strategy STRATEGY_PRESERVE_SHAPES_UNIFORM . |
public static final byte STRATEGY_GLOBAL
The existing layout is divided into two partitions somewhere along the area
.
The division can be vertical or horizontal. To free up the space, the two components are then moved
horizontally (vertical division) or vertically (horizontal division). Edges connecting nodes
of different partitions are rerouted by the routing algorithm
.
This strategy has a rather global effect on the existing layout because every element is displaced.
The edge routes and relative locations between elements that are in the same partition are not changed
at all. Compared to other strategies, more unnecessary free space may be generated as not only the
exact area
is cleared, but a whole vertical or horizontal stripe.
The specified component assignments
is considered such that
if possible all component nodes are in the same partition.
setClearAreaStrategy(byte)
,
Constant Field ValuesInput graph where the gray area must be cleared. | The result where the area was cleared with strategy STRATEGY_GLOBAL . |
Constructor Detail |
---|
public ClearAreaLayouter()
ClearAreaLayouter
with default settings.
Method Detail |
---|
public byte getClearAreaStrategy()
This property controls the main approach followed to clear the area
of graph elements.
setClearAreaStrategy(byte)
public void setClearAreaStrategy(byte clearAreaStrategy)
This property controls the main approach followed to clear the area
of graph elements.
STRATEGY_PRESERVE_SHAPES
clearAreaStrategy
- one of the predefined strategies to clear the area
java.lang.IllegalArgumentException
- if an unknown strategy is providedpublic double getGridSpacing()
Elements are moved by multiples of this value, thus, keeping their offset to the grid. That way, components or parts of them that were placed on a grid before, will stay on their original grid.
The grid spacing needs to be a non-negative value. If it is set to 0
, no grid is considered.
setGridSpacing(double)
public void setGridSpacing(double gridSpacing)
Elements are moved by multiples of this value, thus, keeping their offset to the grid. That way, components or parts of them that were placed on a grid before, will stay on their original grid.
The grid spacing needs to be a non-negative value. If it is set to 0
, no grid is considered.
gridSpacing
- the grid spacing
java.lang.IllegalArgumentException
- if the given spacing is negativepublic Layouter getEdgeRouter()
Several types of edges can be routed by this algorithm:
strategy
if such edges are actually handled by the
routing algorithm or if they are implicitly moved. For example, strategy
STRATEGY_PRESERVE_SHAPES
tries to keep the shapes and can avoid rerouting in many cases.
area nodes
component. If such
a component exists, the inter-edges are the edges connecting area nodes with non-area nodes. They
are always handled by this routing algorithm, independent of the strategy
.
expanded node
and to
the descendants of the expanded node in case it is a group node.
Changing the value of property setEdgeRoutingStrategy(byte)
automatically sets a new edge router
instance according to the specified routing strategy, thus, overwriting any previously set instances. The
following routing algorithms are set:
EdgeRouter
for strategies EDGE_ROUTING_STRATEGY_ORTHOGONAL
and EDGE_ROUTING_STRATEGY_OCTILINEAR
.
OrganicEdgeRouter
for strategy EDGE_ROUTING_STRATEGY_ORGANIC
.
StraightLineEdgeRouter
for strategy EDGE_ROUTING_STRATEGY_STRAIGHTLINE
.
DataProvider
-key
ROUTE_EDGE_DPKEY
. Hence, the specified router has to be configured such that it
observes this key and only routes marked edges!setEdgeRouter(Layouter)
,
ROUTE_EDGE_DPKEY
,
setEdgeRoutingStrategy(byte)
public void setEdgeRouter(Layouter edgeRouter)
Several types of edges can be routed by this algorithm:
strategy
if such edges are actually handled by the
routing algorithm or if they are implicitly moved. For example, strategy
STRATEGY_PRESERVE_SHAPES
tries to keep the shapes and can avoid rerouting in many cases.
area nodes
component. If such
a component exists, the inter-edges are the edges connecting area nodes with non-area nodes. They
are always handled by this routing algorithm, independent of the strategy
.
expanded node
and to
the descendants of the expanded node in case it is a group node.
Changing the value of property setEdgeRoutingStrategy(byte)
automatically sets a new edge router
instance according to the specified routing strategy, thus, overwriting any previously set instances. The
following routing algorithms are set:
EdgeRouter
for strategies EDGE_ROUTING_STRATEGY_ORTHOGONAL
and EDGE_ROUTING_STRATEGY_OCTILINEAR
.
OrganicEdgeRouter
for strategy EDGE_ROUTING_STRATEGY_ORGANIC
.
StraightLineEdgeRouter
for strategy EDGE_ROUTING_STRATEGY_STRAIGHTLINE
.
DataProvider
-key
ROUTE_EDGE_DPKEY
. Hence, the specified router has to be configured such that it
observes this key and only routes marked edges!edgeRouter
- the custom edge router instance that is applied to reroute edgesROUTE_EDGE_DPKEY
,
setEdgeRoutingStrategy(byte)
public byte getEdgeRoutingStrategy()
The algorithm assumes that the existing edges have paths according to the specified strategy
and takes this into account when moving nodes and edges in order to clear the area.
If the automatic strategy
is set, then no assumptions are
made but the given paths are analyzed to derive the best fitting routing strategy.
Note that in this case, the algorithm may use different routing styles for the edges.
This routing strategy is also relevant when edges need to be rerouted, as it determines the
routing algorithm used for rerouting, see setEdgeRouter(Layouter)
for more details.
setEdgeRouter(Layouter)
.setEdgeRoutingStrategy(byte)
,
setEdgeRouter(Layouter)
public void setEdgeRoutingStrategy(byte edgeRoutingStrategy)
The algorithm assumes that the existing edges have paths according to the specified strategy
and takes this into account when moving nodes and edges in order to clear the area.
If the automatic strategy
is set, then no assumptions are
made but the given paths are analyzed to derive the best fitting routing strategy.
Note that in this case, the algorithm may use different routing styles for the edges.
This routing strategy is also relevant when edges need to be rerouted, as it determines the
routing algorithm used for rerouting, see setEdgeRouter(Layouter)
for more details.
setEdgeRouter(Layouter)
.EDGE_ROUTING_STRATEGY_AUTOMATIC
. The routing strategy is automatically determined.edgeRoutingStrategy
- one of the predefined edge routing strategies
java.lang.IllegalArgumentException
- if the given strategy does not match one of the predefined routing strategiessetEdgeRouter(Layouter)
protected void configureEdgeRouter(Layouter edgeRouter)
This method may be overridden to customize the settings of the applied routing algorithm without manually specifying a custom router instance. This can be beneficial because the basic configuration of the router has already been made upon calling this method (e.g. setting up the scope). This method can then be implemented to fine-tune further settings, like, for example, minimum distance values.
The type of the given instance depends on the edge routing strategy.
EdgeRouter
for strategies EDGE_ROUTING_STRATEGY_ORTHOGONAL
and EDGE_ROUTING_STRATEGY_OCTILINEAR
.
OrganicEdgeRouter
for strategy EDGE_ROUTING_STRATEGY_ORGANIC
.
StraightLineEdgeRouter
for strategy EDGE_ROUTING_STRATEGY_STRAIGHTLINE
.
EDGE_ROUTING_STRATEGY_AUTOMATIC
is selected, one of the mentioned types is
chosen, depending on the style of the given edge routes.
setEdgeRouter(Layouter)
is set, its instance corresponds to that of the parameter.
edgeRouter
- the instance used for routing the edgessetEdgeRouter(Layouter)
,
setEdgeRoutingStrategy(byte)
public byte getComponentAssignmentStrategy()
While the algorithm may move a whole component, it tries to not move only a subset of its elements, thus, all elements of a component are not moved at all or moved by the same offset.
COMPONENT_ASSIGNMENT_STRATEGY_CUSTOMIZED
: the components can be user-defined.
If the user does not specify any, there are no components that should explicitly be kept together,
which is equal to the behavior of COMPONENT_ASSIGNMENT_STRATEGY_SINGLE
.
COMPONENT_ASSIGNMENT_STRATEGY_CONNECTED
components are defined by the connected components
of the graph.
COMPONENT_ASSIGNMENT_STRATEGY_CLUSTERING
: components are defined by edge betweenness clustering.
COMPONENT_ASSIGNMENT_STRATEGY_SINGLE
: each node is a separate component which basically
means that there are no components that should explicitly be kept together.
clearing strategies
STRATEGY_PRESERVE_SHAPES
, STRATEGY_PRESERVE_SHAPES_UNIFORM
and STRATEGY_GLOBAL
.setComponentAssignmentStrategy(byte)
,
COMPONENT_ID_DPKEY
public void setComponentAssignmentStrategy(byte componentAssignmentStrategy)
While the algorithm may move a whole component, it tries to not move only a subset of its elements, thus, all elements of a component are not moved at all or moved by the same offset.
COMPONENT_ASSIGNMENT_STRATEGY_CUSTOMIZED
: the components can be user-defined.
If the user does not specify any, there are no components that should explicitly be kept together,
which is equal to the behavior of COMPONENT_ASSIGNMENT_STRATEGY_SINGLE
.
COMPONENT_ASSIGNMENT_STRATEGY_CONNECTED
components are defined by the connected components
of the graph.
COMPONENT_ASSIGNMENT_STRATEGY_CLUSTERING
: components are defined by edge betweenness clustering.
COMPONENT_ASSIGNMENT_STRATEGY_SINGLE
: each node is a separate component which basically
means that there are no components that should explicitly be kept together.
clearing strategies
STRATEGY_PRESERVE_SHAPES
, STRATEGY_PRESERVE_SHAPES_UNIFORM
and STRATEGY_GLOBAL
.COMPONENT_ASSIGNMENT_STRATEGY_CUSTOMIZED
. Components can be user-defined and if none
are defined, each node is a separate component.componentAssignmentStrategy
- one of the predefined assignment strategies
java.lang.IllegalArgumentException
- if the specified strategy does not match one of the predefined strategiesCOMPONENT_ID_DPKEY
public long getMaximumDuration()
Values have to be greater than or equal to 0
.
STRATEGY_LOCAL
and STRATEGY_LOCAL_UNIFORM
a restricted time can highly affect
the quality of the edge routes and, on the other hand, significantly improve the performance.setMaximumDuration(long)
public void setMaximumDuration(long maximumDuration)
Values have to be greater than or equal to 0
.
STRATEGY_LOCAL
and STRATEGY_LOCAL_UNIFORM
a restricted time can highly affect
the quality of the edge routes and, on the other hand, significantly improve the performance.Long.MAX_VALUE
. maximumDuration
- the non-negative value that specifies the time limit in milliseconds
java.lang.IllegalArgumentException
- if the maximum duration is negativepublic boolean isFixPorts()
This property is relevant for edges that are rerouted in order to clear the area, i.e., edges
where one or both endpoints where displaced or edges that intersect the area in the input graph
(depending on property isEdgeConsiderationEnabled()
) and that are consequently handled
by the specified edge router
.
Inter-edges resulting from the area nodes
component are not affected
by this property (edges connecting area nodes with non-area nodes). For such edges,
the behavior is the same as if this property would be disabled, see the following description.
The same applies for edges incident to the expanded node
or the
descendants of the expanded node (if one endpoint is not the expanded node or a descendant).
If the ports are fixed, then the port side and location are not changed,
except for group nodes that grow due to the area
inside them. Edges at these groups
keep the port side, but the absolute location is not fixed.
If disabled, the algorithm considers specified PortConstraint
and PortCandidate
s
when rerouting edges. If there are no such constraints for an edge, then the ports of that edge can
be freely placed. This can often produce better edge routes in the resulting drawing, however,
the overall shape of the edge may then not be preserved.
true
if ports of the input are fixed, false
otherwisesetFixPorts(boolean)
public void setFixPorts(boolean fixPorts)
This property is relevant for edges that are rerouted in order to clear the area, i.e., edges
where one or both endpoints where displaced or edges that intersect the area in the input graph
(depending on property isEdgeConsiderationEnabled()
) and that are consequently handled
by the specified edge router
.
Inter-edges resulting from the area nodes
component are not affected
by this property (edges connecting area nodes with non-area nodes). For such edges,
the behavior is the same as if this property would be disabled, see the following description.
The same applies for edges incident to the expanded node
or the
descendants of the expanded node (if one endpoint is not the expanded node or a descendant).
If the ports are fixed, then the port side and location are not changed,
except for group nodes that grow due to the area
inside them. Edges at these groups
keep the port side, but the absolute location is not fixed.
If disabled, the algorithm considers specified PortConstraint
and PortCandidate
s
when rerouting edges. If there are no such constraints for an edge, then the ports of that edge can
be freely placed. This can often produce better edge routes in the resulting drawing, however,
the overall shape of the edge may then not be preserved.
fixPorts
- true
if ports of the input should be fixed, false
otherwisepublic boolean isEdgeConsiderationEnabled()
area
such that
no segments intersecting the area are allowed.
If enabled, edges that must be rerouted are not allowed to intersect the area
that
is cleared. Furthermore, edges whose source and target node are not moved but where segments intersect
the area in the input graph are rerouted in order to remove that intersection.
If disabled, edges are allowed to intersect the area that is cleared. This has the effect that the area is cleared of nodes only.
EDGE_ROUTING_STRATEGY_STRAIGHTLINE
and
EDGE_ROUTING_STRATEGY_ORGANIC
, intersections with the area are not resolved.
Use strategies EDGE_ROUTING_STRATEGY_ORTHOGONAL
or EDGE_ROUTING_STRATEGY_OCTILINEAR
if
preventing them is an important requirement.true
if edges are considered and edge intersections with the area are removed,
false
otherwisesetEdgeConsiderationEnabled(boolean)
public void setEdgeConsiderationEnabled(boolean edgeConsiderationEnabled)
area
such that
no segments intersecting the area are allowed.
If enabled, edges that must be rerouted are not allowed to intersect the area
that
is cleared. Furthermore, edges whose source and target node are not moved but where segments intersect
the area in the input graph are rerouted in order to remove that intersection.
If disabled, edges are allowed to intersect the area that is cleared. This has the effect that the area is cleared of nodes only.
EDGE_ROUTING_STRATEGY_STRAIGHTLINE
and
EDGE_ROUTING_STRATEGY_ORGANIC
, intersections with the area are not resolved.
Use strategies EDGE_ROUTING_STRATEGY_ORTHOGONAL
or EDGE_ROUTING_STRATEGY_OCTILINEAR
if
preventing them is an important requirement.edgeConsiderationEnabled
- true
if edges are considered and edge intersections with the area
should be removed, false
otherwiseInput example where the gray area must be cleared. | true - edges are considered and moved outside the area. | false - edge are still allowed in the area, only the intersecting node was moved. |
public YRectangle getArea()
All elements (nodes, edges and labels) that currently intersect the area will be moved such that the area is cleared after the layout run.
area nodes
or from the size of an expanded node
.setArea(YRectangle)
public void setArea(YRectangle area)
All elements (nodes, edges and labels) that currently intersect the area will be moved such that the area is cleared after the layout run.
area nodes
or from the size of an expanded node
.area
- the rectangular area that must be clearedpublic BorderLine[] getAreaOutline()
This property should be used if the area is not only a simple rectangular shape but more complex.
An outline consists of four BorderLine
instances, where the array is interpreted as follows:
0
: the top border line
1
: the right border line
2
: the bottom border line
3
: the left border line
setArea(YRectangle)
such that when one is
changed, internally both are changed. The setArea(YRectangle)
property is a more simple
view of this property, as it only provides the rectangular bounding box.area nodes
or from the size of an expanded node
.setAreaOutline(BorderLine[])
public void setAreaOutline(BorderLine[] areaOutline)
This property should be used if the area is not only a simple rectangular shape but more complex.
An outline consists of four BorderLine
instances, where the array is interpreted as follows:
0
: the top border line
1
: the right border line
2
: the bottom border line
3
: the left border line
setArea(YRectangle)
such that when one is
changed, internally both are changed. The setArea(YRectangle)
property is a more simple
view of this property, as it only provides the rectangular bounding box.area nodes
or from the size of an expanded node
.areaOutline
- the four border lines describing the shape of the area outline
java.lang.IllegalArgumentException
- if the given array does not contain exactly four non-null BorderLine
sprotected BorderLine[] createAreaOutline(LayoutGraph graph, NodeList areaNodes, EdgeList areaEdges)
This method is called when the area to be cleared is derived from a specified set of area
nodes, see AREA_NODES_DPKEY
. The outline is defined by four BorderLine
s, which
are then used as the area outline
for the layout run.
The default implementation of this method includes the bounds of the given nodes, the bounding boxes of the
segments of the given edges, as well as the bounds of the corresponding node and edge labels (depending on the
properties isNodeLabelConsiderationEnabled()
and isEdgeLabelConsiderationEnabled()
.
This method may be overridden if another way of deriving the area shape from the defined
nodes and edges is desired (e.g. if only nodes shall be considered, ignoring edges).
The returned array must contain exactly four BorderLine
instances where the indices
are interpreted as follows:
0
: the top border line
1
: the right border line
2
: the bottom border line
3
: the left border line
area nodes
is specified.graph
- the input graphareaNodes
- the nodes that are part of the area that should be clearedareaEdges
- the edges that are adjacent to the given area nodes
BorderLine
s describing the outline of the area to be clearedpublic byte getLayoutOrientation()
The orientation affects the direction that the algorithm prefers when moving elements.
For the vertical orientations ORIENTATION_TOP_TO_BOTTOM
and ORIENTATION_BOTTOM_TO_TOP
,
moving elements horizontally (i.e. to the left and to the right) is preferred. For the horizontal
orientations ORIENTATION_LEFT_TO_RIGHT
and ORIENTATION_RIGHT_TO_LEFT
, the vertical
moving direction is preferred. This is mainly useful for layouts that have a clear direction and
nodes are divided into layers with respect to this directions, like e.g., hierarchical layouts.
If this behavior is undesired, the orientation can be ignored by specifying ORIENTATION_NONE
.
No specific moving direction will be preferred in that case. The orientation can also be automatically
detected based on the flow direction of the edges when choosing ORIENTATION_AUTO_DETECTION
.
setLayoutOrientation(byte)
public void setLayoutOrientation(byte layoutOrientation)
The orientation affects the direction that the algorithm prefers when moving elements.
For the vertical orientations ORIENTATION_TOP_TO_BOTTOM
and ORIENTATION_BOTTOM_TO_TOP
,
moving elements horizontally (i.e. to the left and to the right) is preferred. For the horizontal
orientations ORIENTATION_LEFT_TO_RIGHT
and ORIENTATION_RIGHT_TO_LEFT
, the vertical
moving direction is preferred. This is mainly useful for layouts that have a clear direction and
nodes are divided into layers with respect to this directions, like e.g., hierarchical layouts.
If this behavior is undesired, the orientation can be ignored by specifying ORIENTATION_NONE
.
No specific moving direction will be preferred in that case. The orientation can also be automatically
detected based on the flow direction of the edges when choosing ORIENTATION_AUTO_DETECTION
.
ORIENTATION_NONE
. The layout is considered to have no specific orientation.layoutOrientation
- one of the predefined layout orientations
java.lang.IllegalArgumentException
- if the specified orientation does not match one of the predefined orientationspublic boolean isEdgeLabelConsiderationEnabled()
When enabled, the edge labels intersecting the getArea()
are explicitly rearranged even
if the corresponding edges would not be changed.
If disabled, edge labels may remain intersecting with the area
.
In addition, after moving elements to clear the area, there may be new edge label overlaps.
true
if edge labels are considered, false
otherwisepublic void setEdgeLabelConsiderationEnabled(boolean edgeLabelConsiderationEnabled)
When enabled, the edge labels intersecting the getArea()
are explicitly rearranged even
if the corresponding edges would not be changed.
If disabled, edge labels may remain intersecting with the area
.
In addition, after moving elements to clear the area, there may be new edge label overlaps.
edgeLabelConsiderationEnabled
- true
if edge labels should be considered,
false
otherwisepublic boolean isNodeLabelConsiderationEnabled()
Internally, nodes are treated like they would have a size including their labels. Therefore, layout results can get significantly less compact if this feature is enabled.
If this feature is disabled, node labels may remain intersecting with the area
.
In addition, after moving elements to clear the area, there may be new node label overlaps.
true
if node labels are considered, false
otherwisepublic void setNodeLabelConsiderationEnabled(boolean nodeLabelConsiderationEnabled)
Internally, nodes are treated like they would have a size including their labels. Therefore, layout results can get significantly less compact if this feature is enabled.
If this feature is disabled, node labels may remain intersecting with the area
.
In addition, after moving elements to clear the area, there may be new node label overlaps.
nodeLabelConsiderationEnabled
- true
if node labels should be considered,
false
otherwisepublic double getSpacing()
This spacing only affects the moving of elements out of the area
. Elements keep the
specified distance to other elements. Carefully observe that if the distance between two elements is already
smaller, then they may not be moved apart.
Strategies STRATEGY_PRESERVE_SHAPES
, STRATEGY_PRESERVE_SHAPES_UNIFORM
and
STRATEGY_GLOBAL
consider the spacing for all graph elements, including nodes, edges, node
labels and edge labels when they are encountered during the movement process.
On the other hand, strategies STRATEGY_LOCAL
and STRATEGY_LOCAL_UNIFORM
consider
the spacing only with respect to nodes.
edge router
, this spacing is
not considered. Instead, the respective distance/spacing values of the router instance apply. To configure
custom distance/spacing values for the routing, one may override method configureEdgeRouter(Layouter)
or specify a manually configured router instance.setSpacing(double)
public void setSpacing(double spacing)
This spacing only affects the moving of elements out of the area
. Elements keep the
specified distance to other elements. Carefully observe that if the distance between two elements is already
smaller, then they may not be moved apart.
Strategies STRATEGY_PRESERVE_SHAPES
, STRATEGY_PRESERVE_SHAPES_UNIFORM
and
STRATEGY_GLOBAL
consider the spacing for all graph elements, including nodes, edges, node
labels and edge labels when they are encountered during the movement process.
On the other hand, strategies STRATEGY_LOCAL
and STRATEGY_LOCAL_UNIFORM
consider
the spacing only with respect to nodes.
edge router
, this spacing is
not considered. Instead, the respective distance/spacing values of the router instance apply. To configure
custom distance/spacing values for the routing, one may override method configureEdgeRouter(Layouter)
or specify a manually configured router instance.spacing
- the non-negative spacing between elements
java.lang.IllegalArgumentException
- if the given spacing is negativeSpacing set to 10. The gray area was cleared of elements. | Spacing set to 30. The gray area was cleared of elements. |
public boolean canLayout(LayoutGraph graph)
canLayout
in interface Layouter
graph
- the input graph
true
for all kinds of graphsLayouter.doLayout(LayoutGraph)
public void doLayout(LayoutGraph graph)
getArea()
, the area defined via AREA_NODES_DPKEY
or
EXPANDED_NODE_DPKEY
by moving all other graph elements currently intersecting with it.
doLayout
in interface Layouter
graph
- the input graphLayouter.canLayout(LayoutGraph)
|
© Copyright 2000-2022, yWorks GmbH. All rights reserved. |
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |