C

RecursiveGroupLayout

This layout algorithm recursively traverses a hierarchically organized graph in a bottom-up fashion and applies a specified layout algorithm to the contents (direct children) of each group node.

Remarks

Layout Style

The way a graph is arranged depends on the layout algorithms which are applied to the different group nodes. RecursiveGroupLayout is able to produce different layout styles for the content of each group node.

This layout algorithm can be either applied if an ILayoutAlgorithm cannot handle grouped graphs by itself or if the content of (some) group nodes should be arranged differently.

Concept

RecursiveGroupLayout uses a hierarchy tree representation of the grouped graph in which the content nodes are the children of their containing group node. That way, it can traverse the tree recursively while arranging only the direct children of each group node. The layout algorithm starts by arranging the leaves in the hierarchy tree, then works its way up to the root computing the layout for each group node in the tree.

A) Group Handling

All nodes other than the direct children are temporarily hidden. The layout algorithm performs two steps for each group node.

  1. It arranges the direct children using either the coreLayout or a special layout algorithm defined using the layout data property groupNodeLayouts. The content of group nodes among the children is already arranged at this time and will be ignored. These group nodes are handled like normal nodes with a size that encloses the content.

    The following two special cases should be considered. If null is specified as layout algorithm for a group, the recursion will be disabled and the group is handled non-recursively: the group itself and its content is arranged by the algorithm specified for the nearest ancestor which has a non-null algorithm mapped to it. Importantly, this must be distinguished from the second case where the layout of the group content should remain unchanged. This is achieved when the group is associated with FIX_CONTENT_LAYOUT as responsible layout algorithm (or any other algorithm that does not change the layout).

  2. Then RecursiveGroupLayout computes the final size of the group node using an implementation of ILayoutGroupBoundsCalculator. Customized ILayoutGroupBoundsCalculators can be specified using groupBoundsCalculator. Aside from the resulting layout, this size is used in the following iteration.

B) Top-Level Hierarchy

After a layout is applied to all group nodes, the layout algorithm uses the coreLayout to arrange the top level hierarchy. Note that RecursiveGroupLayout can run without a core layout. In this case no layout is calculated for the top level hierarchy. Still, for group nodes with a non-null algorithm, the bounds are adjusted to fit their respective contents.

C) Inter-Edge Routing

Finally, routes for the edges whose source node is located at a different hierarchy level than its target node are computed. The edge routing algorithm for these so-called inter-edges can be customized.

Features

To apply different layout styles to the contents of group nodes, it is required to map each group node to a corresponding ILayoutAlgorithm via groupNodeLayouts. The content of the hierarchy root is arranged with the coreLayout.

Since RecursiveGroupLayout delegates the actual arrangement of the graph to other layout algorithms, it will support the same features as the currently used layout algorithm.

The improvement of the routing of inter-edges is based on the insertion of EdgePortCandidates. Hence, they only work well if the applied layout algorithm supports EdgePortCandidates.

This algorithm also provides a fromSketchMode that should be activated if the applied layout algorithm runs in From Sketch mode, too. Otherwise, the initial coordinates may not be considered correctly.

It is also possible to apply individual layout styles to different sub-graphs using this algorithm without actually defining group nodes: Use TemporaryGroupInsertionStage and specify RecursiveGroupLayout as its core layout algorithm. The stage allows to define sub-graphs which are internally enclosed by a temporary group node. To assign a specific ILayoutAlgorithm instance for a temporary group, specify the desired ILayoutAlgorithm in the TemporaryGroupDescriptor's property recursiveGroupLayoutAlgorithm. It is then not necessary to use groupNodeLayouts.

Default Values of Properties

NameDefaultDescription
considerEmptyGroupsfalse
Empty group nodes are not resized.
coreLayoutnull
fromSketchModefalse
The initial coordinates of the nodes are not taken into account.
groupBoundsCalculatorGroupBoundsCalculator
interEdgeRouternull
Edges are routed as straight lines from source to target.

See Also

Developer's Guide

Members

Show:

Constructors

Creates a new instance of RecursiveGroupLayout.

Parameters

coreLayout?: ILayoutAlgorithm
The layout algorithm that is applied in each step of the recursion. The default value is null.
groupBoundsCalculator?: ILayoutGroupBoundsCalculator
An optional ILayoutGroupBoundsCalculator for calculating group sizes. The default value is GroupBoundsCalculator.

Properties

Gets or sets whether or not temporary LayoutPortCandidates are inserted to improve the routing of inter-edges.

If enabled, RecursiveGroupLayout will insert LayoutPortCandidates for all inter-edges that cross a group node border. Those LayoutPortCandidates are located at the relative position of the real source/target node. Inter-edges that connect to such LayoutPortCandidates will be routed when the layout of the containing group node is calculated and will not be rerouted later. This may produce more suitable edge routes but cannot prevent edges from crossing nodes.

Without temporary or user specified LayoutPortCandidates, inter-edges will always end at the border/center of the corresponding group node. Thus, they are rerouted afterwards using an edge routing algorithm.

Predefined LayoutPortCandidates are always satisfied depending on the used layout algorithm, even if this option is disabled.
Adding temporary LayoutPortCandidates will only have an effect if the layout algorithm supports them.
final

Property Value

true if temporary port candidates are inserted

Default Value

The default value is: false
No temporary LayoutPortCandidates are added.

Sample Graphs

ShownSetting: false

See Also

API
routeInterEdges, interEdgeRouter, LayoutPortCandidate
Gets or sets whether empty group nodes are handled like group nodes with content or like normal nodes.
If they are handled like other group nodes, RecursiveGroupLayout will resize them according to their (non-existing) content. This results in small empty group nodes. Handled like normal nodes, empty group nodes will keep their initial size.
final

Property Value

true if empty groups are treated like group nodes, false if they are treated like normal nodes

Default Value

The default value is: false
Empty group nodes are not resized.

Sample Graphs

ShownSetting: Initial graph
Gets or sets the core ILayoutAlgorithm that is wrapped by this stage.
final

Property Value

the core layout routine

Default Value

The default value is: null
Gets or sets a value that determines whether this stage should do anything but execute the coreLayout.

By default, when constructed, stages should be enabled. Users may disable a stage's functionality by setting this property to false.

Stages that can guarantee that the graph will not change can choose to not even execute the coreLayout when disabled.

final
Gets or sets whether or not to consider the initial coordinates of the graph elements.
When using the initial coordinates, RecursiveGroupLayout sets the coordinates of the nodes to their initial position before the corresponding ILayoutAlgorithm is called.
This option should be enabled if RecursiveGroupLayout uses an ILayoutAlgorithm that runs in From Sketch mode.
final

Property Value

true if the initial coordinates of the graph elements are considered, false otherwise

Default Value

The default value is: false
The initial coordinates of the nodes are not taken into account.
Gets or sets a ILayoutGroupBoundsCalculator which computes the sizes of all group nodes.
This ILayoutGroupBoundsCalculator is used each time after calculating the layout for a content graph.
final

Property Value

The current ILayoutGroupBoundsCalculator instance.

Default Value

The default value is: GroupBoundsCalculator
Gets or sets the current edge routing algorithm for handling inter-edges.
During layout, edges that connect from outside a group node to the content inside (inter-edges) are temporarily connected to the group node itself. Hence, these edges have to be routed after restoring the original graph structure using this edge routing algorithm.
final

Property Value

the edge routing algorithm for inter-edges

Default Value

The default value is: null
Edges are routed as straight lines from source to target.

Methods

Implementation of the ILayoutAlgorithm interface and main entry point for the layout calculation.
This implementation checks the enabled state and when it's not enabled, will delegate to the coreLayout, directly. When the stage is enabled, all the work will be delegated to applyLayoutImpl, instead.
final

Parameters

graph: LayoutGraph
The graph to apply the layout to.
Invokes a recursive traversal through the grouping hierarchy of the given graph during which the specified layout algorithms are applied to the content of the groups.
protected

Parameters

graph: LayoutGraph
the input graph
Returns an instance of LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel> that can be used to perform item-specific configurations for the RecursiveGroupLayout.
The generic type arguments of the created layout data are compatible with instances of LayoutGraph, but the layout data is not bound to a specific graph instance. Therefore, the created layout data still has to be passed as an argument of applyLayout in order to be applied.

Parameters

graph: LayoutGraph
the graph that determines the generic type arguments of the created layout data

Return Value

RecursiveGroupLayoutData<LayoutNode, LayoutEdge, LayoutNodeLabel, LayoutEdgeLabel>
an instance of layout data that can be used to perform item-specific configurations for the given RecursiveGroupLayout.
Returns an instance of LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel> that can be used to perform item-specific configurations for the RecursiveGroupLayout.
The generic type arguments of the created layout data are compatible with instances of IGraph, but the layout data is not bound to a specific graph instance. Therefore, the created layout data still has to be passed as an argument of applyLayout in order to be applied.
This method is not available unless the module view-layout-bridge is loaded. Either load the module 'view-layout-bridge' explicitly or ensure that the LayoutExecutor type is available at runtime.

Parameters

graph?: IGraph
the graph that determines the generic type arguments of the created layout data

Return Value

RecursiveGroupLayoutData<INode, IEdge, ILabel, ILabel>
an instance of layout data that can be used to perform item-specific configurations for the given RecursiveGroupLayout.

Constants

A constant that represents a ILayoutAlgorithm implementation that does nothing.
This implementation can be assigned to group nodes to keep their content unchanged. The layout algorithm will still calculate the sizes of the group nodes.
static

See Also

API
groupNodeLayouts
A constant that represents a ILayoutAlgorithm implementation that does nothing.
This implementation can be assigned to group nodes to keep their contents and sizes unchanged. The layout algorithm will not recalculate the sizes of the group nodes, however the group and its content may still be moved as a whole by this stage's coreLayout.
static

See Also

API
groupNodeLayouts
A constant that represents a ILayoutAlgorithm implementation that delegates to the coreLayout.

This implementation can be assigned to group nodes to specify that they should not be handled recursively. In this case, the marked group node handled by this stage's coreLayout as is. The core layout must therefore be able to handle group nodes.

This constant is functionally equivalent to marking a group node with the value null or not marking it at all. It can be used to explicitly specify that the default behaviour is intended.

static

See Also

API
groupNodeLayouts