public class PartialLayout extends AbstractLayoutStage
The location and size of the remaining elements (called fixed elements) is not allowed to be changed.
This partial layout algorithm offers a kind of generic partial layout support for other existing layout algorithms.
Hence, its layout style heavily depends on the selected core layout algorithm
as well as the specified edge router
or
edge routing strategy
.
The partial layout is suitable for applications where users may incrementally add new elements to an existing drawing. The added elements should be arranged so that they fit best possible into the given diagram without making any changes to the already existing layout. Hence, the so-called mental map of the existing drawing is preserved.
The input graph where marked nodes denote the partial elements that were incrementally added to the existing diagram.
The result of a partial layout run with component assignment strategy
set to ComponentAssignmentStrategy.SINGLE
and with node alignment
enabled.
Similar to the layout style, the supported feature set mainly depends on the features supported by the specified core layout algorithm
as well as the specified edge router
or
edge routing strategy
. The internal step that places the components
can handle group nodes as well as minimum distance constraints. Furthermore, it is able to consider node labels.
The layout algorithm handles each selected graph element as partial element. For this, it looks up the IDataProvider
keys AFFECTED_NODES_DPKEY
and AFFECTED_EDGES_DPKEY
. Partial node elements can be assigned to the
so-called subgraph components. During the layout process each subgraph induced by the nodes of a component is
first laid out using the specified core layout algorithm
. Then, the different
components are placed one-by-one onto the drawing area such that the number of overlaps among graph elements is small.
The user can specify different objectives for finding 'good' positions for subgraph components (see
SubgraphPlacement
), e.g., SubgraphPlacement.BARYCENTER
specifies that the component should be placed close to the barycenter of its graph neighbors and SubgraphPlacement.FROM_SKETCH
specifies that the component should be placed close to its original position.
Method ComponentAssignmentStrategy
allows to
specify the strategy that assigns partial nodes to subgraph components. Possible values are
ComponentAssignmentStrategy.CLUSTERING
, ComponentAssignmentStrategy.CONNECTED
, ComponentAssignmentStrategy.SINGLE
and
ComponentAssignmentStrategy.CUSTOMIZED
. The last value allows to use a customized component assignment. Note
that nodes of a component cannot be assigned to different group nodes.
Furthermore, the user can specify the edge routing strategy (see
EdgeRoutingStrategy
) that is used for routing partial edges and
edges between different subgraph components (so-called inter-edges). Possible values are
EdgeRoutingStrategy.ORGANIC
, EdgeRoutingStrategy.ORTHOGONAL
,
EdgeRoutingStrategy.STRAIGHTLINE
, EdgeRoutingStrategy.OCTILINEAR
and
EdgeRoutingStrategy.AUTOMATIC
.
Modifier and Type | Field and Description |
---|---|
static EdgeDpKey<Boolean> |
AFFECTED_EDGES_DPKEY
A
DataProvider key for marking partial edges.
|
static NodeDpKey<Boolean> |
AFFECTED_NODES_DPKEY
A
DataProvider key for marking partial nodes.
|
static NodeDpKey<Object> |
COMPONENT_ID_DPKEY
A
DataProvider key for defining custom subgraph components.
|
static EdgeDpKey<Boolean> |
DIRECTED_EDGES_DPKEY
A
DataProvider key for specifying the edges that should be considered to be directed.
|
static EdgeDpKey<Boolean> |
ROUTE_EDGE_DPKEY
A
DataProvider key for obtaining the edges that should be routed by the edge router.
|
Constructor and Description |
---|
PartialLayout()
Creates a new instance of
PartialLayout which uses the specified ILayoutAlgorithm instance as the core
layout algorithm. |
PartialLayout(ILayoutAlgorithm subgraphLayouter)
Creates a new instance of
PartialLayout which uses the specified ILayoutAlgorithm instance as the core
layout algorithm. |
Modifier and Type | Method and Description |
---|---|
void |
applyLayout(LayoutGraph graph)
This method calculates the partial layout.
|
protected void |
configureEdgeRouter(ILayoutAlgorithm edgeRouter)
This method is called each time when edges are routed with an edge router.
|
ComponentAssignmentStrategy |
getComponentAssignmentStrategy()
Gets the strategy that assigns partial nodes to subgraph components.
|
ILayoutAlgorithm |
getCoreLayout()
Gets the
ILayoutAlgorithm instance that is applied to each subgraph component. |
ILayoutAlgorithm |
getEdgeRouter()
Gets the custom edge router instance that is used for partial edges and edges between different subgraph components
(so-called inter-edges).
|
EdgeRoutingStrategy |
getEdgeRoutingStrategy()
Gets the routing strategy that is used for partial edges and edges between different subgraph components (so-called
inter-edges).
|
LayoutOrientation |
getLayoutOrientation()
Gets the layout orientation that is considered during the placement of partial elements.
|
long |
getMaximumDuration()
Gets the preferred time limit (in milliseconds) for the layout algorithm.
|
int |
getMinimumNodeDistance()
Gets the minimum distance between two adjacent nodes.
|
SubgraphPlacement |
getSubgraphPlacement()
Gets the objective used for finding 'good' positions for subgraph components.
|
boolean |
isComponentCompactionEnabled()
Gets whether or not a subgraph component may be placed within another subgraph component.
|
boolean |
isImmediateInterEdgeRoutingEnabled()
Gets whether or not edges between different subgraph components should be routed immediately.
|
boolean |
isMirroringAllowed()
Gets whether or not subgraph components are mirrored to improve the layout quality.
|
boolean |
isNodeAlignmentConsiderationEnabled()
Gets whether or not partial nodes should be aligned.
|
boolean |
isOrientationOptimizationEnabled()
Gets whether or not a postprocessing step should be applied to reduce the number of directed edges that do not comply
with the specified layout orientation.
|
boolean |
isResizeFixedGroups()
Gets whether or not fixed (non-partial) group nodes may be resized.
|
protected void |
layoutSubgraph(LayoutGraph subGraph)
This method is called during the
layout process and calculates the layout for the
given subgraph component using the specified core layout algorithm . |
protected void |
placeSubgraphs(LayoutGraph graph,
NodeList[] subgraphComponents)
This method is called during the
layout process and places the subgraph components
one-by-one onto the drawing area. |
protected void |
routeEdgesBetweenFixedElements(LayoutGraph graph,
EdgeList partialEdges)
This method is called during the
layout process and routes all partial edges that
connect two fixed elements. |
protected void |
routeInterEdges(LayoutGraph graph,
EdgeList interEdges)
This method is called during the
layout process and routes all inter-edges. |
void |
setComponentAssignmentStrategy(ComponentAssignmentStrategy value)
Sets the strategy that assigns partial nodes to subgraph components.
|
void |
setComponentCompactionEnabled(boolean value)
Sets whether or not a subgraph component may be placed within another subgraph component.
|
void |
setCoreLayout(ILayoutAlgorithm value)
Sets the
ILayoutAlgorithm instance that is applied to each subgraph component. |
void |
setEdgeRouter(ILayoutAlgorithm value)
Sets the custom edge router instance that is used for partial edges and edges between different subgraph components
(so-called inter-edges).
|
void |
setEdgeRoutingStrategy(EdgeRoutingStrategy value)
Sets the routing strategy that is used for partial edges and edges between different subgraph components (so-called
inter-edges).
|
void |
setImmediateInterEdgeRoutingEnabled(boolean value)
Sets whether or not edges between different subgraph components should be routed immediately.
|
void |
setLayoutOrientation(LayoutOrientation value)
Sets the layout orientation that is considered during the placement of partial elements.
|
void |
setMaximumDuration(long value)
Sets the preferred time limit (in milliseconds) for the layout algorithm.
|
void |
setMinimumNodeDistance(int value)
Sets the minimum distance between two adjacent nodes.
|
void |
setMirroringAllowed(boolean value)
Sets whether or not subgraph components are mirrored to improve the layout quality.
|
void |
setNodeAlignmentConsiderationEnabled(boolean value)
Sets whether or not partial nodes should be aligned.
|
void |
setOrientationOptimizationEnabled(boolean value)
Sets whether or not a postprocessing step should be applied to reduce the number of directed edges that do not comply
with the specified layout orientation.
|
void |
setResizeFixedGroups(boolean value)
Sets whether or not fixed (non-partial) group nodes may be resized.
|
void |
setSubgraphPlacement(SubgraphPlacement value)
Sets the objective used for finding 'good' positions for subgraph components.
|
applyLayoutCore
public static final EdgeDpKey<Boolean> AFFECTED_EDGES_DPKEY
DataProvider
key for marking partial edges.
AFFECTED_NODES_DPKEY
public static final NodeDpKey<Boolean> AFFECTED_NODES_DPKEY
DataProvider
key for marking partial nodes.
AFFECTED_EDGES_DPKEY
public static final NodeDpKey<Object> COMPONENT_ID_DPKEY
DataProvider
key for defining custom subgraph components.
IDataProvider
is only considered if ComponentAssignmentStrategy
is set to ComponentAssignmentStrategy.CUSTOMIZED
.ComponentAssignmentStrategy.CUSTOMIZED
,
setComponentAssignmentStrategy(ComponentAssignmentStrategy)
public static final EdgeDpKey<Boolean> DIRECTED_EDGES_DPKEY
DataProvider
key for specifying the edges that should be considered to be directed.
If a layout orientation is specified (i.e., LayoutOrientation
is not
LayoutOrientation.NONE
), the algorithm tries to route directed edges such that they adhere to that
orientation.
IDataProvider
is not registered, all edges are considered to be directed.setLayoutOrientation(LayoutOrientation)
public static final EdgeDpKey<Boolean> ROUTE_EDGE_DPKEY
DataProvider
key for obtaining the edges that should be routed by the edge router.
IDataProvider
must not be set by the user! The key is used by this algorithm to temporarily add a
IDataProvider
that marks edges that should be routed by the specified edge router, see
EdgeRouter
.setEdgeRouter(ILayoutAlgorithm)
public PartialLayout()
PartialLayout
which uses the specified ILayoutAlgorithm
instance as the core
layout algorithm.
This instance is applied to each subgraph component, see
ComponentAssignmentStrategy
.
public PartialLayout(ILayoutAlgorithm subgraphLayouter)
PartialLayout
which uses the specified ILayoutAlgorithm
instance as the core
layout algorithm.
This instance is applied to each subgraph component, see
ComponentAssignmentStrategy
.
subgraphLayouter
- the layout algorithm that is applied to the subgraph componentssetComponentAssignmentStrategy(ComponentAssignmentStrategy)
public void applyLayout(LayoutGraph graph)
It calls the following methods:
applyLayout
in interface ILayoutAlgorithm
applyLayout
in class AbstractLayoutStage
OrientationLayout
. Hence, they always assume that the graph is drawn from top to bottom.graph
- the input graphprotected void configureEdgeRouter(ILayoutAlgorithm edgeRouter)
Subclasses may modify the configuration of the given edge router instance.
The type of the given instance depends on the edge routing strategy, i.e., if the routing strategy is set to EdgeRoutingStrategy.OCTILINEAR
or EdgeRoutingStrategy.ORTHOGONAL
it's an instance of
EdgeRouter
, if the routing strategy is set to EdgeRoutingStrategy.ORGANIC
it's an instance of OrganicLayout
, and, if the routing strategy is set to EdgeRoutingStrategy.STRAIGHTLINE
it's an instance of a private StraightLineEdgeRouter
. If the edge routing
strategy is set to
EdgeRoutingStrategy.AUTOMATIC
, the layout algorithm chooses one of the above strategies that best fits the
routing style of the fixed edges.
EdgeRouter
), its instance corresponds to that of the parameter.edgeRouter
- the instance used for routing the edgessetEdgeRouter(ILayoutAlgorithm)
,
setEdgeRoutingStrategy(EdgeRoutingStrategy)
public ComponentAssignmentStrategy getComponentAssignmentStrategy()
The specified core layouter (see
CoreLayout
) independently calculates the layout for each such subgraph
component.
IllegalArgumentException
- if the specified strategy does not match one of the predefined assignment strategies.ComponentAssignmentStrategy.SINGLE
. Each partial node is assigned to a separate subgraph component.setCoreLayout(ILayoutAlgorithm)
,
setComponentAssignmentStrategy(ComponentAssignmentStrategy)
public ILayoutAlgorithm getCoreLayout()
ILayoutAlgorithm
instance that is applied to each subgraph component.
More precisely, during the layout process each subgraph induced by the (partial) nodes of a component (see
ComponentAssignmentStrategy
) is first laid out
using this instance.
getCoreLayout
in interface ILayoutStage
getCoreLayout
in class AbstractLayoutStage
ILayoutAlgorithm
instance that is applied to each subgraph componentsetCoreLayout(ILayoutAlgorithm)
public ILayoutAlgorithm getEdgeRouter()
EdgeRoutingStrategy
automatically sets a new edge
router instance according to the specified routing strategy.IDataProvider
key
ROUTE_EDGE_DPKEY
. Hence, the specified router has to be configured such that it observes this key and only
routes marked edges!StraightLineEdgeRouter
ROUTE_EDGE_DPKEY
,
setEdgeRoutingStrategy(EdgeRoutingStrategy)
,
setEdgeRouter(ILayoutAlgorithm)
public EdgeRoutingStrategy getEdgeRoutingStrategy()
IllegalArgumentException
- if the specified strategy does not match one of the predefined routing strategiesEdgeRouter
.EdgeRoutingStrategy.STRAIGHTLINE
setEdgeRouter(ILayoutAlgorithm)
,
setEdgeRoutingStrategy(EdgeRoutingStrategy)
public LayoutOrientation getLayoutOrientation()
More precisely, the algorithm tries to place each subgraph component
such that each predecessor of a component's node v
is placed before v
and each successor after v
with respect to the layout orientation.
IllegalArgumentException
- if the specified orientation does not match one of the predefined orientationscore layout algorithm
.LayoutOrientation.NONE
. The layout orientation is completely ignored.DIRECTED_EDGES_DPKEY
,
setLayoutOrientation(LayoutOrientation)
public long getMaximumDuration()
The specified value has to be greater than or equal to 0
. If the value is
Integer.MAX_VALUE
, the time is not limited.
IllegalArgumentException
- if the maximum duration is negativeInteger.MAX_VALUE
. The time is not limited.setMaximumDuration(long)
public int getMinimumNodeDistance()
The specified value has to be non-negative.
IllegalArgumentException
- if the distance is negativesetMinimumNodeDistance(int)
public SubgraphPlacement getSubgraphPlacement()
IllegalArgumentException
- if the specified strategy does not match one of the predefined positioning strategiesSubgraphPlacement.BARYCENTER
. Each subgraph component is placed close to the barycenter of its graph neighbors.setSubgraphPlacement(SubgraphPlacement)
public boolean isComponentCompactionEnabled()
Enabling this option leads to more compact layout results but requires more runtime.
true
. Subgraph component may be placed within another subgraph component.true
if a subgraph component may be placed within another subgraph component, false
otherwisesetComponentCompactionEnabled(boolean)
public boolean isImmediateInterEdgeRoutingEnabled()
If this option is enabled, edges are routed during the placement of the subgraph components, i.e., immediately after a component is placed, its edges to other already placed components are routed. Otherwise, these edges are routed in a separate step after placing all subgraph components. Hence, while enabling this option usually leads to shorter edge routes, the placement of subgraph components is less compact.
false
. Edges are not routed immediately.true
if edges between different subgraph components are routed immediately, false
otherwise.routeInterEdges(LayoutGraph, EdgeList)
,
placeSubgraphs(LayoutGraph, NodeList[])
,
setImmediateInterEdgeRoutingEnabled(boolean)
public boolean isMirroringAllowed()
If enabled, the algorithm checks for each component which of the four possible mirrorings minimizes the edge length.
false
. Mirroring is disabled.true
if subgraph components are mirrored, false
otherwisesetMirroringAllowed(boolean)
public boolean isNodeAlignmentConsiderationEnabled()
If this option is enabled, the algorithm tries to align the center of partial nodes with other nodes.
core layout algorithm
doesn't consider this option, the
alignment works best if the component assignment
is
set to ComponentAssignmentStrategy.SINGLE
.false
. Nodes are not aligned.true
if nodes are aligned, false
otherwisesetNodeAlignmentConsiderationEnabled(boolean)
public boolean isOrientationOptimizationEnabled()
true
. This postprocessing step is enabled.true
if this postprocessing step is applied, false
otherwisesetLayoutOrientation(LayoutOrientation)
,
DIRECTED_EDGES_DPKEY
,
setOrientationOptimizationEnabled(boolean)
public boolean isResizeFixedGroups()
Enabling this option may lead to better results if there are fixed group nodes, since there is more space for the partial elements.
false
. Fixed group nodes may not be resized.true
if fixed group nodes may be resized, false
otherwisesetResizeFixedGroups(boolean)
protected void layoutSubgraph(LayoutGraph subGraph)
layout process
and calculates the layout for the
given subgraph component using the specified core layout algorithm
.
It is called once for each subgraph component.
Subclasses may implement a custom layout strategy or add some additional data.
subGraph
- the subgraph componentprotected void placeSubgraphs(LayoutGraph graph, NodeList[] subgraphComponents)
layout process
and places the subgraph components
one-by-one onto the drawing area.
Therefore, it considers the specified objective
for finding a suitable
position.
Subclasses may implement a custom placement strategy or add some additional data. However, they must not modify the given subgraph component lists.
graph
- the input graphsubgraphComponents
- each entry contains a NodeList
that induces a subgraph componentprotected void routeEdgesBetweenFixedElements(LayoutGraph graph, EdgeList partialEdges)
layout process
and routes all partial edges that
connect two fixed elements.
It either uses a custom edge router
or an internal edge router that produces
routes according to the specified routing strategy
.
Subclasses may implement a custom routing strategy or add some additional data.
graph
- the subgraph of the input graph induced by the fixed nodespartialEdges
- the list of partial edges
to be routedprotected void routeInterEdges(LayoutGraph graph, EdgeList interEdges)
layout process
and routes all inter-edges.
Inter-edges are edges between different subgraph components including edges between fixed and partial elements.
For the routing, this method uses the edge router instance set with method
EdgeRouter
. If no edge router was specified by the user, it uses an
internal edge router with routing strategy EdgeRoutingStrategy
.
Subclasses may implement a custom routing strategy or add some additional data.
graph
- the relevant subgraphinterEdges
- the list of inter-edges
to be routedpublic void setComponentAssignmentStrategy(ComponentAssignmentStrategy value)
The specified core layouter (see
CoreLayout
) independently calculates the layout for each such subgraph
component.
IllegalArgumentException
- if the specified strategy does not match one of the predefined assignment strategies.ComponentAssignmentStrategy.SINGLE
. Each partial node is assigned to a separate subgraph component.value
- one of the predefined assignment strategiessetCoreLayout(ILayoutAlgorithm)
,
getComponentAssignmentStrategy()
public void setComponentCompactionEnabled(boolean value)
Enabling this option leads to more compact layout results but requires more runtime.
true
. Subgraph component may be placed within another subgraph component.value
- true
if a subgraph component may be placed within another subgraph component, false
otherwiseisComponentCompactionEnabled()
public void setCoreLayout(ILayoutAlgorithm value)
ILayoutAlgorithm
instance that is applied to each subgraph component.
More precisely, during the layout process each subgraph induced by the (partial) nodes of a component (see
ComponentAssignmentStrategy
) is first laid out
using this instance.
setCoreLayout
in interface ILayoutStage
setCoreLayout
in class AbstractLayoutStage
value
- the ILayoutAlgorithm
instance that is applied to each subgraph componentgetCoreLayout()
public void setEdgeRouter(ILayoutAlgorithm value)
EdgeRoutingStrategy
automatically sets a new edge
router instance according to the specified routing strategy.IDataProvider
key
ROUTE_EDGE_DPKEY
. Hence, the specified router has to be configured such that it observes this key and only
routes marked edges!StraightLineEdgeRouter
value
- the custom edge router instance that is used for partial edges and edges between different subgraph componentsROUTE_EDGE_DPKEY
,
setEdgeRoutingStrategy(EdgeRoutingStrategy)
,
getEdgeRouter()
public void setEdgeRoutingStrategy(EdgeRoutingStrategy value)
IllegalArgumentException
- if the specified strategy does not match one of the predefined routing strategiesEdgeRouter
.EdgeRoutingStrategy.STRAIGHTLINE
value
- one of the predefined edge routing strategiessetEdgeRouter(ILayoutAlgorithm)
,
getEdgeRoutingStrategy()
public void setImmediateInterEdgeRoutingEnabled(boolean value)
If this option is enabled, edges are routed during the placement of the subgraph components, i.e., immediately after a component is placed, its edges to other already placed components are routed. Otherwise, these edges are routed in a separate step after placing all subgraph components. Hence, while enabling this option usually leads to shorter edge routes, the placement of subgraph components is less compact.
false
. Edges are not routed immediately.value
- true
if edges between different subgraph components are routed immediately, false
otherwise.routeInterEdges(LayoutGraph, EdgeList)
,
placeSubgraphs(LayoutGraph, NodeList[])
,
isImmediateInterEdgeRoutingEnabled()
public void setLayoutOrientation(LayoutOrientation value)
More precisely, the algorithm tries to place each subgraph component
such that each predecessor of a component's node v
is placed before v
and each successor after v
with respect to the layout orientation.
IllegalArgumentException
- if the specified orientation does not match one of the predefined orientationscore layout algorithm
.LayoutOrientation.NONE
. The layout orientation is completely ignored.value
- one of the predefined layout orientationsDIRECTED_EDGES_DPKEY
,
getLayoutOrientation()
public void setMaximumDuration(long value)
The specified value has to be greater than or equal to 0
. If the value is
Integer.MAX_VALUE
, the time is not limited.
IllegalArgumentException
- if the maximum duration is negativeInteger.MAX_VALUE
. The time is not limited.value
- the preferred time limitgetMaximumDuration()
public void setMinimumNodeDistance(int value)
The specified value has to be non-negative.
IllegalArgumentException
- if the distance is negativevalue
- the non-negative minimum distancegetMinimumNodeDistance()
public void setMirroringAllowed(boolean value)
If enabled, the algorithm checks for each component which of the four possible mirrorings minimizes the edge length.
false
. Mirroring is disabled.value
- true
if subgraph components are mirrored, false
otherwiseisMirroringAllowed()
public void setNodeAlignmentConsiderationEnabled(boolean value)
If this option is enabled, the algorithm tries to align the center of partial nodes with other nodes.
core layout algorithm
doesn't consider this option, the
alignment works best if the component assignment
is
set to ComponentAssignmentStrategy.SINGLE
.false
. Nodes are not aligned.value
- true
if nodes are aligned, false
otherwiseisNodeAlignmentConsiderationEnabled()
public void setOrientationOptimizationEnabled(boolean value)
true
. This postprocessing step is enabled.value
- true
if this postprocessing step is applied, false
otherwisesetLayoutOrientation(LayoutOrientation)
,
DIRECTED_EDGES_DPKEY
,
isOrientationOptimizationEnabled()
public void setResizeFixedGroups(boolean value)
Enabling this option may lead to better results if there are fixed group nodes, since there is more space for the partial elements.
false
. Fixed group nodes may not be resized.value
- true
if fixed group nodes may be resized, false
otherwiseisResizeFixedGroups()
public void setSubgraphPlacement(SubgraphPlacement value)
IllegalArgumentException
- if the specified strategy does not match one of the predefined positioning strategiesSubgraphPlacement.BARYCENTER
. Each subgraph component is placed close to the barycenter of its graph neighbors.value
- one of the predefined positioning strategiesgetSubgraphPlacement()