This custom data provides several ways to modify the scope of the OrganicLayout with regard to nodes that are laid out.
Type Parameters
- TNode
Type Details
- yFiles module
- algorithms
Properties
Gets or sets the mapping from group nodes to a policy describing how to handle the group node.
Remarks
Examples
The easiest option is to treat all group nodes the same, by just setting a constant value:
layoutData.scope.groupNodeHandlingPolicies =
GroupNodeHandlingPolicy.FIX_CONTENTS
Handling only certain group nodes differently can be done easily by using the mapper property:
layoutData.scope.groupNodeHandlingPolicies.mapper.set(
groupNode1,
GroupNodeHandlingPolicy.FIX_BOUNDS,
)
layoutData.scope.groupNodeHandlingPolicies.mapper.set(
groupNode2,
GroupNodeHandlingPolicy.FIX_CONTENTS,
)
// All other edges not set in the mapper implicitly get the default value
// GroupNodeMode.normal.
In cases where the ideal GroupNodeHandlingPolicy can be determined by looking at the node itself it's often easier to just set a delegate instead of preparing a mapper:
layoutData.scope.groupNodeHandlingPolicies = (node) => {
if (graph.getChildren(node).size > 0) {
return GroupNodeHandlingPolicy.FREE
}
// Ensure that empty group nodes remain where they are
return GroupNodeHandlingPolicy.FIX_BOUNDS
}
See Also
Gets or sets the subset of nodes that are moved by the layout algorithm.
Remarks
Examples
Defining the subset of nodes that should be laid out can be done in various ways, mostly depending on which option is more convenient for a particular use case. You can use the ItemCollection<TItem>'s source property to use any .NET collection or IEnumerable<T>:
const layoutData = new OrganicLayoutData()
layoutData.scope.nodes = graphComponent.selection.nodes
Alternatively, ItemCollection<TItem> also has an items property, which is a collection that already exists, in case the items may have to be added one by one. This can be more convenient than defining an own list and setting it to source:
for (const edge of graphComponent.selection.edges) {
layoutData.scope.nodes.items.add(edge.sourceNode)
layoutData.scope.nodes.items.add(edge.targetNode)
}
A powerful option that doesn't use a collection is to use the predicate to set a custom delegate that returns for every node whether it is contained in the set or not:
// We assume here that all nodes have a CustomData instance as their tag,
// which then has a boolean property 'IncludeInLayout'.
layoutData.scope.scopeModes = (node) =>
(node.tag as CustomData).includeInLayout
? OrganicScope.AFFECTED
: OrganicScope.FIXED
See Also
Defines whether a node and possibly its surrounding nodes are laid out by OrganicLayout.