public class ComponentLayout extends AbstractLayoutStage
ComponentLayout
arranges the connected components of a graph.
styles
. All styles except ComponentArrangementStyles.NONE
place the components without overlaps.
Layout with orthogonal components using ComponentArrangementStyles.MULTI_ROWS_COMPACT
ComponentLayout
is a ILayoutStage
that can wrap another layout algorithm
. That
way, it allows handling disconnected graphs for the wrapped
core layout algorithm
.
The following steps outline the concept of ComponentLayout
:
Optionally arrange
the components
To arrange the subgraphs of the components, ComponentLayout
uses the specified
core layout algorithm
. If there is no core layout algorithm
specified, it will keep the locations in the subgraph and arrange the components as they are.
Hierarchically grouped graphs are handled in a special way. The contents of a group node will always belong to the same
component as the group node itself. To change that behavior grouping
can be disabled.
By default, the components consist of the connected nodes in a graph. To choose custom subgraphs to form components,
register a IDataProvider
with COMPONENT_ID_DPKEY
and assign component IDs to the nodes.
MultiStageLayout
Modifier and Type | Field and Description |
---|---|
static NodeDpKey<Boolean> |
AFFECTED_COMPONENTS_DPKEY
A
DataProvider key for specifying which nodes should be arranged
If no IDataProvider is registered with this key, all components will be laid out by the core layout algorithm. |
static NodeDpKey<Comparable> |
COMPONENT_ID_DPKEY
A
DataProvider key for specifying custom graph components
|
Constructor and Description |
---|
ComponentLayout()
Creates a new
ComponentLayout instance with an optional
core layout algorithm . |
ComponentLayout(ILayoutAlgorithm coreLayouter)
Creates a new
ComponentLayout instance with an optional
core layout algorithm . |
Modifier and Type | Method and Description |
---|---|
void |
applyLayout(LayoutGraph graph)
Delegates the layout calculation for each component separately to the
core layout algorithm
and optionally arranges the components. |
protected void |
arrangeComponents(LayoutGraph graph,
NodeList[] nodes,
EdgeList[] edges,
YRectangle[] bbox,
Rectangle2D[] boxes)
Produces a component graph layout.
|
protected void |
arrangeFields(LayoutGraph graph,
NodeList[] nodes,
EdgeList[] edges,
YRectangle[] bbox,
Rectangle2D[] boxes,
boolean circular,
boolean fill,
boolean fromSketch)
Arranges the bounding boxes of the components.
|
protected Rectangle2D |
calculateBounds(LayoutGraph graph)
Calculates the bounding box of a graph component including
NodeHalo s. |
protected int |
findGraphComponents(LayoutGraph graph,
INodeMap compNumber)
Determines which nodes belong to the same graph component.
|
double |
getComponentSpacing()
Gets the distance between the bounding boxes of the components.
|
double |
getGridSpacing()
Gets the current grid spacing.
|
YDimension |
getPreferredSize()
Gets the preferred size of the layout.
|
ComponentArrangementStyles |
getStyle()
Gets how the components are arranged.
|
boolean |
isComponentArrangementEnabled()
Gets whether or not the separately arranged components of the input graph should be arranged relative to each other.
|
boolean |
isGroupingConsiderationEnabled()
Gets whether or not grouping information bound to the graph should be considered when determining the graph components.
|
boolean |
isLabelConsiderationEnabled()
Gets whether or not to take node and edge labels into account when calculating the bounding box of the graph
components.
|
void |
setComponentArrangementEnabled(boolean value)
Sets whether or not the separately arranged components of the input graph should be arranged relative to each other.
|
void |
setComponentSpacing(double value)
Sets the distance between the bounding boxes of the components.
|
void |
setGridSpacing(double value)
Sets the current grid spacing.
|
void |
setGroupingConsiderationEnabled(boolean value)
Sets whether or not grouping information bound to the graph should be considered when determining the graph components.
|
void |
setLabelConsiderationEnabled(boolean value)
Sets whether or not to take node and edge labels into account when calculating the bounding box of the graph
components.
|
protected void |
setOrigin(LayoutGraph graph,
NodeList nodes,
EdgeList edges,
YPoint origin,
YRectangle rectangle)
Moves the subgraph containing the given nodes and edges to the specified origin.
|
void |
setPreferredSize(YDimension value)
Sets the preferred size of the layout.
|
void |
setStyle(ComponentArrangementStyles value)
Sets how the components are arranged.
|
applyLayoutCore, getCoreLayout, setCoreLayout
public static final NodeDpKey<Boolean> AFFECTED_COMPONENTS_DPKEY
DataProvider
key for specifying which nodes should be arranged
If no IDataProvider
is registered with this key, all components will be laid out by the core layout algorithm.
public static final NodeDpKey<Comparable> COMPONENT_ID_DPKEY
DataProvider
key for specifying custom graph components
public ComponentLayout()
ComponentLayout
instance with an optional
core layout algorithm
.public ComponentLayout(ILayoutAlgorithm coreLayouter)
ComponentLayout
instance with an optional
core layout algorithm
.coreLayouter
- The core layout algortihm.public void applyLayout(LayoutGraph graph)
core layout algorithm
and optionally arranges the components.applyLayout
in interface ILayoutAlgorithm
applyLayout
in class AbstractLayoutStage
graph
- the input graphprotected void arrangeComponents(LayoutGraph graph, NodeList[] nodes, EdgeList[] edges, YRectangle[] bbox, Rectangle2D[] boxes)
This method is called by applyLayout(LayoutGraph)
in case component arrangement
is enabled. It moves the graph's components such that their bounding boxes do not overlap. Subclasses may want to
override this method to introduce custom component arrangement styles.
ComponentArrangementStyles.NONE
, ComponentArrangementStyles.SINGLE_ROW
and ComponentArrangementStyles.SINGLE_COLUMN
are excluded.graph
- the input graphnodes
- the nodes of the components; the i-th list contains the nodes of the i-th componentedges
- the edges of the components; the i-th list contains the edges of the i-th componentbbox
- the bounds of the components; the i-th rectangle describes the bounding box of the i-th componentboxes
- the extended bounds of the components; the i-th rectangle describes the bounding box of the i-th component extended by
the spacing between components. The method arranges these boxes in such a way that they do not overlap. Then, the i-th
graph component must be placed inside the i-th boxarrangeFields(LayoutGraph, NodeList[], EdgeList[], YRectangle[], Rectangle2D[], boolean, boolean, boolean)
,
LayoutGraphUtilities.arrangeRectangleRows(Rectangle2D[], Rectangle2D, double, RowAlignment)
,
LayoutGraphUtilities.arrangeRectangleMultiRows(Rectangle2D[], Rectangle2D, double, double, boolean, MultiRowConstraint, RowAlignment)
protected void arrangeFields(LayoutGraph graph, NodeList[] nodes, EdgeList[] edges, YRectangle[] bbox, Rectangle2D[] boxes, boolean circular, boolean fill, boolean fromSketch)
This method is called by arrangeComponents(LayoutGraph, NodeList[], EdgeList[], YRectangle[], Rectangle2D[])
if
the style
is set to ComponentArrangementStyles.PACKED_RECTANGLE
,
ComponentArrangementStyles.PACKED_COMPACT_RECTANGLE
, ComponentArrangementStyles.PACKED_CIRCLE
or
ComponentArrangementStyles.PACKED_COMPACT_CIRCLE
. It may be overridden to adjust the component arrangement
strategy of the mentioned styles.
graph
- the input graphnodes
- the nodes of the components; the i-th list contains the nodes of the i-th componentedges
- the edges of the components; the i-th list contains the edges of the i-th componentbbox
- the bounds of the components; the i-th rectangle describes the bounding box of the i-th componentboxes
- the extended bounds of the components; the i-th rectangle describes the bounding box of the i-th componentcircular
- true
if the arrangement should be circular, false
if it should be rectangularfill
- true
if it is allowed to place components in empty spaces inside other
components, false
otherwisefromSketch
- true
if the initial coordinates should be considered, false
otherwiseprotected Rectangle2D calculateBounds(LayoutGraph graph)
NodeHalo
s.
This method will be invoked for each component of the graph. Depending on the state of property
LabelConsiderationEnabled
, the returned bounding box will also include node
and edge labels. It may be overridden to extend the bounds to reserve space for other elements.
graph
- the subgraph containing the nodes and edges of a componentsetLabelConsiderationEnabled(boolean)
protected int findGraphComponents(LayoutGraph graph, INodeMap compNumber)
This implementation uses the graph connectivity to sort the nodes into different components. Nodes that are not connected by a path will be in separate components.
This method is called by applyLayout(LayoutGraph)
. It may be overridden to choose another approach to find
components that will be passed to the
core layout algorithm
. However, most of the layout algorithms cannot
handle disconnected graphs. Also, edges between custom components will be ignored.
graph
- the input graphcompNumber
- a map that will be filled with the zero-based index of the component to which the node belongsGraphConnectivity.connectedComponents(com.yworks.yfiles.algorithms.Graph)
public double getComponentSpacing()
The spacing needs to be non-negative.
IllegalArgumentException
- if the spacing is negativesetComponentSpacing(double)
public double getGridSpacing()
Components will be 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 also influences the distance between the components.
The spacing needs to be a non-negative value. If the grid spacing is set to
0
, the grid won't be considered at all.
IllegalArgumentException
- if the given spacing is negativesetGridSpacing(double)
public YDimension getPreferredSize()
The layout size also defines the desired aspect ratio (width/height).
The width and height need to be greater than zero.
IllegalArgumentException
- if the specified width or height is negative or zero.ComponentArrangementStyles.NONE
, ComponentArrangementStyles.SINGLE_ROW
and ComponentArrangementStyles.SINGLE_COLUMN
do not consider the preferred layout size.YDimension
. Both preferred width and height are 400
.setPreferredSize(YDimension)
public ComponentArrangementStyles getStyle()
IllegalArgumentException
- if the specified style is unknowncomponent arrangement
is disabled.ComponentArrangementStyles.ROWS
setStyle(ComponentArrangementStyles)
public boolean isComponentArrangementEnabled()
If enabled, the components are arranged using a specific style
without producing overlaps between
components (except for
ComponentArrangementStyles.NONE
). Otherwise, the layout algorithm will keep the components at their
location. Then, the components may overlap.
true
. The components are arranged relative to each other.true
if the components of the graph are arranged, false
otherwisesetComponentArrangementEnabled(boolean)
public boolean isGroupingConsiderationEnabled()
true
. Grouping information is considered for determining the components.true
if the nesting structure of the graph is considered when determining the components, false
otherwisesetGroupingConsiderationEnabled(boolean)
public boolean isLabelConsiderationEnabled()
true
. Node and edge labels are included in the bounds of the components.true
if node and edge labels are taken into account when calculating the bounding box of the graph components, false
otherwisecalculateBounds(LayoutGraph)
,
setLabelConsiderationEnabled(boolean)
public void setComponentArrangementEnabled(boolean value)
If enabled, the components are arranged using a specific style
without producing overlaps between
components (except for
ComponentArrangementStyles.NONE
). Otherwise, the layout algorithm will keep the components at their
location. Then, the components may overlap.
true
. The components are arranged relative to each other.value
- true
if the components of the graph are arranged, false
otherwiseisComponentArrangementEnabled()
public void setComponentSpacing(double value)
The spacing needs to be non-negative.
IllegalArgumentException
- if the spacing is negativevalue
- the component spacinggetComponentSpacing()
public void setGridSpacing(double value)
Components will be 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 also influences the distance between the components.
The spacing needs to be a non-negative value. If the grid spacing is set to
0
, the grid won't be considered at all.
IllegalArgumentException
- if the given spacing is negativevalue
- the grid spacinggetGridSpacing()
public void setGroupingConsiderationEnabled(boolean value)
true
. Grouping information is considered for determining the components.value
- true
if the nesting structure of the graph is considered when determining the components, false
otherwiseisGroupingConsiderationEnabled()
public void setLabelConsiderationEnabled(boolean value)
true
. Node and edge labels are included in the bounds of the components.value
- true
if node and edge labels are taken into account when calculating the bounding box of the graph components, false
otherwisecalculateBounds(LayoutGraph)
,
isLabelConsiderationEnabled()
protected void setOrigin(LayoutGraph graph, NodeList nodes, EdgeList edges, YPoint origin, YRectangle rectangle)
This method is called by arrangeComponents(LayoutGraph, NodeList[], EdgeList[], YRectangle[], Rectangle2D[])
and arrangeFields(LayoutGraph, NodeList[], EdgeList[], YRectangle[], Rectangle2D[], boolean, boolean, boolean)
to move the components to overlap-free positions.
graph
- the input graphnodes
- the nodes in the moving subgraphedges
- the edges in the moving subgraphorigin
- the new origin of the graphrectangle
- the current bounds of the subgraphpublic void setPreferredSize(YDimension value)
The layout size also defines the desired aspect ratio (width/height).
The width and height need to be greater than zero.
IllegalArgumentException
- if the specified width or height is negative or zero.ComponentArrangementStyles.NONE
, ComponentArrangementStyles.SINGLE_ROW
and ComponentArrangementStyles.SINGLE_COLUMN
do not consider the preferred layout size.YDimension
. Both preferred width and height are 400
.value
- the preferred size of the calculated graph layoutgetPreferredSize()
public void setStyle(ComponentArrangementStyles value)
IllegalArgumentException
- if the specified style is unknowncomponent arrangement
is disabled.ComponentArrangementStyles.ROWS
value
- one of the valid style specifiersgetStyle()