Using yFiles Layout Functionality

Layout Infrastructure

All graph layout algorithms in the yFiles for Silverlight Algorithms library component implement interface ILayouter. This interface declares methods for testing if a given input graph of type LayoutGraph can be handled, and also for actually assigning a layout to such a graph.

The calculated new layout information that results from an ILayouter invocation supersedes that of the given LayoutGraph object. Figure 10.1, “ILayouter dependencies” shows the dependencies for interface ILayouter.

Figure 10.1. ILayouter dependencies

ILayouter dependencies.

IGraph-related Adapter Mechanisms

Internally, the layout algorithms in the yFiles for Silverlight Algorithms library component are tailored to the LayoutGraph API. By means of the adapter mechanisms presented in Chapter 8, Using yFiles for Silverlight Algorithms Functionality, however, the layout algorithms can be used with an IGraph-based graph structure without much effort as well.

Invoking a layout algorithm can be as simple as this one-liner that implicitly uses the services of class CopiedLayoutIGraph:

Example 10.1. Layout invocation for an IGraph-based graph using adapter mechanisms

// 'graph' is of type yWorks.yFiles.UI.Model.IGraph.

graph.ApplyLayout(new IncrementalHierarchicLayouter());

Layout morphing can also be set up conveniently:

Example 10.2. Layout morphing for a GraphControl's IGraph-based graph

// 'graphControl' is of type yWorks.yFiles.UI.GraphControl.

IncrementalHierarchicLayouter ihl = new IncrementalHierarchicLayouter();
graphControl.MorphLayout(ihl, TimeSpan.FromMilliseconds(500), null);

The following detailed example shows the invocation of a layout algorithm with additional setup prior to calling the algorithm. A dedicated data structure (to hold supplemental data for the layout algorithm) is created, filled, and then registered with the graph.

Example 10.3. Creating edge groupings at a common target node

// 'graph' is of type yWorks.yFiles.UI.Model.IGraph.

// Create a mapper.
IMapper<IEdge, object> egMap = new DictionaryMapper<IEdge, object>();

// Declare an edge group for the target end of all incoming edges at a specific
// node.
string targetEdgeGroupID = "All my grouped edges.";
foreach (IEdge e in graph.InEdgesAt(specificNode)) {
  egMap[e] = targetEdgeGroupID;
}

// Add the mapper to the mapper registry of the graph.
// Use the "well-known" look-up key defined in class PortConstraintKeys as tag.
graph.MapperRegistry.AddMapper(PortConstraintKeys.TargetGroupIdDpKey, egMap);

// Invoke the layouter.
graph.ApplyLayout(new IncrementalHierarchicLayouter());

Nearly all use cases for automatically calculating a layout are conveniently supported using an IGraph-based graph in conjunction with the adapter mechanisms:

  • invoking a layout algorithm
  • layout morphing
  • associating supplemental data to be used by a layout algorithm

Resorting to the layout graph structure should only be necessary for advanced customizations of a layout process, like, e.g., creating a custom layout stage, or (even more advanced) creating a custom ILayerer implementation.

Compared to using the LayoutGraph API, the main differences in the setup with an IGraph-based graph and adapter mechanisms are as follows:

  • No need to use IDataProvider (INodeMap/IEdgeMap): associating supplemental data for graph elements can be conveniently achieved using IMapper<K, V> instances. IMappers that are in the mapper registry of the IGraph are automatically converted to corresponding IDataProviders, which can be accessed by a layout algorithm.
  • Layout invocation: most conveniently, a layout algorithm can be run by means of IGraph (extension) methods.