The task of a layout algorithm is a major undertaking that involves arbitrarily complex logic. However, there can be identified a number of well-defined (sub-)tasks that even completely different algorithms do in a similar manner. Factoring out such tasks so that they can be reused in varying contexts, greatly reduces the complexity of any layout algorithm.
The yFiles library allows to formulate complex layout processes by plugging together so-called "layout stages" that, among other things, can be used to handle such well-defined (sub-)tasks.
A layout stage serves as a kind of container that encapsulates arbitrary layout
functionality, and provides a general means to string together multiple stages
into a compound layout process.
Interface ILayoutStage
defines the
basis for a layout stage.
It is a specialization of interface
ILayouter
, and thus can be used as a
stand-alone layout provider as well as a part of a larger layout process.
The methods of interface ILayoutStage are used to establish a relationship to another ILayouter implementation, the so-called "core layouter." The core layouter's invocation is entirely bracketed by the layout stage's logic.
When used in the context of a larger layout process, the layout stage can easily be used to simplify the core layouter's task. It performs preprocessing steps on the input graph before the core layouter's invocation, and postprocessing steps thereafter.
Table 5.1, “Predefined layout stages” lists some of the predefined ILayoutStage implementations, most of them being part of the default compound layout process as described below. Further layout stages are described in the section called “Layout Stages”.
Table 5.1. Predefined layout stages
| Classname | Description |
|---|---|
| SelfLoopLayouter |
Calculates orthogonal edge paths for a graph's self-loops (reflexive edges). |
| ParallelEdgeLayouter |
Calculates edge paths for all edges with identical source node and target node. (Self-loops are not processed.) |
| OrientationLayouter |
Changes the orientation of a computed layout. |
| SubgraphLayouter |
Reduces the original graph to the subgraph that is induced by selected nodes. |
Figure 5.3, “Layout stages complex” shows the class hierarchy for the layout stages.
The most prominent example for a complex layout process can be observed with
abstract class
CanonicMultiStageLayouter
.
It is the superclass for the yFiles major layout algorithms, and provides a
conveniently configurable layout pipeline for performing preprocessing steps on
the input graph before the core layouter's invocation, and postprocessing steps
thereafter.
The central role of CanonicMultiStageLayouter can also be seen in
Figure 5.9, “The yFiles layout algorithms”.
All layout stages from Table 5.1, “Predefined layout stages” are part of the compound layout process defined by CanonicMultiStageLayouter. The following methods of class CanonicMultiStageLayouter can be used for configuring the layout process:
void AppendStage(ILayoutStage stage) |
|
| Description | Methods to add and remove individual layout stages. |
void EnableOnlyCore() |
|
| Description | Methods and properties for enabling and disabling the predefined layout stages, and also for controlling their enabled state. (Excerpt.) |
ILayoutStage ComponentLayouter { get; set; } |
|
| Description | Properties for predefined layout stages. (Excerpt.) |
The yFiles layout algorithms support advanced functionality that can take into account even individual information for single graph elements. However, individual setup like, e.g., attaching a preferred edge length to each edge, is beyond the means a graph structure provides. Instead, a data provision scheme is used to provide the individual setup as supplemental information to a layout algorithm.
The supplemental data for the graph elements is bound to the graph using a so-called "data provider key." During layout calculation, the algorithm then retrieves the data provider that contains the data from the graph by using the same key.
Depending on the data provider key, the algorithm expects the returned data provider to hold values of specific type for either nodes or edges of the graph. Example 5.4, “Binding supplemental data (IGraph API)” shows the use of an IMapper as the data provider for an IGraph-based graph. The mapper returns an integral value for each edge indicating the edge's preferred length to the organic layout algorithm.
Example 5.4. Binding supplemental data (IGraph API)
// 'graph' is of type yWorks.yFiles.UI.Model.IGraph.
// Create an implicit IMapper and add it to the mapper registry of the graph
// using a so-called data provider look-up key as its tag.
// The key is then used by the layout algorithm to retrieve the supplemental
// data.
graph.MapperRegistry.AddMapper<IEdge, int>(
SmartOrganicLayouter.PreferredEdgeLengthDpKey,
delegate(IEdge e) { return (int)(200 * GetLength(e)); }
);
// Invoke organic layout on the graph.
SmartOrganicLayouter sol = new SmartOrganicLayouter();
graph.ApplyLayout(sol);
|
Copyright ©2004-2011, yWorks GmbH. All rights reserved. |