Graphic Components > Network Component > Network Component Services > Layout

JViews TGO makes use of the ILOG JViews graph layout algorithms. Each IlpNetworkView can be connected to several node algorithms and one link algorithm.

The detailed description of all the graph layout algorithms can be found in the ILOG JViews Diagrammer Using Graph Layout Algorithms documentation.

In case of multiple layouts, one layout can be set to be applied automatically whenever the contents of the view changes, while the others can be applied on demand. If the view contains subnetworks, you can specify different node layouts and a different link layout for the subnetworks.

To configure the layouts, it is recommended to use CSS (see Configuring a Network Component through a CSS File). Using CSS, you can also configure per-object layout parameters.

If a layout takes too much time to execute, or if you want to add toolbar buttons to execute a layout, you can configure the layout for the view and subnetworks, then execute it on demand by using the API method performAttachedLayout. The advantage of this method over the method performLayoutOnce is that the layout remains attached to the view, therefore storing any previously-defined configuration.

The class IlpNetworkView provides the following methods to handle the layout operation:

Note
Graphical parameters, such as the layout region, that are passed to the graph layout are expressed in view coordinates. Therefore, if you have expressed these parameters in stationary coordinates, you must transform them to view coordinates (by applying network.getView().getCompositeGrapher().getZoomTransformer() network.getManagerView().getTransformer()) before passing them to the graph layout.

How to Use Hierarchical Node Layout in the Network Component

In CSS, use the following rules:

Network {
  graphLayout: true;
}
  
GraphLayout {
  class: 'ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout';
  flowDirection: Bottom;
  levelJustification: Top;
  globalLinkStyle: 'ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout.POLYLINE_STYLE';
  connectorStyle: 'ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout.EVENLY_SPACED_PINS';
}

Note that the full class path is required for the properties globalLinkStyle and connectorStyle for the type converter to locate and convert the constants.

Please refer to The LinkLayout Rule for an example of a CSS link layout.

In the API, use the following code:

IlvHierarchicalLayout layout = new IlvHierarchicalLayout();
layout.setFlowDirection (IlvDirection.Bottom);
layout.setLevelJustification (IlvDirection.Top);
layout.setGlobalLinkStyle (IlvHierarchicalLayout.POLYLINE_STYLE);
layout.setConnectorStyle (IlvHierarchicalLayout.EVENLY_SPACED_PINS);
 
network.setNodeLayout(layout);

Note
All layouts to be used with JViews TGO must be set in view coordinate mode. This mode is automatically set when you install layouts through setNodeLayout, setLinkLayout, or performLayoutOnce. If you call the method IlvGraphLayout.performLayout directly, you must first set the mode: layout.setCoordinatesMode(IlvGraphLayout.VIEW_COORDINATES);

Even when you decide to use a certain node or link layout, you may want some links or nodes to be pinned; that is, you may want to keep a certain element in a specified position that is not affected when the layout is executed on a network.

You can achieve this effect by using the following methods defined in IlvGraphLayout:

How to Set a Link to Fixed Shape and a Node to Fixed Position in the Network View

The following code illustrates how you can set a given link to have a fixed shape and a given node to have a fixed position in the network.

In CSS, use the following rules:

Network {
  graphLayout: true;
  linkLayout: true;
}
 
LinkLayout {
  class: 'ilog.views.graphlayout.link.IlvLinkLayout';
}
 
GraphLayout {
  layouts[0]: @+treeLayout;
}
 
Subobject#treeLayout {
  class: 'ilog.views.graphlayout.tree.IlvTreeLayout';
}
 
#Link:linkLayoutRenderer {
  fixed: true;
}
 
#NE1:graphLayoutRenderer:tree {
  fixed: true;
}

In the API, use the following code:

IlvGraphLayout layout = networkView.getLinkLayout();
layout.setPreserveFixedLinks (true);
IlpRepresentationObject linkRO =  networkAdapter.getRepresentationObject(link);
layout.setFixed(networkView.getLayoutProxy(linkRO)); 
 
layout = networkView.getNodeLayout();
layout.setPreserveFixedNodes (true);
IlpRepresentationObject neRO =  networkAdapter.getRepresentationObject(ne);
layout.setFixed(networkView.getLayoutProxy(neRO));

When the position or shape of an object is not handled by the layout, you must set it by calling the method IlpNetwork.setPosition (or IlpNetworkView.setPosition).

JViews TGO provides a default layout which uses IlvShortLinkLayout to shape and position links. This default layout sets all objects without an attached position to (0,0).

How to Use Multiple Node Layouts in a Network View

In this scenario, two node layouts are configured for the network view. The first one is configured to be executed automatically.

In CSS, use the following rules:

Network {
  graphLayout: true;
}
 
GraphLayout {
  layouts[0]: @+hierarchicalLayout;
  layouts[1]: @+treeLayout;
  autoLayoutIndex: 0;
}
 
Subobject#hierarchicalLayout {
  class: 'ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout';
  flowDirection: Bottom;  
  levelJustification: Top;  
  globalLinkStyle: POLYLINE_STYLE;
  connectorStyle: EVENLY_SPACED_PINS;
}
 
Subobject#treeLayout {
  class: 'ilog.views.graphlayout.tree.IlvTreeLayout';
  flowDirection: Bottom;
}

The same layout that is applied to the network view will be applied to the whole subnetwork hierarchy.

In the API, use the following code:

IlvHierarchicalLayout layout = new IlvHierarchicalLayout();
layout.setFlowDirection (IlvDirection.Bottom);
layout.setLevelJustification (IlvDirection.Top);
layout.setGlobalLinkStyle (IlvHierarchicalLayout.POLYLINE_STYLE);
layout.setConnectorStyle (IlvHierarchicalLayout.EVENLY_SPACED_PINS); 
 
IlvTreeLayout treeLayout = new IlvTreeLayout();
layout.setFlowDirection(IlvDirection.Bottom);
 
network.setGraphLayouts(new IlvGraphLayout[] { layout, treeLayout });
network.getView().optimizeLayout();

To execute the tree layout in the view, use the method performAttachedLayout, where the index is the one defined in the CSS configuration, as illustrated below:

network.getView().performAttachedLayout(1);
How to Use Different Layouts for the View and Subnetworks

It is also possible to configure some subnetworks with layout algorithms that are different from the network view.

Note
If the subnetworks have intergraph links, the link layout renderer must be enabled, otherwise the intergraph links will not be routed.

In this scenario, the object 'SubNetwork1' positions its nodes using a tree layout algorithm, while the nodes in the main view are positioned using a grid layout.

In CSS, use the following rules:

Network {
  graphLayout: true;
  linkLayout: true;
}
 
LinkLayout {
  class: 'ilog.views.graphlayout.link.IlvLinkLayout';
}
 
GraphLayout {
  layouts[0]: @+gridLayout;
}
 
Subobject#gridLayout {
  class: 'ilog.views.graphlayout.grid.IlvGridLayout';
}
 
#SubNetwork1:graphLayoutRenderer {
  layouts[0]: @+treeLayout;
}
 
Subobject#treeLayout {
  class: 'ilog.views.graphlayout.tree.IlvTreeLayout';
}

In the API, use the following code:

IlvGridLayout gridLayout = new IlvGridLayout();
network.setGraphLayouts(new IlvGraphLayout[] { gridLayout });
 
IlvTreeLayout treeLayout = new IlvTreeLayout();
layout.setFlowDirection(IlvDirection.Bottom);
 
IlpRepresentationObject ro = network.getAdapter().getRepresentationObject("SubNetwork1");
network.getView().setGraphLayouts(ro, new IlvGraphLayout[] { treeLayout });
network.getView().optimizeLayout();
How to Configure Per-Object Layout Properties in the Network Component

Some layout algorithms require a specific configuration in order to be properly executed. For example, the bus layout needs to have a bus object specified; or the tree layout, for which you may want to specify the root node prior to the layout execution. Starting from JViews TGO 7.5, you can configure these properties using CSS, as illustrated below:

Network {
  graphLayout: true;
}
 
GraphLayout {
  layouts[0]: @+busLayout
}
 
Subobject#busLayout {
  class: 'ilog.views.graphlayout.bus.IlvBusLayout';
  horizontalOffset: 50;
  verticalOffsetToLevel: 50;
  verticalOffsetToPreviousLevel: 40;
  margin: 30;
  marginOnBus: 50;
}
 
// Configure the bus object as the bus in the layout
// All layout configuration uses the 'graphLayoutRenderer'
// and the graph layout name pseudoclasses
#BUS:graphLayoutRenderer:bus { 
  bus: true;
}
 
// Configure the bus to route the links that connect the 
// bus to the nodes
#BUS { 
  linksConnectToBase: true;
}

or, using the API:

IlvBusLayout busLayout = new IlvBusLayout();
network.setGraphLayouts(new IlvGraphLayout[] { busLayout });
 
IlpRepresentationObject ro = network.getAdapter().getRepresentationObject("BUS");
IlvGraphic layoutProxy = network.getView().getLayoutProxy(ro);
busLayout.setBus((IlvPolyPointsInterface)layoutProxy);
How to Disable the Per-Object Layout Properties Configuration in the Network View

By default, per-object layout parameters can be configured using CSS. However, if you are not interested in this feature, you can disable it by setting the property usePerObjectParamenters in the graph layout renderer and link layout renderer. Disabling the per-object layout properties configuration speeds up significantly the rendering process.

Network {
  graphLayout: true;
  linkLayout: true;
}
 
LinkLayout {
  class: 'ilog.views.graphlayout.link.IlvLinkLayout';
  usePerObjectParameters: false;
}
 
GraphLayout {
  layouts[0]: @+treeLayout;
  usePerObjectParameters: false;
}