Where to Find Up-to-date yFiles Information

This page is from the outdated yFiles for Java 2.13 documentation. You can find the most up-to-date documentation for all yFiles products on the yFiles documentation overview page.

Please see the following links for more information about the yFiles product family of diagramming programming libraries and corresponding yFiles products for modern web apps, for cross-platform Java(FX) applications, and for applications for the Microsoft .NET environment.

More about the yFiles product family Close X

Interactive Organic Layout

Class InteractiveOrganicLayouter provides organic layout for use in interactive environments. Its strength is its capability to generate continuous updates to the layout of a graph during calculation. Furthermore, it also allows a user to seemingly simultaneously perform arbitrary modifications to a graph, which are subsequently accounted for in the layout calculation.

In contrast to the majority of yFiles layout algorithms, class InteractiveOrganicLayouter does not inherit from CanonicMultiStageLayouter, but is instead provided as an implementation of interface Layouter as depicted in Figure 5.65, “Interactive organic layout implementation”.

Figure 5.65. Interactive organic layout implementation

Interactive organic layout implementation.

Among other things, this means that there is no special support for routing of either self-loops or parallel edges, for example. In particular, when a graph contains parallel edges, they will be routed using overlapping edge paths.

General Usage

InteractiveOrganicLayouter is designed to be used in a concurrent setup where the layout algorithm runs in a thread of its own. This enables an application that executes on the event-dispatching thread (EDT) and presents a graphical user interface (GUI) to the user to remain fully interactive even while the layout algorithm performs its calculations. Moreover, the actual setup also enables modifications to the graph seemingly simultaneous to the layout calculation by InteractiveOrganicLayouter.

Setup

First and foremost, the setup for using interactive organic layout relies on a thread to encapsulate the layout functionality. The thread can be created and started by means of the following convenience method. It subsequently begins the layout calculation for the given graph.

Thread startLayout(LayoutGraph graph)
Description Creates and starts the layout thread.

If the graph that is to be processed by InteractiveOrganicLayouter is intended to allow structural modifications by a user, then it is strongly recommended to use an instance of CopiedLayoutGraph instead of a simple LayoutGraph. Doing so helps avoiding race conditions and synchronization problems that occur when nodes and/or edges can be added to or removed from the graph while the layout algorithm performs its calculations.

Creation of the layout thread using a copy of the original graph is shown in Example 5.33, “Creating the layout thread”.

Example 5.33. Creating the layout thread

void createAndStartLayoutThread(InteractiveOrganicLayouter iol, 
                                LayoutGraph graph) {
  // Create a copy of the given graph. Using an instance of CopiedLayoutGraph 
  // helps avoiding race conditions with graph *structure* modifications from a 
  // user. 
  final CopiedLayoutGraph clg = new CopiedLayoutGraph(graph);
  iol.startLayout(clg);
}

State

Interactive organic layout algorithm can be in either of three states: running, sleeping, or stopped. When running, the algorithm lives on the allowed maximal runtime and continuously calculates "intermediate" layouts for the given graph. When sleeping, the algorithm does nothing, but is still "alive." In contrast, when stopped, the algorithm is terminated. Figure 5.66, “State diagram for InteractiveOrganicLayouter” depicts the states and the possible state transitions of InteractiveOrganicLayouter.

Figure 5.66. State diagram for InteractiveOrganicLayouter

State diagram for InteractiveOrganicLayouter.

The following methods can be used to query the current state of an InteractiveOrganicLayouter instance, change its state, and set the maximal runtime. Note that when an instance is changed from "sleeping" to "running" state, the maximal runtime is again fully available.

boolean isRunning()
boolean isSleeping()
boolean isStopped()
Description Getter methods to query the algorithm's current state.
void wakeUp()
void stop()
void stopAndWait()
Description Methods to change the current state.
void setMaxTime(long maxTime)
Description Determines the maximal runtime when in "running" state.

Polling for Results

The concurrent setup as used with InteractiveOrganicLayouter means that the layout process does not return a single result by itself, but instead continuously generates "intermediate" results as long as it is in "running" state. These results are in the layout algorithm's data structures only, but can be polled by a user at any time and be used as continuous updates to the layout of a graph.

The following methods allow to easily poll either the current coordinates of single nodes or commit all current positions of nodes to the original graph at once:

double getCenterX(Node node)
double getCenterY(Node node)
YPoint getCenter(Node node)
Description Retrieve the current center coordinate(s) of a single node from InteractiveOrganicLayouter's data structures.
void commitPositions()
double commitPositionsSmoothly(double maxMovement, double percentage)
Description Updates all node locations with the coordinates from InteractiveOrganicLayouter's data structures.

Typically, to assign the "intermediate" results in a contiuous fashion to the original graph, a technique similar to that outlined in Example 5.34, “Repeatedly polling InteractiveOrganicLayouter for the current node positions” can be used. The current positions of all nodes are repeatedly polled by means of a javax.swing.Timer.

Example 5.34. Repeatedly polling InteractiveOrganicLayouter for the current node positions

void createAndStartPollingTimer(final InteractiveOrganicLayouter iol) {
  // Create and start a Timer object that will poll the given 
  // InteractiveOrganicLayouter instance every 25 milliseconds to update the 
  // node positions in the original graph. 
  new javax.swing.Timer(25, new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
      // Test if the layout algorithm is in running state. 
      if (iol == null || !iol.isRunning()) {
        return;
      }
      // Smoothly update the node positions from the layout algorithm's data 
      // structures to the original graph. 
      iol.commitPositionsSmoothly(50, 0.15);
    }
  }).start();
}

Interaction

The interactive organic layout algorithm allows a user to seemingly simultaneously modify node positions and also node-related parameters while layout calculation takes place. The following methods can be used to update InteractiveOrganicLayouter's data structures with new node positions, and also to specify further node-related parameters that determine, e.g., the size of a node or its inertia:

void setCenterX(Node node, double x)
void setCenterY(Node node, double y)
void setCenter(Node node, double x, double y)
Description Set the current center coordinate(s) of a single node in InteractiveOrganicLayouter's data structures.
void setInertia(Node node, double inertia)
void setRadius(Node node, double radius)
Description Further node-related parameters used by InteractiveOrganicLayouter.

In addition, InteractiveOrganicLayouter optionally also supports modifications to the original graph's structure, i.e., nodes and/or edges can be added to or removed from the graph and the layout calculation subsequently properly accounts for these changes. The following setter method has to be used to enable support for structural modifications.

Important

To avoid race conditions and synchronization problems when structural changes to the graph are allowed, it is strongly recommended to provide InteractiveOrganicLayouter a copy of the original graph using an instance of CopiedLayoutGraph. See also the section called “Setup”.

void setAutomaticStructureUpdateEnabled(boolean enable)
Description Enables/disables automatic updates for structural changes in the original graph.

To properly support arbitrary structural modifications to the original graph, interactive organic layout relies on proper notification by means of graph events. To this end, a GraphListener is registered with the original graph that informs InteractiveOrganicLayouter of any structural changes that occur. See also the description of graph listeners in the section called “Events and Listeners”.

As an alternative to using automatic structure updates, the structure of the original graph can also be synchronized explicitly using code similar to that shown in Example 5.35, “Performing explicit structure updates”.

Example 5.35. Performing explicit structure updates

// 'iol' is of type y.layout.organic.InteractiveOrganicLayouter. 

boolean enabled = iol.isAutomaticStructureUpdateEnabled();
// Disable automatic structure updates. 
iol.setAutomaticStructureUpdateEnabled(false);

// Perform the actual graph structure modifications on the original graph. 
// For example, remove some nodes and edges... 
modifyOriginalGraphStructureHere();

// Synchronize the structure of the original graph with that of the copy given 
// to InteractiveOrganicLayouter. 
iol.syncStructure();

// Reset to previous behavior for automatic structure updates. 
iol.setAutomaticStructureUpdateEnabled(enabled);

Supplemental Layout Data

Class InteractiveOrganicLayouter 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.44, “Data provider look-up keys” lists all look-up keys for InteractiveOrganicLayouter.

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

Table 5.44. Data provider look-up keys

Key Element Type Value Type Description
PREFERRED_EDGE_LENGTH_DATA Edge double For each edge a double value that indicates its preferred length.

Layout Options

Interactive organic layout provides a set of options that affect its behavior. These options can be set using the setter methods of class InteractiveOrganicLayouter.

Maximal Runtime
API
void setMaxTime(long time)
Description Sets the maximal duration of the layout process in milliseconds.

After the layout process has finished or the time specified using Maximal Runtime is spent, InteractiveOrganicLayouter will sleep, i.e., it has to be awakened before another layout process can be invoked (see also the description of running/sleeping state of InteractiveOrganicLayouter).

If this upper bound is hit during the layout process, the quality of the layout may not be optimal. Increasing the value increases the likeliness of an optimal layout.

Preferred Node Distance
API
void setPreferredNodeDistance(double distance)
Description The preferred node distance which will be used to calculate the layout. The layout algorithm tries to arrange the nodes in such a way that the desired distance is complied with.

The following methods allow to specify both the general preferred length for all edges as well as individual preferred edge lengths. The layout algorithm tries to arrange the nodes in such a way that the edges have the desired edge length. Note that the edge length is measured from node border to node border.

Preferred Edge Length
API
void setPreferredEdgeLength(double preferredEdgeLength)
void setPreferredEdgeLength(Edge edge, double newEdgeLength)
Description Setter methods for both general preferred edge lengths as well as individual preferred edge lengths.

Alternatively, to specify the preferred edge length for each edge individually, a data provider holding such supplemental layout data can be bound to the graph. The data provider is expected to be registered with the graph using key PREFERRED_EDGE_LENGTH_DATA. Note that in the absence of an individual preferred edge length the general preferred edge length will be used.

Important

Although the data provider look-up key defined in class OrganicLayouter is used to specify individual preferred edge lengths, the actual type of data provided are double values.

Quality
API
void setQuality(double quality)
Description This setting can be used to adjust the quality of the layout calculated by the layout algorithm. Small values lead to short running times, while greater values result in better quality. For large graph structures (hundreds and thousands of nodes) it is advisable to begin with smaller values and to gradually increase them.

Output Restrictions

Class InteractiveOrganicLayouter allows to impose so-called "output restrictions" on the result of the layout calculcation. More precisely, the layout result can be determined to fit into a specified region, e.g., a rectangle or a circle. Also, the layout result can be restricted to a specified aspect ratio, too.

void setOutputRestriction(OutputRestriction outputRestriction)
Description Class OutputRestriction serves as a factory to create predefined output restrictions that can be used in conjunction with this setter method.

Tutorial Demo Code

Using the layout functionality of class InteractiveOrganicLayouter in an interactive environment where the user can "live"-drag nodes is presented in detail in the following tutorial demo applications: