How to Layout Subsets of Nodes Only
Questions & AnswersSummary
Description
The yFiles layout algorithms provide different ways when only a subset of nodes
shall be arranged.
In the majority of scenarios, the subset of nodes to be processed is declared by
means of an
IMapper
that holds specific supplemental data for each node from the subset.
This supplemental data can be as simple as a boolean value, but can also be more complex.
For example, IncrementalHierarchicLayouter (see below) uses so-called hints.
Incremental Layout Algorithms
Several of the yFiles layout algorithms provide support for incremental layout where distinct parts of a graph can be rearranged and be optimally integrated into an already existing layout.
IncrementalHierarchicLayouter
Class
IncrementalHierarchicLayouter
offers sophisticated support for rearranging a subset of nodes.
A variety of "hints" for nodes (and edges, by the way) is made available by a hint
factory object of type
IIncrementalHintsFactory
.
The hints are then associated with a subset's nodes by means of an IMapper that can be retrieved during the layout process using the look-up key
IncrementalHintsDpKey
.
The setup of IncrementalHierarchicLayouter and the use of hints is shown in this tutorial source code demo:
Demo.yFiles.Layout.IncrementalHierarchicLayouter
OrganicLayouter and SmartOrganicLayouter
For indication of the subset of nodes to be processed, both organic layout algorithms
expect a data accessor (like an IMapper, for example) to return simple boolean values.
The look-up key for the data accessor is
SphereOfActionNodesDpKey
(for OrganicLayouter) and
NodeSubsetDpKey
(for SmartOrganicLayouter), respectively.
GenericTreeLayouter
Class
GenericTreeLayouter
provides support for incremental layout with the help of IComparer implementations.
The IComparers are used to determine the ordering of child nodes at their root node.
There are two schemes available, which can also be combined:
- a single IComparer implementation can be registered as the default to handle all root nodes, i.e., to act globally on the entire tree
- individual IComparer implementations can be registered to handle specific root nodes, i.e., act locally on subtrees
Setting a single IComparer for the entire tree is done with the following line of code:
// 'myChildComparer' is an System.Collection.IComparer implementation.
// 'gtl' is of type yWorks.yFiles.Layout.Tree.GenericTreeLayouter.
gtl.DefaultChildComparator = myChildComparer;
Setting individual IComparer for specific subtrees is done by means of an IMapper
that can be retrieved by GenericTreeLayouter using the look-up key
ChildComparatorDpKey
TreeLayouter, BalloonLayouter, HVTreeLayouter, and ARTreeLayouter
Similar to GenericTreeLayouter (see above), the tree layout algorithm classes
TreeLayouter
,
BalloonLayouter
,
HVTreeLayouter
,
and
ARTreeLayouter
also provide support for incremental layout.
Using the
Comparator
property, a
NodeOrderComparator
(an IComparer implementation) that is used to determine the ordering of child nodes at their respective root node can be registered.
It works in conjunction with an IMapper that is retrieved using the
NodeOrderDpKey
look-up key.
Class NodeOrderComparator, when given the outgoing edges of a (sub)tree's root node, uses the target nodes of the edges for querying the IMapper.
The System.Collections.IComparable objects, which the IComparer implementation expects in return, are then used to determine the order of the child nodes.
Setting a NodeOrderComparator is done with the following line of code:
// 'myChildComparator' is a NodeOrderComparator.
// 'tl' is an instance of one of the tree layout algorithm classes TreeLayouter,
// BalloonLayouter, HVTreeLayouter, or ARTreeLayouter.
tl.Comparator = myChildComparator;
Note that class TreeLayouter in particular uses a
XCoordComparator
instance as the default NodeOrderComparator to enable incremental layout by default.
BalloonLayouter
As an alternative to using an explicit IComparer implementation, class
BalloonLayouter
also supports incremental layout by taking into account a diagram's current drawing when
calculating a new layout.
This special mode can be enabled using property
FromSketchMode
.
PartialLayouter
Class PartialLayouter
supports arranging user-specified parts of a diagram, the so-called partial elements. In a first step, partial elements are combined to form subgraph components. Subsequently, these are arranged and afterwards placed so that the remainder of the diagram, which consists of the so-called fixed elements, is not affected.
This concept is a perfect fit for incremental scenarios where subsequently added parts should be arranged so that they fit best possible into a given diagram without applying any changes to the already existing layout.
The subset of graph elements that shall be processed (the partial elements) can be specified using the data provider keys PartialNodesDpKey
and PartialEdgesDpKey
. This layouter
also supports different strategies for component placement
, component assignment
and edge routing
.
Non-incremental Layout Algorithms
The group of layout algorithms that is not capable of incremental layout, but nevertheless
is able to process only a subset of a graph, does so by means of the look-up key
SelectedNodesDpKey
in conjunction with class
SubgraphLayouter
.
SubgraphLayouter is an already built-in layout stage in class
CanonicMultiStageLayouter
,
which is the superclass of almost all yFiles major layout algorithms.
To activate it, the following line of code suffices.
// 'layouter' is of type yWorks.yFiles.Layout.CanonicMultiStageLayouter (i.e. one
// of the yFiles major layouters).
layouter.SubgraphLayouterEnabled = true;
Using SubgraphLayouter, the best results can be achieved when whole
components are processed, i.e., when there are no (or only a small number of) interconnections
between selected elements and non-selected elements.