Specifies custom data for the HierarchicLayout.
Default Values of Properties
Examples
The following example shows how to create a new instance of HierarchicLayoutData and use it with an HierarchicLayout:
In many cases the complete initialization of HierarchicLayoutData can also be done in a single object initializer:
Type Details
- yfiles module
- view-layout-bridge
- yfiles-umd modules
- view-layout-bridge
- Legacy UMD name
- yfiles.hierarchic.HierarchicLayoutData
See Also
Constructors
Creates a new instance of HierarchicLayoutData which helps configuring HierarchicLayout.
Parameters
A map of options to pass to the method.
- alternativeEdgePaths - ItemMapping<IEdge,IEnumerable<IPoint>>
A mapping from edges to alternative paths for edges connecting to groups, group content or folder nodes. This option sets the alternativeEdgePaths property on the created object.
- alternativeGroupBounds - ItemMapping<INode,IRectangle>
A mapping from group/folder nodes to alternative bounds for these nodes. This option sets the alternativeGroupBounds property on the created object.
- criticalEdgePriorities - ItemMapping<IEdge,number>
A mapping from edges to their priority to be a 'critical' edge. This option sets the criticalEdgePriorities property on the created object.
- reduceCriticalEdgeCrossings - boolean
Whether or not critical edges automatically get crossing costs assigned based on their critical edge priorities. This option sets the reduceCriticalEdgeCrossings property on the created object.
- folderNodes - ItemCollection<INode>
The collection of folder nodes used for recursive edge styles in incremental mode. This option sets the folderNodes property on the created object.
- edgeLayoutDescriptors - ItemMapping<IEdge,HierarchicLayoutEdgeLayoutDescriptor>
The mapping of edges to their HierarchicLayoutEdgeLayoutDescriptor. This option sets the edgeLayoutDescriptors property on the created object.
- nodeLayoutDescriptors - ItemMapping<INode,HierarchicLayoutNodeLayoutDescriptor>
The mapping of nodes to their HierarchicLayoutNodeLayoutDescriptor This option sets the nodeLayoutDescriptors property on the created object.
- nodeHalos - ItemMapping<INode,NodeHalo>
- nodeTypes - ItemMapping<INode,Object>
The mapping from nodes to an object defining the node type, which influences the ordering of nodes during the sequencing such that nodes of same type are preferably placed next to each other. This option sets the nodeTypes property on the created object.
- subcomponents - ItemCollectionMapping<INode,HierarchicLayoutSubcomponentDescriptor>
The mapping of nodes to a subcomponent which is arranged by the layout algorithm defined by property layoutAlgorithm. This option sets the subcomponents property on the created object.
- sourcePortConstraints - ItemMapping<IEdge,PortConstraint>
A mapping from edges to their source PortConstraint. This option sets the sourcePortConstraints property on the created object.
- targetPortConstraints - ItemMapping<IEdge,PortConstraint>
A mapping from edges to their target PortConstraint. This option sets the targetPortConstraints property on the created object.
- sourcePortCandidates - ItemMapping<IEdge,ICollection<PortCandidate>>
A mapping from edges to a collection of their source port candidates. This option sets the sourcePortCandidates property on the created object.
- targetPortCandidates - ItemMapping<IEdge,ICollection<PortCandidate>>
A mapping from edges to a collection of their target port candidates. This option sets the targetPortCandidates property on the created object.
- nodePortCandidateSets - ItemMapping<INode,PortCandidateSet>
A mapping from nodes to their PortCandidateSet. This option sets the nodePortCandidateSets property on the created object.
- sourceGroupIds - ItemMapping<IEdge,Object>
A mapping from edges to an object representing their source edge group. This option sets the sourceGroupIds property on the created object.
- sourcePortGroupIds - ItemMapping<IEdge,Object>
A mapping from edges to an object representing their source port group. This option sets the sourcePortGroupIds property on the created object.
- targetGroupIds - ItemMapping<IEdge,Object>
A mapping from edges to an object representing their target edge group. This option sets the targetGroupIds property on the created object.
- targetPortGroupIds - ItemMapping<IEdge,Object>
A mapping from edges to an object representing their target port group. This option sets the targetPortGroupIds property on the created object.
- buses - ItemCollectionMapping<IEdge,HierarchicLayoutBusDescriptor>
The mapping from edges to their bus descriptor which defines the bus structure they belong to. This option sets the buses property on the created object.
- busRootOffsets - ItemMapping<INode,number>
The mapping from nodes to their layer index relative to the root node of the bus they belong to. This option sets the busRootOffsets property on the created object.
- nodesBeforeBus - ItemCollection<INode>
The collection of bus nodes that should be placed before the common bus segment. This option sets the nodesBeforeBus property on the created object.
- layerConstraints - LayerConstraintData
The layout data to specify layer constraints. This option sets the layerConstraints property on the created object.
- sequenceConstraints - SequenceConstraintData
The layout data to specify sequence constraints. This option sets the sequenceConstraints property on the created object.
- layerConstraintFactory - ILayerConstraintFactory
The factory to specify layer constraints. This option sets the layerConstraintFactory property on the created object.
- sequenceConstraintFactory - ISequenceConstraintFactory
The factory to specify sequence constraints. This option sets the sequenceConstraintFactory property on the created object.
- incrementalHints - IncrementalHintItemMapping
A mapping from nodes and edges to their incremental hints. This option sets the incrementalHints property on the created object.
- layerIndices - IMapper<INode,number>
A mapper from nodes to the index of their layer. This option sets the layerIndices property on the created object.
- sequenceIndices - IMapper<INode,number>
A mapper from nodes to the sequence index in their layer. This option sets the sequenceIndices property on the created object.
- abortHandler - AbortHandler
The AbortHandler used during the layout. This option sets the abortHandler property on the created object.
- partitionGridData - PartitionGridData
The partition grid layout data. This option sets the partitionGridData property on the created object.
- selfLoopCalculatorData - SelfLoopCalculatorData
The layout data for the SelfLoopCalculator. This option sets the selfLoopCalculatorData property on the created object.
- constraintIncrementalLayererAdditionalEdgeWeights - ItemMapping<IEdge,number>
The mapping from edges to an additional weight used by the ConstraintIncrementalLayerer. This option sets the constraintIncrementalLayererAdditionalEdgeWeights property on the created object.
- bfsLayererCoreNodes - ItemCollection<INode>
The collection of core nodes used by the BFSLayerer. This option sets the bfsLayererCoreNodes property on the created object.
- givenLayersLayererIds - ItemMapping<INode,number>
The mapping from nodes to their layer index when using the GivenLayersLayerer. This option sets the givenLayersLayererIds property on the created object.
- edgeDirectedness - ItemMapping<IEdge,number>
The mapping from edges to their directedness. This option sets the edgeDirectedness property on the created object.
- edgeThickness - ItemMapping<IEdge,number>
The mapping from edges to their thickness. This option sets the edgeThickness property on the created object.
- edgeCrossingCosts - ItemMapping<IEdge,number>
The mapping from edges to their crossing cost. This option sets the edgeCrossingCosts property on the created object.
- groupBorderCrossingCosts - ItemMapping<INode,number>
The mapping from group nodes to the costs for a crossing with the group node border. This option sets the groupBorderCrossingCosts property on the created object.
- edgeLabelPreferredPlacement - ItemMapping<ILabel,PreferredPlacementDescriptor>
The mapping that provides a PreferredPlacementDescriptor instance for edge ILabels. This option sets the edgeLabelPreferredPlacement property on the created object.
- uniformPortAssignmentGroups - ItemCollection<INode>
The collection of group nodes for which the ports of the adjacent edges are uniformly distributed. This option sets the uniformPortAssignmentGroups property on the created object.
- tabularGroups - ItemCollection<INode>
The collection of tabular group nodes whose children are arranged in a tabular fashion. This option sets the tabularGroups property on the created object.
- tabularGroupChildComparers - ItemMapping<INode,system.Comparison<INode>>
The mapping from tabular group nodes to comparison functions used to sort the child nodes of the group. This option sets the tabularGroupChildComparers property on the created object.
Properties
Gets or sets the AbortHandler used during the layout.
Remarks
An AbortHandler can be used to gracefully stop or cancel a running layout and offers options for automatically doing so after a predetermined time.
An AbortHandler configured or set here overrides the one on LayoutExecutor.
Examples
The most common use case would be to just configure the AbortHandler here, e.g. to set timeouts for a graceful stop or canceling the running layout:
layoutData.abortHandler.stopDuration = TimeSpan.fromSeconds(10) layoutData.abortHandler.cancelDuration = TimeSpan.fromSeconds(30)
layoutData.abortHandler!.stopDuration = TimeSpan.fromSeconds(10) layoutData.abortHandler!.cancelDuration = TimeSpan.fromSeconds(30)
If there's already an AbortHandler instance that's pre-configured or will be used in a different place to, e.g., cancel the layout when the user presses a button, you can also set one explicitly:
layoutData.abortHandler = abortHandler
See Also
Gets or sets a mapping from edges to alternative paths for edges connecting to groups, group content or folder nodes.
Remarks
When running in incremental layout mode, the alternative edge paths are considered during the routing of fixed (i.e., non-incremental) edges.
The alternative paths should be used in conjunction with alternative group bounds to achieve more stable layout results when collapsing/expanding a group node as follows:
- Collapsing: edges adjacent to the group itself and edges where one of the endpoints (source/target) lies inside the group should get the path before collapsing the group as alternative path. If both endpoints are either inside or outside the group, no alternative path is required.
- Expanding: edges adjacent to the expanded folder node (which is now a group) should get the path before expanding as alternative path.
See Also
Gets or sets a mapping from group/folder nodes to alternative bounds for these nodes.
Remarks
See Also
Gets or sets the collection of core nodes used by the BFSLayerer.
Remarks
The core nodes will be placed in the first layer. If there are no core nodes, then nodes with in-degree 0
are considered to be the core nodes.
The BFSLayerer is used when fromScratchLayeringStrategy is set to BFS.
See Also
Gets or sets the mapping from edges to their bus descriptor which defines the bus structure they belong to.
Remarks
All edges with the same HierarchicLayoutBusDescriptor adjacent to a specific node (the root) and having the same direction are arranged in a compact, bus-like way. The edgeDirectedness is also considered here. The direction defines the placement of the bus structure in the following way:
- Bus nodes connected by out-edges are placed in the layers starting with the layer that comes directly after the layer of the root (e.g. below the root for top-to-bottom layout orientation).
- Bus nodes connected by in-edges are placed in the layers ending with the layer that comes directly before the layer of the root (e.g. above the root for top-to-bottom layout orientation).
The bus substructures are arranged using a style that yields more compact layout results. Edges to the child nodes, the so-called bus nodes, are routed using a shared segment that connects to the common root node. The bus nodes are arranged using several layers above or below the root node such that the whole substructure has a compact area. By default, each bus layer contains equally many bus nodes, bus nodes of adjacent layers are center-aligned and the shared bus segment is routed in the middle of the nodes. This produces compact, symmetric arrangements of the bus structures.
The arrangement can be customized for each bus individually, by using the settings offered by HierarchicLayoutBusDescriptor. It allows to configure the number of bus nodes before and after the common bus segment.
There apply some restrictions for bus structures:
- Only nodes that are in the same partition grid cell or same swimlane as the root node are included in the bus structure.
- The bus nodes must all belong to the same group node. Also, a group node can not be part of a bus structure; neither as bus element nor as root.
- Bus structures can not be nested. That means that if a node is a bus node it can not be a root node of another bus at the same time.
- For bus edges, the integrated edge labeling feature does not place port labels as close to the actual port as it does for other edges (see AT_SOURCE_PORT and AT_TARGET_PORT).
- Edge grouping constraints at the side of the bus root node are ignored for bus edges; the grouping induced by the bus structure is considered to be stronger.
- If in incremental layout mode, the bus edges are always treated in an incremental way such that the bus-style routing remains consistent (e.g. if a fixed bus edge contains bends that suggest another route, they are ignored). The reason is that the bus-style layout of the structures has higher priority. Furthermore, the location of the bus segment relative to the elements is not derived from the sketch but depends on the settings maximumNodesBeforeBus and maximumNodesAfterBus as well as the before/after constraints defined by nodesBeforeBus. This means that it can happen that a fixed bus node which was placed before the bus in the input drawing may be placed after the bus if the bus was enlarged due to the insertion of incremental bus nodes.
- It is not recommended to define buses inside a group node which has an incremental group hint. Fixed bus nodes inside such a group are not necessarily kept fix but are treated like an incrementally inserted node.
Examples
Buses can be configured by first adding a new HierarchicLayoutBusDescriptor and saving the resulting ItemCollection<TItem>. That one can then be used to define the structure of the bus:
// Retrieve an ItemCollection<IEdge> which defines all edges
// of a bus. This bus will be arranged according to the HierarchicLayoutBusDescriptor
const bus = layoutData.buses.add(new HierarchicLayoutBusDescriptor())
// You can use this ItemCollection<IEdge> as usual, using either one of
// the Source, Items, Mapper, or Delegate properties.
// Here, we simply use the selected edges:
bus.source = graphComponent.selection.selectedEdges
Since adding a new HierarchicLayoutBusDescriptor for a bus returns the ItemCollection<TItem>, configuring buses can also be conveniently chained:
// bus1Edges, bus2Edges, bus3Edges are of type IEnumerable.<IEdge>
layoutData.buses.add(new HierarchicLayoutBusDescriptor()).source = bus1Edges
layoutData.buses.add(new HierarchicLayoutBusDescriptor()).source = bus2Edges
layoutData.buses.add(new HierarchicLayoutBusDescriptor()).source = bus3Edges
See Also
Sample Graphs
Gets or sets the mapping from nodes to their layer index relative to the root node of the bus they belong to.
Remarks
i
specified for a bus node is interpreted relative to the root node as follows, assuming that the root node is in layer x
.- If the bus is placed in the layers after the root, the bus node will be placed in layer
x + i
- If the bus is placed in the layers before the root, the bus node will be placed in layer
x - i
Examples
When the layer offsets can be readily inferred from the nodes, then the easiest option is usually to use the delegate:
layoutData.busRootOffsets = (node) => node.tag.offset
layoutData.busRootOffsets = (node: INode): number => node.tag.offset
In case only some nodes need to be mapped to their layer respective offset, it's sometimes easier to use the mapper:
layoutData.busRootOffsets.mapper.set(node1, 0)
layoutData.busRootOffsets.mapper.set(node2, 1)
See Also
Gets or sets the mapping from edges to an additional weight used by the ConstraintIncrementalLayerer.
Remarks
See Also
Gets or sets a mapping from edges to their priority to be a 'critical' edge.
Remarks
The layout tries to vertically align each node pair that is connected by a critical edge. Critical edges are marked by having a priority greater than 0
; edges with a zero or negative priority are not considered critical.
Critical edges highlight different edge paths that are relevant for a user. The layout algorithm tries to vertically align each node pair that is connected by a critical edge. Conflicts between different critical edges are always resolved in favor of the higher priority.
Examples
Critical edges are often determined by some external data source and are often part of a larger path. The following example shows how two different such paths can be made 'critical' with different priorities:
Alternatively, a delegate may be used as well, if determining edge criticality is easier when looking at the edge itself:
See Also
Sample Graphs
Gets or sets the mapping from edges to their crossing cost.
Remarks
1
, which is used for edges which do not have an individual crossing cost.Examples
See Also
Gets or sets the mapping from edges to their directedness.
Remarks
1
means that the edge should fully comply, a value of -1
that it should comply inversely (the edge should point against the main layout direction), and a value of 0
means that the direction doesn't matter at all and the endpoints of the edges may be placed at the same layer. If there are conflicting preferences, edges with higher absolute values are more likely to point in the desired direction.Examples
The easiest option is to define all edges with the same directedness:
Handling only certain edges differently can be done easily by using the mapper property:
In cases where the directedness for each edge can be determined by looking at the edge itself it's often easier to just set a delegate instead of preparing a mapper:
See Also
Gets or sets the mapping that provides a PreferredPlacementDescriptor instance for edge ILabels.
Examples
Depending on how much customization is needed, some ways of setting PreferredPlacementDescriptors are more convenient than others. For example, to set the same descriptor for all labels, you can just use the constant property:
If some labels should use custom placement or this has to be configured ahead of time, you can use the mapper instead:
When the preferred placement can be inferred from the label itself, a delegate is usually the easiest choice:
Note that the preferred placement can also be inferred from an arbitrary ILabelModelParameter:
See Also
Gets or sets the mapping of edges to their HierarchicLayoutEdgeLayoutDescriptor.
Remarks
null
, the default descriptor is used.Examples
This property allows to change how edges are routed for each edge individually. To just change a few edges that deviate from the default style, using the mapper is probably the best option:
If an HierarchicLayoutEdgeLayoutDescriptor is easier to create from every edge itself, using a delegate is often easier:
See Also
Gets or sets the mapping from edges to their thickness.
Remarks
0
.Examples
The easiest option is to define the same thickness for all edges:
Handling only certain edges differently can be done easily by using the mapper property:
In cases where the thickness for each edge can be determined by looking at the edge itself it's often easier to just set a delegate instead of preparing a mapper:
See Also
Sample Graphs
Gets or sets the collection of folder nodes used for recursive edge styles in incremental mode.
Remarks
Examples
Using the folderNodes property is probably easiest with a delegate that checks for each node whether it's a folder node or not:
However, the other options are also still there, such as using an IEnumerable<T> via source:
or explicitly using the items collection to add or remove items, perhaps based on the user collapsing/expanding group nodes:
See Also
Gets or set the mapping from nodes to their layer index when using the GivenLayersLayerer.
Remarks
Nodes with the same layer index are in the same layer while the layers are sorted according to their layer indices such that the smallest layer index represents the top layer.
The GivenLayersLayerer is used when fromScratchLayeringStrategy is set to USER_DEFINED.
See Also
Gets or sets the mapping from group nodes to the costs for a crossing with the group node border.
Remarks
5
. This means that by default, a crossing between an edge and a group node border is more expensive than a crossing between two edges. Also note that a crossing with a group node border that has a cost of zero is cost-free and such a crossing will therefore not be avoided.Examples
See Also
Gets or sets a mapping from nodes and edges to their incremental hints.
Remarks
Examples
Elements which should be placed incrementally can be provided as collections:
More specific hints can be created using an IIncrementalHintsFactory:
See Also
Gets or sets the factory to specify layer constraints.
Remarks
See Also
Deprecation warning
Use LayerConstraints insteadGets or sets the layout data to specify layer constraints.
Remarks
Layer constraints affect the assignment of nodes to layers. A layer constraint can be specified either explicitly for a given node or by mapping some or all nodes to an IComparable, e.g., a number, with the nodeComparables property.
In the latter case, the comparables are used to create placeBelow constraints between one node and another, if the one precedes the other. These constrains work just like explicitly created constraints. Note that equal values do not result in placeInSameLayer constraints, and no constraints are added for nodes mapped to null
..
Examples
One way to map each node to an IComparable is to use the delegate:
If only some nodes should be constrained, the mapper can be used instead:
If those mappings have been prepared beforehand, e.g. in a HashMap<TKey,TValue> or IMapper<K,V>, that property on the ItemMapping<TItem,TValue> can also be set:
IComparable is only the most natural option if such an object can be readily produced from a node, or there already exists such a mapping from nodes to something that can be compared. In many cases it can be easier to construct constraints manually with the respective methods on LayerConstraintData:
See Also
Sample Graphs
Gets or sets a mapper from nodes to the index of their layer.
Remarks
true
. This will skip the remaining stages of the layout and therefore reduce the runtime.Examples
See Also
Gets or sets the mapping from nodes to their NodeHalo.
Remarks
Examples
The easiest option is to reserve the same space around all nodes, by setting a constant NodeHalo:
Handling only certain nodes differently can be done easily by using the mapper property:
In cases where the NodeHalo for each node can be determined by looking at the node itself it's often easier to just set a delegate instead of preparing a mapper:
See Also
Gets or sets the mapping of nodes to their HierarchicLayoutNodeLayoutDescriptor
Remarks
null
, the default descriptor is used.Examples
This property allows to change how nodes are laid out within their layer for each node individually. To just change a few nodes that deviate from the default handling, using the mapper is probably the best option:
If a HierarchicLayoutNodeLayoutDescriptor is easier to create from every node itself, using a delegate is often easier:
See Also
Gets or sets a mapping from nodes to their PortCandidateSet.
Remarks
Examples
The simplest way to define node port candidate sets is to use the same PortCandidateSet for all nodes, if suitable for the use case:
The same effect can be achieved with a delegate as well, however, a more useful way to use a delegate would be to decide whether a node should get a port candidate set based on some data at the node, e.g., found in its tag:
If specific nodes should get a certain PortCandidateSet, it may sometimes be easier to use the mapper to set them:
See Also
Gets or sets the collection of bus nodes that should be placed before the common bus segment.
Remarks
Examples
When the placement can be readily inferred from the nodes, then the easiest option is usually to use the delegate:
layoutData.nodesBeforeBus = (node) =>
graphComponent.selection.selectedNodes.isSelected(node)
However, the other options are also still there, such as using an IEnumerable<T> via source:
layoutData.folderNodes = graphComponent.selection.selectedNodes
or explicitly using the items collection to add or remove items:
layoutData.nodesBeforeBus.items.add(node1)
layoutData.nodesBeforeBus.items.add(node2)
See Also
Gets or sets the mapping from nodes to an object defining the node type, which influences the ordering of nodes during the sequencing such that nodes of same type are preferably placed next to each other.
Remarks
See Also
Sample Graphs
Gets or sets the partition grid layout data.
Examples
The following sample shows how to assign nodes to partition grid cells simply via cell indices:
When used this way there is no need to create a PartitionGrid instance or work with it directly. For more flexibility, e.g. to use cells that span multiple columns or rows, the PartitionGrid can be used as well:
See Also
Gets or sets whether or not critical edges automatically get crossing costs assigned based on their critical edge priorities.
Remarks
1
as the crossing cost (which is the default for it). If disabled, the critical edge priorities do not automatically affect the crossing minimization. The user can still provide higher crossing costs manually, of course.Default Value
true
.Critical edges automatically get crossing costs based on their priorities
See Also
Gets or sets the layout data for the SelfLoopCalculator.
See Also
Gets or sets the factory to specify sequence constraints.
Remarks
See Also
Deprecation warning
Use SequenceConstraints insteadGets or sets the layout data to specify sequence constraints.
Examples
One way to set sequence constraints is by mapping nodes or edges to an IComparable (e.g. a number) which define the order in which those nodes are placed within the same layer. This can be done with the itemComparables property. One way to map each item to such an IComparable is to use the delegate:
If only some nodes should be constrained, the mapper can be used instead:
If those mappings have been prepared beforehand, e.g. in a HashMap<TKey,TValue> or IMapper<K,V>, that property on the ItemMapping<TItem,TValue> can also be set:
IComparable is only the most natural option if such an object can be readily produced from a node, or there already exists such a mapping from nodes to something that can be compared. In many cases it can be easier to construct constraints manually with the respective methods on SequenceConstraintData:
See Also
Sample Graphs
Gets or sets a mapper from nodes to the sequence index in their layer.
Remarks
true
. This will skip the remaining stages of the layout and therefore reduce the runtime.Examples
See Also
Gets or sets a mapping from edges to an object representing their source edge group.
Remarks
Edges sharing a source group identifier will share a common bus near the source or at a common source node if possible.
The HierarchicLayout is able to group incoming and outgoing edges. Therefore, the source group identifier of the outgoing edges of a node has to match with the target group identifier of the incoming edges.
Examples
One simple way to use source groups is to use the edge's source node as group ID which effectively groups all edges with the same source together:
Another useful way to use a delegate here would be grouping edges by some commonality, such as the same color:
If only certain edges should be grouped it may sometimes be easier to use the mapper to set the group IDs:
See Also
Gets or sets a mapping from edges to a collection of their source port candidates.
Remarks
Port constraints allow to define where an edge can connect to its source node and allow fine control over port placement.
If all that is needed is to fix the source port in its location or on a node side, port constraints are easier to work with, since they are a slightly simpler concept.
The HierarchicLayout does not support PortCandidates with multiple directions (e.g. EAST or WEST). To model that an edge should connect at one of several sides, define multiple candidates instead, where each candidate has a single direction.
Examples
Source port candidates are effectively a collection of possible port placements with different costs and the layout algorithm is free to choose the candidate that fits best into the overall layout, while also preferring candidates with a lower cost. To set the same candidate list for all edges, it's easiest to use the constant property:
If certain edges need specific port candidates, it's usually convenient to use the mapper property:
For cases when the desired configuration of port candidates can be readily created from the edge itself, the delegate is often the most convenient option:
See Also
Sample Graphs
Gets or sets a mapping from edges to their source PortConstraint.
Remarks
Port constraints allow to define where an edge attaches to its source node and can either restrict that to one of the node's sides, or to a fixed port position.
A more general concept which allows finer control over where ports are placed, are port candidates.
Examples
If all edges should exit their source node on the same side, you can simply set a constant constraint for all edges:
To change the constraints for individual edges, it's usually easiest to use the mapper:
If a PortConstraint can readily be created from an edge, using a delegate is often easier:
See Also
Sample Graphs
Gets or sets a mapping from edges to an object representing their source port group.
Remarks
Examples
The simplest way to use source port groups is to use the same object as group ID for all edges. Since grouping is done per node, this has the effect of grouping all edges with the same source node together:
The same effect can be achieved with a delegate as well, by returning the source node as group ID for each edge. However, a more useful way to use a delegate here would be grouping edges by some commonality, such as the same color:
If only certain edges should be grouped it may sometimes be easier to use the mapper to set the group IDs:
See Also
Gets or sets the mapping of nodes to a subcomponent which is arranged by the layout algorithm defined by property layoutAlgorithm.
Remarks
The nodes forming a subcomponent are arranged by another layout algorithm and that sub-layout is finally embedded into the global hierarchical layout. This feature allows, for example, to highlight special sub-structures by arranging them in a different fashion. Note that subcomponents may not be nested, that is, a subcomponent is not allowed to contain nodes that belong to yet another subcomponent. Nesting of subcomponents results in an exception.
To conveniently define a subcomponent as well as the layout algorithm responsible for it use the add method of this property. It takes the HierarchicLayoutSubcomponentDescriptor as parameter and allows to define the nodes associated to it using the returned ItemCollection<TItem>.
A subcomponent can be connected to nodes of another subcomponent as well as to nodes that are not part of any subcomponent. Edges that model these connections are so-called inter-edges. For inter-edges there apply some smaller restrictions with respect to the supported features (see the documentation of SUBCOMPONENT_DESCRIPTOR_DP_KEY for details).
If all inter-edges of a subcomponent connect to the same external node, that single external so-called connector node is included in the calculation of the component layout when using placement policy AUTOMATIC or ALWAYS_INTEGRATED. In case the result is feasible, this results in a better and more compact integration of the component in the main layout. In that case the sub-layout is fully responsible for the routing of inter-edges (meaning the restrictions below may not apply anymore).
Subcomponents can be defined on grouped graphs with the following restrictions:
- All subcomponent nodes must be on the same hierarchy level if the group node itself is not part of the subcomponent.
- If a group is assigned to a subcomponent, all its descendants (including other group nodes) must be in that component, too.
When running in incremental mode, it is still up to the sub-layout algorithm to decide whether to treat a subcomponent element as incremental or fixed. If the given layout of the subcomponent should be considered, then the from-sketch mode of the used layout algorithm needs to be enabled (if such a mode is supported).
Examples
Subcomponents can be configured by first adding a new HierarchicLayoutSubcomponentDescriptor and saving the resulting ItemCollection<TItem>. That one can then be used to define the subset of nodes which the layout should process:
// Retrieve an ItemCollection<INode> which defines all nodes
// of a subcomponent. This subcomponent will be arranged by an OrganicLayout
const organicSubset = layoutData.subcomponents.add(
new HierarchicLayoutSubcomponentDescriptor(new OrganicLayout())
)
// You can use this ItemCollection<INode> as usual, using either one of
// the Source, Items, Mapper, or Delegate properties.
// Here, we simply use the selected nodes:
organicSubset.source = graphComponent.selection.selectedNodes
Since adding a new subcomponent returns the ItemCollection<TItem>, configuring subcomponents can also be conveniently chained:
layoutData.subcomponents.add(
new HierarchicLayoutSubcomponentDescriptor(
new OrganicLayout(),
HierarchicLayoutSubcomponentPlacementPolicy.ISOLATED
)
).source = organicNodes
layoutData.subcomponents.add(
new HierarchicLayoutSubcomponentDescriptor(new TreeLayout())
).source = treeNodes
layoutData.subcomponents.add(
new HierarchicLayoutSubcomponentDescriptor(new OrthogonalLayout())
).source = orthogonalNodes
See Also
Gets or sets the mapping from tabular group nodes to comparison functions used to sort the child nodes of the group.
Remarks
Examples
See Also
Gets or sets the collection of tabular group nodes whose children are arranged in a tabular fashion.
Remarks
Children of tabular groups are laid out in a compact tabular fashion as shown in the figure below. Groups contained in a tabular group behave like tabular groups as well.
Child nodes are placed next to each other within the same layer with a distance defined by tabularGroupChildDistance, which is zero by default.
There are some setups for which a tabular group may not be tight (i.e., maximally compact):
- If edges directly connect to a tabular group (not to its content), then it is not guaranteed that the group becomes maximally compact. Children may be placed a little further apart to fulfill the defined edge-to-edge distance.
- The same is true if there are children with self-loops. Such self-loops are always drawn within the tabular group.
- In addition, labels of edges connecting two children of the same tabular group may intersect with other edge segments.
Besides, the table groups may not be tight if there are user specified constraints like node halos, node labels that exceed the size of the associated child node, and port constraints connecting to a side orthogonal to the layout orientation.
Examples
See Also
Sample Graphs
Gets or sets a mapping from edges to an object representing their target edge group.
Remarks
Edges sharing a target group identifier will share a common bus near the target or at a common target node if possible.
The HierarchicLayout is able to group incoming and outgoing edges. Therefore, the target group identifier of the incoming edges of a node has to match with the source group identifier of the outgoing edges.
Examples
One simple way to use source groups is to use the edge's target node as group ID which effectively groups all edges with the same target together:
Another useful way to use a delegate here would be grouping edges by some commonality, such as the same color:
If only certain edges should be grouped it may sometimes be easier to use the mapper to set the group IDs:
See Also
Gets or sets a mapping from edges to a collection of their target port candidates.
Remarks
Port constraints allow to define where an edge can connect to its target node and allow fine control over port placement.
If all that is needed is to fix the target port in its location or on a node side, port constraints are easier to work with, since they are a slightly simpler concept.
The HierarchicLayout does not support PortCandidates with multiple directions (e.g. EAST or WEST). To model that an edge should connect at one of several sides, define multiple candidates instead, where each candidate has a single direction.
Examples
Target port candidates are effectively a collection of possible port placements with different costs and the layout algorithm is free to choose the candidate that fits best into the overall layout, while also preferring candidates with a lower cost. To set the same candidate list for all edges, it's easiest to use the constant property:
If certain edges need specific port candidates, it's usually convenient to use the mapper property:
For cases when the desired configuration of port candidates can be readily created from the edge itself, the delegate is often the most convenient option:
See Also
Sample Graphs
Gets or sets a mapping from edges to their target PortConstraint.
Remarks
Port constraints allow to define where an edge attaches to its target node and can either restrict that to one of the node's sides, or to a fixed port position.
A more general concept which allows finer control over where ports are placed, are port candidates.
Examples
If all edges should exit their source node on the same side, you can simply set a constant constraint for all edges:
To change the constraints for individual edges, it's usually easiest to use the mapper:
If a PortConstraint can readily be created from an edge, using a delegate is often easier:
See Also
Sample Graphs
Gets or sets a mapping from edges to an object representing their target port group.
Remarks
Examples
The simplest way to use target port groups is to use the same object as group ID for all edges. Since grouping is done per node, this has the effect of grouping all edges with the same target node together:
The same effect can be achieved with a delegate as well, by returning the target node as group ID for each edge. However, a more useful way to use a delegate here would be grouping edges by some commonality, such as the same color:
If only certain edges should be grouped it may sometimes be easier to use the mapper to set the group IDs:
See Also
Gets or sets the collection of group nodes for which the ports of the adjacent edges are uniformly distributed.
Remarks
By default, there is no guarantee that the ports at group nodes are uniformly distributed. This setting only affects the two sides of a group node that are in flow and against the flow of the layout orientation. For example, for orientation TOP_TO_BOTTOM only the edges incident to the top and bottom group node side are considered but not the edges at the left and right side.
The uniform group port assignment considers the edge-to-edge distance such that two ports keep the specified distance to each other. Group nodes may in consequence be enlarged to satisfy that constraints, potentially generating less compact layouts. The distance from the group node border to the first/last port on each group side may be influenced by using group node insets.
Importantly, it is not guaranteed that the group node ports of a specific side can be uniformly distributed. In the following cases ports of a specific side are not uniformly distributed:
- There are edges that cross the group node border because they connect to a child node of the group.
- There is a self-loop at the group node which has its source and target port at the same group node side.
Examples
See Also
Sample Graphs
Methods
Combines this instance with the given layout data.
Remarks
Parameters
A map of options to pass to the method.
- data - LayoutData
- The LayoutData to combine this instance with.
Returns
- ↪LayoutData
- The combined layout data.