Class ComponentLayouter

Class ComponentLayouter provides services for arranging the connected components of a graph. When invoked, it calls its core layouter on each of the input graph's components. After the core layouter has successively performed its layout processes, ComponentLayouter regains control and arranges the separate components.

Wrapping a core layouter with a ComponentLayouter object has several benefits:

Supplemental Layout Data

Class ComponentLayouter knows a number of data provider keys which are used to retrieve supplemental layout data for a graph's elements. The data is bound to the graph by means of a data provider, which is registered using a given look-up key. Table 5.13, “Data provider look-up keys” lists all look-up keys for ComponentLayouter.

Binding supplemental layout data to a graph is described in the section called “Providing Supplemental Layout Data”.

Table 5.13. Data provider look-up keys

Key Element Type Value Type Description
LAYOUT_NODE_DPKEY Node boolean For each node a boolean value indicating whether it should be layouted or not.
GIVEN_COMPONENT_ID_DPKEY Node Object For each node an arbitrary Object indicating the component it is affiliated with.

Layout Options

Class ComponentLayouter provides a set of options that influence its behavior.

Component Arrangement Style (see API)

Specifies the style for arranging the components of a graph. ComponentLayouter supports a variety of different arrangement styles which can be set as shown in Example 5.15, “Arranging components”.

Example 5.15. Arranging components

// 'graph' is of type y.layout.LayoutGraph. 

OrganicLayouter ol = new OrganicLayouter();
ComponentLayouter cl = (ComponentLayouter)ol.getComponentLayouter();

// Set another arrangement style instead of the default 
// ComponentLayouter.STYLE_ROWS. 
cl.setStyle(ComponentLayouter.STYLE_PACKED_COMPACT_RECTANGLE);

// Buffered layout with component arrangement. 
new BufferedLayouter(ol).doLayout(graph);

Component Spacing (see API)

Defines the minimum distance between the bounding boxes of adjacent components.

Label Awareness (see API)

Determines whether node and edge labels are taken into account when computing the bounding boxes of components.

Grid Spacing (see API)

Defines the spacing of the grid on which the separate components are placed.

Preferred Layout Size (see API)

Defines the preferred size of the layout.

Arranging Components (see API)

Determines whether the separate components should be arranged or not.

Support for Hierarchically Organized Graphs (see API)

Specifies whether the graph's hierarchical organization is taken into account when determining its components.

Advanced Layout Techniques

Class ComponentLayouter offers the possibility to call the core layouter only on a subset of the graph's components, effectively excluding the coset of components from layout calculation. This technique is presented in Example 5.16, “Excluding components from layout calculation”.

Example 5.16. Excluding components from layout calculation

// 'graph' is of type y.layout.LayoutGraph. 

NodeList[] components = GraphConnectivity.connectedComponents(graph);

// Create a node map that will be used as a data provider to hold boolean 
// values indicating whether a component should be considered for layout 
// calculation. 
NodeMap nm = graph.createNodeMap();
// Register the node map with the graph using the special look-up key defined 
// by class ComponentLayouter. 
graph.addDataProvider(ComponentLayouter.LAYOUT_NODE_DPKEY, nm);

// Every second component of the graph is marked so that a layout is calculated 
// for it. The other components, while being arranged nevertheless, are not 
// considered for layout calculation. 
for (int i = 0; i < components.length; i += 2)
  nm.setBool(components[i].firstNode(), true);

// The default ComponentLayouter stage of OrganicLayouter arranges all 
// components. 
new BufferedLayouter(new OrganicLayouter()).doLayout(graph);

// Remove the data provider from the graph. 
graph.removeDataProvider(nm);

Example 5.17, “Using different layout algorithms for components” shows how ComponentLayouter can be used in conjunction with class LayoutMultiplexer to invoke different layout algorithms on the separate components of a graph.

Example 5.17. Using different layout algorithms for components

// 'graph' is of type y.layout.LayoutGraph. 

NodeList[] components = GraphConnectivity.connectedComponents(graph);

// Create a node map that will be used as a data provider to hold a Layouter 
// implementation for each of the components. This layouter will be used for 
// layout calculation.
NodeMap nm = graph.createNodeMap();
// Register the node map with the graph using the special look-up key defined 
// by class LayoutMultiplexer.
graph.addDataProvider(LayoutMultiplexer.LAYOUTER_DPKEY, nm);

// For each component one of the layouters is set.
Layouter[] coreLayouter = { new HierarchicLayouter(), 
                            new SmartOrganicLayouter(), 
                            new OrthogonalLayouter() };
for (int i = 0; i < components.length; i++) {
  nm.set(components[i].firstNode(), coreLayouter[i % 3]);
}

// ComponentLayouter uses LayoutMultiplexer as its core layouter, which, for 
// each component, invokes the layouter retrieved from the data provider 
// registered with the graph.
// Afterwards, the ComponentLayouter nicely arranges the components.
ComponentLayouter cl = new ComponentLayouter();
cl.setCoreLayouter(new LayoutMultiplexer());
new BufferedLayouter(cl).doLayout(graph);

// Remove the data provider from the graph. 
graph.removeDataProvider(nm);