Specifies custom data for the RadialLayout.
Examples
The following example shows how to create a new instance of RadialLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel> and use it with an RadialLayout:
const layoutData = new RadialLayoutData()
// use the current selection as center nodes
layoutData.centerNodes = graphComponent.selection.nodes
graph.applyLayout(new RadialLayout(), layoutData)
In many cases the complete initialization of RadialLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel> can also be done in a single object initializer:
const layoutData = new RadialLayoutData({
// use the current selection as center nodes
centerNodes: graphComponent.selection.nodes,
})
graph.applyLayout(new RadialLayout(), layoutData)
Type Parameters
- TNode
- TEdge
- TNodeLabel
- TEdgeLabel
Type Details
- yFiles module
- algorithms
Constructors
Parameters
A map of options to pass to the method.
- centerNodes - ItemCollection<TNode>
- The collection of nodes that should be placed in the center. This option either sets the value directly or recursively sets properties to the instance of the centerNodes property on the created object.
- nodeMargins - ItemMapping<TNode,Insets>
- The mapping from nodes to their margins. This option either sets the value directly or recursively sets properties to the instance of the nodeMargins property on the created object.
- edgeBundleDescriptors - ItemMapping<TEdge,EdgeBundleDescriptor>
- The mapping of edges to their EdgeBundleDescriptor. This option either sets the value directly or recursively sets properties to the instance of the edgeBundleDescriptors property on the created object.
- layerIds - ItemMapping<TNode,number>
- The mapping from nodes to their layer/circle index. This option either sets the value directly or recursively sets properties to the instance of the layerIds property on the created object.
- nodeTypes - ItemMapping<TNode,any>
- The mapping from nodes to an object defining the node type, which influences the ordering of nodes on the same circle such that nodes of the same type are preferably placed next to each other. This option either sets the value directly or recursively sets properties to the instance of the nodeTypes property on the created object.
- childOrder - ChildOrderData<TNode,TEdge>
- The ChildOrderData<TNode,TEdge> which specifies how child nodes are to be sorted. This option either sets the value directly or recursively sets properties to the instance of the childOrder property on the created object.
- nonTreeEdges - ItemCollection<TEdge>
- The collection of edges explicitly marked as not belonging to a tree. This option either sets the value directly or recursively sets properties to the instance of the nonTreeEdges property on the created object.
- ports - BasicPortData<TNode,TEdge,TNodeLabel,TEdgeLabel>
- The sub-data that influences the placement of the ports. This option either sets the value directly or recursively sets properties to the instance of the ports property on the created object.
Properties
Gets or sets the collection of nodes that should be placed in the center.
Remarks
Examples
Defining the nodes that should be placed in the center 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>:
layoutData.centerNodes = 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:
layoutData.centerNodes.items.add(node1)
layoutData.centerNodes.items.add(node2)
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.centerNodes = (node) => (node.tag as CustomData).placeInCenter
See Also
Gets or sets the ChildOrderData<TNode,TEdge> which specifies how child nodes are to be sorted.
Remarks
Examples
The ChildOrderData<TNode,TEdge> class provides two primary methods for determining the order of a parent's child nodes: either by directly sorting the child nodes using targetNodeComparators or targetNodeComparables, or by sorting the outgoing edges from the parent node to its child nodes using outEdgeComparators or outEdgeComparables. Setting a comparable value (e.g. a number or a string) for all nodes means that the child nodes of all parents in the graph are ordered using those values.
// Use the node height as comparable to sort the child nodes by their height
layoutData.childOrder.targetNodeComparables = (child) =>
child.layout.height
Using a comparison delegate for specific nodes is convenient if the child nodes should be ordered only for particular parent nodes.
layoutData.childOrder.targetNodeComparators = (parent: INode) => {
if (parent == specificNode) {
// Define a comparison function only for a specific parent node
// ... and sort its child nodes based on an order value specified in their tags
return (child1: INode, child2: INode) =>
child1.tag.sequenceOrder.compareTo(child2.tag.sequenceOrder)
}
// No ordering for the edges around the other nodes
return null
}
Setting a comparable value (e.g. a number or a string) for all edges means that the outgoing edges of all parents in the graph are ordered using those values.
// Use the label count of the out edges as comparable value to sort them
layoutData.childOrder.outEdgeComparables = (edge) => edge.labels.size
Using a comparison delegate for specific edges is convenient if the outgoing edges should be ordered only for particular nodes.
layoutData.childOrder.outEdgeComparators = (parent: INode) => {
if (parent == specificNode) {
// Define a comparison function only for a specific parent node
// ... and sort its outgoing edges based on an order value specified in their tags
return (edge1: IEdge, edge2: IEdge) =>
edge1.tag.sequenceOrder.compareTo(edge2.tag.sequenceOrder)
}
// No ordering for the edges around the other nodes
return null
}
See Also
Gets or sets the mapping of edges to their EdgeBundleDescriptor.
Remarks
Bundling together multiple edges means that their common parts are to some degree merged into a bundled part. At the source and target point, the edges are again clearly split.
If an edge is mapped to null
, the default descriptor is used.
See Also
Gets or sets the mapping from nodes to their layer/circle index.
Remarks
Nodes with the same ID are placed on the same circle while the circles are sorted according to their IDs such that a smaller ID means that the circle has a smaller radius and is closer to the center of the radial layout.
When providing user-defined IDs, the center nodes (nodes on the innermost circle) are not determined by the specified centerNodesPolicy anymore. Instead, the nodes with the smallest given ID (i.e. 0
) define the set of center nodes.
See Also
Gets or sets the mapping from nodes to their margins.
Remarks
Examples
The easiest option is to reserve the same space around all nodes, by setting a constant value:
layoutData.nodeMargins = new Insets(20)
Handling only certain nodes differently can be done easily by using the mapper property:
// node1 only reserves space above and below
layoutData.nodeMargins.mapper.set(node1, new Insets(20, 10, 0, 0))
// node2 has space all around
layoutData.nodeMargins.mapper.set(node2, new Insets(25))
// all other nodes don't get extra space
In cases where the nodeMargins for each node can be determined by looking at the node itself it's often easier to just set a mapperFunction instead of preparing a mapper:
// Retrieve the space around the node from its tag property
layoutData.nodeMargins = (node: INode): Insets =>
new Insets(parseFloat(node.tag))
See Also
Gets the mapping from nodes to a RadialLayoutNodePlacementResult describing on which circle and in which sector the node is placed.
Examples
const layoutData = new RadialLayoutData()
graph.applyLayout(new RadialLayout(), layoutData)
for (const node of graph.nodes) {
const info = layoutData.nodePlacementsResult.get(node)!
console.log(
`Node ${node} has been placed in circle ${info.circleIndex} with radius ${info.radius}.`,
)
console.log(
`It has been placed in a segment from ${info.sectorStart} to ${
info.sectorStart + info.sectorSize
} degrees`,
)
}
See Also
Gets or sets the mapping from nodes to an object defining the node type, which influences the ordering of nodes on the same circle such that nodes of the same type are preferably placed next to each other.
Remarks
Node types are a subordinate criterion for nodes of the same circle. More precisely, for nodes of the same circle (i.e., within the same layer), the algorithm prefers to place nodes of the same type next to each other if this does not lead to additional crossings or conflicts with other constraints.
Note that the algorithm uses a local optimization heuristic to improve the placement with respect to node types and therefore does not guarantee optimal results. Furthermore, this additional step may increase the required runtime. The layer assignment is not affected by the node types.
See Also
Sample Graphs
Gets or sets the collection of edges explicitly marked as not belonging to a tree.
Remarks
See Also
Gets or sets the sub-data that influences the placement of the ports.
Remarks
The port placement can be influenced by specifying EdgePortCandidates for the source and target of an edge, as well as by specifying NodePortCandidates at the nodes.
In addition, it is possible to specify that ports should be grouped at the source or target.
If both EdgePortCandidates and NodePortCandidates are specified, the layout algorithm tries to match them. An edge port candidate matches a node port candidate if
- Their matchingIds are equal or one type is
null
, - They belong to a common side or one side is ANY, and
- If both candidates are fixed, they describe the same positions.
The position of a port candidate is defined by offset or the actual offset of the edge endpoint for fixed-from-sketch candidates. When there is no match, the port candidate with the lowest costs specified for the edge is chosen.
Methods
combineWith
(data: LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>…) : LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>Combines this instance with the given layout data.
Remarks
Parameters
A map of options to pass to the method.
- data - LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>
- The LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel> to combine this instance with.
Returns
- ↪LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>
- The combined layout data.