skip to main content
Diagrammer > Programmer's documentation > Using graph layout algorithms > Automatic label placement > Using the label layout API
 
Using the label layout API
Describes how to perform a label layout.
*Overview
*Provides useful links for label layout.
*The label layout base class and its subclasses
*Describes the classes associated with Label Layout.
*Instantiating and attaching a subclass of IlvLabelLayout
*Describes how to subclass the Label Layout class.
*Performing a layout
*Describes how to start a layout algorithm.
*Performing a recursive layout on nested subgraphs
*Describes how to start layout algorithms recursively on a nested grapher hierarchy.
*The label layout report
*Describes the report on label layout which is generated when you apply the layout.
*Layout events and listeners
*Describes the events provided by the label layout framework and how to listen for them.
*Layout parameters and features in IlvLabelLayout
*Explains which generic parameters and features are defined by the label layout class.
Overview
You will see how to perform a label layout in Java™ when working directly on an IlvManager instance. If you are using Rogue Wave®  JViews Diagrammer with style sheets, see Controlling layout renderers by style sheets.
NOTE Before reading this information, you should be familiar with the IlvGraphLayout class (see Graph layout: using the API). Many of the concepts for the labeling layout mechanism are similar and not all details are repeated in this topic.
The label layout base class and its subclasses
The IlvLabelLayout class is the base class for all label layout algorithms. This class is an abstract class and cannot be used directly.
Subclasses of IlvLabelLayout
There are currently two subclasses:
*IlvRandomLabelLayout which randomizes the label positions for demonstration purpose.
*IlvAnnealingLabelLayout which carries out real label arrangement.
You can also create your own subclasses to implement other label layout algorithms.
The label layout renderer always uses the IlvAnnealingLabelLayout. You can use IlvRandomLayout or your own label layout algorithm when you write Java™ code.
It is not possible to use IlvRandomLayout or your own label layout algorithm in a diagram component based on CSS styling.
Despite the fact that only subclasses of IlvLabelLayout are directly used to obtain the layouts, it is still necessary to learn about this class because it contains methods that are inherited (or overridden) by its subclasses. And, of course, you will need to understand it if you subclass it yourself.
The class IlvLabelLayout and its subclasses and relationship to layout reports
Instantiating and attaching a subclass of IlvLabelLayout
The class IlvLabelLayout is an abstract class. It has no constructors. You will instantiate a subclass as shown in the following example:
 
IlvAnnealingLabelLayout layout = new IlvAnnealingLabelLayout();
In order to place labels, a manager needs to be attached to the layout instance. The following method, defined on the class IlvLabelLayout, allows you to specify the manager you want to lay out:
 
void attach(IlvManager manager)
For example:
 
...
IlvManager manager = new IlvManager();
/* Add obstacles and labels to the manager here */
layout.attach(manager);
The attach method does nothing if the specified manager is already attached. If a different manager is attached, this method first detaches this old manager, then attaches the new one. You can obtain the attached manager using the method getManager. If the manager is attached in this way, a default labeling model is created internally. The labeling model can be obtained by:
 
IlvLabelingModel labelingModel = layout.getLabelingModel();
Warning It is not allowed to attach any such model created internally to any other layout instance.
After layout, when you no longer need the layout instance, you should call the method
 
void detach()
If the detach method is not called, some objects may not be garbage-collected. This method also performs cleaning operations on the manager (properties that may have been added by the layout algorithm on objects of the manager.
Performing a layout
The performLayout methods start the layout algorithm using the currently attached manager and the current settings for the layout parameters. The method returns a report object that contains information about the behavior of the label layout algorithm.
 
IlvLabelLayoutReport performLayout()
IlvLabelLayoutReport performLayout(boolean force, boolean redraw)
The first method simply calls the second one with the force argument set to false and the redraw argument set to true.
*Because the force argument is set to false (by default), the layout algorithm first verifies whether it is necessary to perform the layout. It checks internal flags to see whether the manager or any of the parameters have changed since the last time the layout was successfully performed. A “change” can be any of the following ones:
*Obstacles or labels were added or removed.
*Obstacles or labels were moved or reshaped.
*The value of a layout parameter was modified.
*The transformer changed while nonzoomable obstacles or labels were used.
Users often do not want the layout to be computed again if no changes occurred. If there were no changes, the method performLayout returns without performing the layout. If the argument force is passed as true, the verification is skipped, and layout is performed even if no changes occurred.
*The redraw argument determines whether the manager needs to be redrawn. This mechanism works exactly in the same way as in graph layout. For details, see Redrawing the grapher after layout.
The protected abstract method layout(boolean redraw) is then called. This means that control is passed to the subclasses that are implementing this method. The implementation computes the layout and moves the labels to new positions.
Performing a recursive layout on nested subgraphs
The examples and explanations above assume that you work with a flat manager. Rogue Wave® JViews Diagrammer allows you to nest a grapher as a node into another grapher. You can create a hierarchy of nested graphers (see the following figure); see also Nested graphers in Advanced Features of JViews Framework).
You can apply a recursive graph layout to the nested grapher hierarchy by calling:
 
graphLayout.performLayout(true, true, true);
However, it usually makes no sense to apply a label layout alone to nested graphers. When labels are placed in a subgrapher, this will likely change the bounds of the subgrapher; hence the node positions in its parent grapher will no longer be up-to-date and a new graph layout will be necessary.
It makes sense to apply a label layout in combination with another graph layout to nested graphers.
1. First, the graph layout is applied to arrange the nodes and links nicely.
2. Then the label layout is applied to position the labels according to the node and link positions.
3. When this is finished for all subgraphers, then it can be done for the parent grapher.
To perform a graph layout and a label layout together, you can use the Multiple Layout class. This is a subclass of IlvGraphLayout that allows combining graph layouts with a label layout. The following sample shows how to apply a Tree Layout and an Annealing Label Layout in combination on a subgrapher.
 
IlvTreeLayout treeLayout = new IlvTreeLayout();
IlvAnnealingLabelLayout labelLayout = new IlvAnnealingLabelLayout();
IlvGraphLayout multipleLayout = new IlvMultipleLayout(treeLayout,
                                                      null,
                                                      labelLayout);
// Now set the parameters for tree layout and label layout ...
// Finally, perform a recursive layout that handles tree layout and label
// layout together
try {
    multipleLayout.performLayout(true, true, true);
} catch (IlvGraphLayoutException e) {
    ...
}
Thus, the label layout does not provide a separate mechanism for a recursive layout on submanagers. By incorporating the label layout into a multiple graph layout, you can use all the graph layout facilities that are available for nested graphs (see also Nested layouts).
Nested subgraphers with labels
The label layout report
The label layout report contains information about the particular behavior of a label layout algorithm. After the layout is completed, this information is available for reading from the label layout report. The information can also be obtained during layout by using a layout listener, as described in Layout events and listeners.
The layout report is created automatically at the start of layout via the method createLayoutReport and is available as long as the manager is attached to the layout instance.
To read a layout report, all you need to do is store the layout report instance returned by the performLayout method and read the information, as shown in the following example:
 
...
IlvLabelLayoutReport layoutReport = labelLayout.performLayout();
if (layoutReport.getCode() == IlvLabelLayoutReport.LAYOUT_DONE)
     System.out.println("Label layout done.");
else
     System.out.println("Label layout not done, code = " +
                                         layoutReport.getCode());
The class IlvLabelLayoutReport stores the following information, which is very similar to the information stored in an IlvGraphLayoutReport (see Information stored in a layout report for details):
Code
This field contains information about special, predefined cases that may have occurred during the layout. The possible values are:
*IlvLabelLayoutReport.LAYOUT_DONE
*IlvLabelLayoutReport.STOPPED_AND_VALID
*IlvLabelLayoutReport.STOPPED_AND_INVALID
*IlvLabelLayoutReport.NOT_NEEDED
*IlvLabelLayoutReport.NO_LABELS
*IlvLabelLayoutReport.EXCEPTION_DURING_LAYOUT
To read the code, use the method:
 
int getCode()
Layout time
This field contains the total duration of the layout algorithm at the end of the layout. To read the time (in milliseconds), use the method:
 
long getLayoutTime()
Percentage of completion
This field contains an estimate of the percentage of the layout that has been completed. To access the percentage, use the method:
 
int getPercentageComplete()
Layout events and listeners
The label layout framework provides the same event mechanism as the graph layout framework. Various events may occur.
Label layout events
The class GraphLayoutEvent corresponds to the class GraphLayoutEvent (see Graph layout event listeners). You can install a listener for these events at the layout instance by using the method:
 
labelLayout.addLabelLayoutEventListener(listener);
The listener must implement the LabelLayoutEventListener interface and receives events while the layout is running. A typical example is to check how much of the layout has already completed:
 
class MyLabelLayoutListener
  implements LabelLayoutEventListener
{
  public void layoutStepPerformed(LabelLayoutEvent event)
  {
    IlvLabelLayoutReport layoutReport = event.getLayoutReport();
    System.out.println("percentage of completion: " +
                       layoutReport.getPercentageComplete());
  }
}
Label layout parameter events
The class LabelLayoutParameterEvent corresponds to the class GraphLayoutParameterEvent (see Parameter event listeners). You can install a listener to these events at the layout instance by
 
labelLayout.addLabelLayoutParameterEventListener(listener);
The listener must implement the LabelLayoutParameterEventListener interface and receives events when layout parameters change. It also receives a special event at the end of a successful layout. For example:
 
class MyLabelLayoutParameterListener
  implements LabelLayoutParameterEventListener
{
  public void parametersUpToDate(LabelLayoutParameterEvent event)
  {
    if (!event.isParametersUpToDate())
      System.out.println("Any label layout parameter has changed.”);
  }
}
Layout parameters and features in IlvLabelLayout
The class IlvLabelLayout defines a number of generic features and parameters. These are a subset of the mechanism, methods, and parameters that are available for the IlvGraphModel class. Therefore, they are only listed here; for detailed explanations, refer to the appropriate subsection in Generic parameters and features which describes the corresponding features for the IlvGraphLayout class.
In CSS, the main difference is that you add the specification to the LabelLayout section (not to the GraphLayout section).
Although the IlvLabelLayout class defines the generic parameters, it does not control how they are used by its subclasses. Each label layout algorithm (that is, each subclass of IlvLabelLayout ) supports a subset of the generic features and determines the way in which it uses the generic parameters. When you create your own label layout algorithm by subclassing IlvLabelLayout, you decide whether to use the features and the way in which you are going to use them.
The IlvLabelLayout class defines the following generic features:
*Allowed time
*Percentage of completion calculation
*Random generator seed value
*Stop immediately
*Use default parameters
 
To specify that the label layout is allowed to run for 60 seconds:
In CSS
Add to the LabelLayout section:
 
allowedTime: "60000";
In Java™
Call:
 
labelLayout.setAllowedTime(60000);
For more details of all generic features, see Generic parameters and features.

Copyright © 2018, Rogue Wave Software, Inc. All Rights Reserved.