Layout Stages
Layout algorithms involve arbitrarily complex logic to complete their task. However, many algorithms perform a number of well-defined sub-tasks in a similar manner. yFiles factors out these sub-tasks into layout stages and re-uses them in various contexts.
In addition to these distinct tasks, more complex layout algorithms, full-fledged layout styles, and edge routers are also implemented as layout stages. These layout stages can be combined to realize complex layout processes tailored to your requirements.
The Layout Stage Concept
A layout stage serves as a container that encapsulates layout functionality, providing a way to combine multiple stages into a compound layout process. The ILayoutStage interface defines the basis for a layout stage.
ILayoutStage is a specialization of the ILayoutAlgorithm interface, and therefore can be used as a stand-alone layout provider as well as part of a larger layout process.
When used within a larger layout process, a layout stage can simplify the core layout algorithm’s task. It can perform preprocessing steps on the input graph before the core algorithm is invoked, and/or post-processing steps afterward.
The most common layout stages are:
Stage | Description |
---|---|
Each layout algorithm has different stages activated by default:
PortPlacementStage | GroupHidingStage | ComponentLayout | GenericLabeling | OrientationStage | SelfLoopRouter | ParallelEdgeRouter | TreeReductionStage | |
---|---|---|---|---|---|---|---|---|
With these layout stages, the algorithms are configured well. However, there are further stages that are not part of any layout algorithm’s default pipeline but can still enhance the layout process:
- SubgraphLayoutStage
- Reduces the original graph to the subgraph induced by selected subgraph nodes and/or edges.
- RecursiveGroupLayout
- Applies a specified layout algorithm to the direct children of each group node (recursively).
- LineWrappingStage
- Line-wraps or column-wraps a graph layout to achieve a desired aspect ratio or fixed width or height.
All major layout algorithms have a LayoutStages
property of type LayoutStageStack, which
allows the layout stages to be managed.
Stages can be added, removed, disabled, and modified. For modification, there are convenience properties on the layout
algorithm classes for the most relevant stages.
All other stages can be retrieved using the get<T> method.
All major layout algorithms are implemented with layout stages and can be customized by adding layout stages. For example, this can be used to run edge routing after any major layout.
The following example shows how to add an ILayoutStage to the layout stages of an existing layout algorithm.
const layout = new OrganicLayout()
// prepend the EdgeRouter to the stack such that it wraps all other stages, this means EdgeRouter
// routes the edges as a post-processing after the organic layout
layout.layoutStages.prepend(new EdgeRouter())
graph.applyLayout(layout)
It is also possible to create an LayoutStageStack from scratch, but this is rarely necessary, unless you are implementing a custom layout algorithm.
const stages = new LayoutStageStack()
// add some stages
stages.append(new GenericLabeling({ enabled: false }))
stages.prepend(new GroupHidingStage())
// enable the GenericLabeling stage again
const genericLabeling = stages.get(GenericLabeling)
if (genericLabeling) {
genericLabeling.enabled = true
}
// chain the layout stages together into one layout algorithm
const linkedStages = LayoutStageStack.linkCoreLayouts(stages.stack)
linkedStages.applyLayout(new LayoutGraph())
Layout of Unconnected Components
The ComponentLayout class arranges the connected components of a graph. It invokes its core layout algorithm on each of the input graph’s components and afterward arranges the separate components while keeping the relative layout within each component fixed.
Using ComponentLayout’s services with a given ILayoutAlgorithm implementation as its core layout algorithm has several benefits:
- The core layout algorithm does not need to handle non-connected graphs itself. It can safely assume that its input graph is connected. This often simplifies the formulation of a core algorithm substantially.
- The core layout algorithm does not need to arrange the separate components of an input graph, since this is done by ComponentLayout.
- Customization of the layout strategy used for arranging separate components can conveniently be done by tailoring, or even exchanging, the ComponentLayout. All core algorithms can take advantage of this customization immediately.
- ComponentLayout objects can be used in conjunction with arbitrary core layout algorithms, since the services provided by ComponentLayout are highly reusable.
The class ComponentLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel> provides a number of properties to specify supplemental layout data for the graph elements:
Property | Element Type | Value Type | Description |
---|---|---|---|
The ComponentLayout class provides a set of options that affect its behavior.
- Component Arrangement Style
- style
- Specifies the style for arranging the components of a graph.
- Component Spacing
- componentSpacing
- Defines the minimum distance between the bounding boxes of adjacent components.
- Grid Spacing
- gridSpacing
- Defines the spacing of the grid on which the separate components are placed.
- Label Awareness
- nodeLabelPlacement
- edgeLabelPlacement
- Determines whether labels are taken into account when computing the bounding boxes of components.
- Support for Grouped Graphs
- considerGrouping
- Specifies whether the grouped graph’s hierarchy of nodes is taken into account when determining its components.
Wrapping Wide or High Layouts
The LineWrappingStage is a layout stage that can be used to line-wrap or column-wrap a graph layout. Line-wrapping arranges the graph into horizontal lines, while column-wrapping arranges it into vertical columns. It allows you to specify a desired aspect ratio for the wrapped layout or a fixed width (height) for the lines (columns).
The LineWrappingStage is most commonly used with hierarchical layouts. Hierarchical layout before and after line-wrapping shows a hierarchical layout that has been line-wrapped to achieve a desired aspect ratio.


Using LineWrappingStage with hierarchical layout shows how the LineWrappingStage class can be used to wrap hierarchical top-to-bottom layouts.
graph.applyLayout(
new LineWrappingStage({
columnMode: true,
mirror: false,
coreLayout: new HierarchicalLayout()
})
)
LineWrappingStage provides a set of options that influence its behavior.
- Column Mode
- columnMode
- Specifies whether the graph layout should be column-wrapped instead of line-wrapped. If enabled, the layout will be arranged in columns. Otherwise, it will be arranged in lines.
- Spacing
- spacing
- Defines the spacing between adjacent lines (columns) in the line-wrapped (column-wrapped) graph layout.
- Edge Spacing
- edgeSpacing
- Defines the spacing between adjacent edge paths that connect consecutive lines (columns) in the line-wrapped (column-wrapped) graph layout.
- Mirroring
- mirror
- Specifies whether the lines (columns) of the line-wrapped (column-wrapped) graph layout should be arranged in an alternating (mirrored) manner. Every second line (column) goes from right to left (bottom to top) instead of left to right (top to bottom).
- Pre-set vs. Automatic Line Width (Column Height)
- fixedWidthLineBreaks
- Specifies whether the lines (columns) of the line-wrapped (column-wrapped) graph layout should use a pre-set width (height) defined by fixedWidth. If enabled, the layout will use the fixed width/height. Otherwise, the width/height is automatically determined to reach the target aspect ratio.
- Fixed Line Width (Column Height)
- fixedWidth
- Defines the width (height) that should be used for the lines (columns) of the line-wrapped (column-wrapped) graph layout. This setting only has an effect if pre-set line width (column height) is enabled through fixedWidthLineBreaks.
- Aspect Ratio
- targetRatio
- Defines the desired aspect ratio for the line-wrapped (column-wrapped) graph layout. This setting only has an effect if automatic line width (column height) is enabled.
Alignment Stage
The class AlignmentStage is a layout stage that automatically aligns nodes on vertical and horizontal lines. The stage minimizes the number of lines used, while ensuring that the nodes' position changes are limited.
The algorithm operates in two phases. In the first phase, the nodes are partitioned into disjoint sets for both the x-dimension and the y-dimension. During this phase, the nodes are aligned to lines whose positions are not yet defined. In the second phase, the positions of these lines, and consequently the positions of their assigned nodes, are determined. The positions are chosen to minimize the overall movement of the nodes.
The stage is intended to be used as a post-processing step on graphs that are already well-arranged. Although the stage can resolve node overlaps, it is recommended to use it on graph layouts without node overlaps. If necessary, another stage that resolves node overlaps can be applied before this stage (e.g., RemoveOverlapsStage).
![]() | ![]() |
Basic Properties
- Alignment Policy
- alignmentPolicy
- The AlignmentStage allows you to specify the direction in which the nodes are snapped. Choosing the x-direction means that the nodes are snapped to vertical grid lines, while choosing the y-direction means that the nodes are snapped to horizontal grid lines. If both axes are chosen, the snapping is done sequentially for the two orientations. See Table Example for the choice of the alignment policy. for an example.
![]() | ![]() |
![]() | ![]() |
- Snap Distance
- snapDistance
- The snap distance describes the maximum distance between two nodes that can be snapped to the same line. That is, two nodes are aligned on the same line only if the distance between their centers does not exceed the given snap distance in the respective dimension. Therefore, large snap distances produce a more pronounced grid structure but deviate more from the initial layout than small snap distances.
- Separate Alignments
- separateStripes
- If this property is enabled, the nodes are placed in strictly separated rows and columns. That is, nodes aligned on consecutive lines are geometrically separated by lines. Table Example for separated alignments. (right column) shows an example with separated stripes. The nodes assigned to consecutive horizontal lines are separated by a horizontal line, where the nodes of one grid line are above that horizontal line, and nodes of the other are below. Similarly, the nodes assigned to consecutive vertical grid lines are separated by a vertical line. This gives the visual impression that the nodes are placed in disjoint rows and columns. While enabling this property visually separates nodes, it may reduce the compactness of the layout substantially.
![]() | ![]() |
- Grid Spacing
- gridSpacing
- You can place the generated alignments at regular intervals to produce a grid-like appearance. If this property is set to a value greater than zero, the distance between any two parallel alignment axes is set to a multiple of that value.
![]() | ![]() |
- Snap Offset
- snapOffsets
- By default, the nodes are aligned with their centers on common lines. However, depending on the use case, you might want to align other points of the nodes, for example, their top-left corners. To that end, the snap point of a node can be customized through a snap offset. The snap offset is relative to the node’s center and defines a snap point in the interior or on the boundary of a node. If the snap point lies outside of the node, the point is mapped onto the boundary of the node. You can specify the snap offset for each node using the supplemental data that can be conveniently defined via class AlignmentStageData<TNode,TEdge,TNodeLabel,TEdgeLabel>.
Grouped Graphs
The alignment stage can also be applied to grouped graphs. In this case, the alignment stage will be performed on all nodes that are not group nodes or that do not have any children. The alignment of these nodes will conform to the Basic Properties. Group nodes that contain child nodes are not aligned. However, it is ensured that they can be drawn without overlaps.
![]() | ![]() |
Layout Data
Supplemental layout data for a graph’s items can be specified via the AlignmentStageData<TNode,TEdge,TNodeLabel,TEdgeLabel> class. This data can be created using the createLayoutData factory method. Table Supplemental layout data lists the properties of the layout data.
Providing supplemental layout data is described in detail in Layout Data.
Supplemental layout data
layoutGridData - Specifies a LayoutGrid for the alignment stage to consider.