001/*
002 * Copyright 2006 - 2013
003 *     Stefan Balev     <stefan.balev@graphstream-project.org>
004 *     Julien Baudry    <julien.baudry@graphstream-project.org>
005 *     Antoine Dutot    <antoine.dutot@graphstream-project.org>
006 *     Yoann Pigné      <yoann.pigne@graphstream-project.org>
007 *     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
008 * 
009 * This file is part of GraphStream <http://graphstream-project.org>.
010 * 
011 * GraphStream is a library whose purpose is to handle static or dynamic
012 * graph, create them from scratch, file or any source and display them.
013 * 
014 * This program is free software distributed under the terms of two licenses, the
015 * CeCILL-C license that fits European law, and the GNU Lesser General Public
016 * License. You can  use, modify and/ or redistribute the software under the terms
017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
019 * the Free Software Foundation, either version 3 of the License, or (at your
020 * option) any later version.
021 * 
022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
024 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
025 * 
026 * You should have received a copy of the GNU Lesser General Public License
027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
028 * 
029 * The fact that you are presently reading this means that you have had
030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
031 */
032package org.graphstream.ui.layout;
033
034import org.graphstream.stream.Pipe;
035import org.graphstream.ui.geom.Point3;
036
037/**
038 * Layout algorithm interface.
039 * 
040 * <p>
041 * The layout algorithm role is to compute the best possible positions of nodes
042 * in a given space (2D or 3D) and eventually break points for edges if
043 * supported using either aesthetic constraints, hierarchical constraints or
044 * grouping constraints. As there are many such algorithms with distinct
045 * qualities and uses, this interface defines what is awaited from a general
046 * layout algorithm.
047 * </p>
048 * 
049 * <p>
050 * This algorithm is a {@link Pipe} that receives notifications on the graph
051 * eventually maintain an internal representation of it (or for some of them
052 * work directly on the graph), and in return send graph events to give each
053 * node a position via "xyz" attributes. Some algorithms may also export more
054 * information for nodes and edges. For example some algorithms are also able to
055 * work on the shape of an edge or the shape of a node.
056 * </p>
057 * 
058 * <p>
059 * The layout algorithm described by this interface may be iterative. Some
060 * algorithm will compute directly their final representation of the graph in
061 * one pass. However most algorithms will probably work step by step until a
062 * global quality function is satisfied. This is the best way to handle evolving
063 * graphs.
064 * </p>
065 * 
066 * <p>
067 * This behavior has been chosen because this algorithm is often run aside the
068 * main thread that works on the graph. We want a thread to be able to compute a
069 * new layout on its side, without disturbing the main algorithm run on the
070 * graph. See the {@link org.graphstream.ui.layout.LayoutRunner} for an helper
071 * class allowing to create such a thread.
072 * </p>
073 * 
074 * <p>
075 * To be notified of the layout changes dynamically, you must register as a
076 * sink of the layout.
077 * </p>
078 * 
079 * <p>
080 * The graph viewers in the UI package often use a layout algorithm to present
081 * graphs on screen.
082 * </p>
083 * 
084 * @since 20050706
085 */
086public interface Layout extends Pipe {
087        /**
088         * Name of the layout algorithm.
089         */
090        String getLayoutAlgorithmName();
091
092        /**
093         * How many nodes moved during the last step?. When this method returns
094         * zero, the layout stabilized.
095         */
096        int getNodeMovedCount();
097
098        /**
099         * Estimate of how close to stabilization the layout algorithm is.
100         * 
101         * @return a value between 0 and 1. 1 means fully stabilized.
102         */
103        double getStabilization();
104
105        /**
106         * Above which value a correct stabilization is achieved?
107         * 
108         * @return The stabilization limit.
109         */
110        double getStabilizationLimit();
111
112        /**
113         * Smallest point in space of the layout bounding box.
114         */
115        Point3 getLowPoint();
116
117        /**
118         * Largest point in space of the layout bounding box.
119         */
120        Point3 getHiPoint();
121
122        /**
123         * Number of calls made to step() so far.
124         */
125        int getSteps();
126
127        /**
128         * Time in nanoseconds used by the last call to step().
129         */
130        long getLastStepTime();
131
132        /**
133         * The current layout algorithm quality. A number between 0 and 1 with 1 the
134         * highest (but probably slowest) quality.
135         * 
136         * @return A number between 0 and 1.
137         */
138        double getQuality();
139
140        /**
141         * The current layout force.
142         * 
143         * @return A real number.
144         */
145        double getForce();
146
147        /**
148         * Clears the whole nodes and edges structures
149         */
150        void clear();
151
152        /**
153         * The general "speed" of the algorithm. For some algorithm this will have
154         * no effect. For most "dynamic" algorithms, this change the way iterations
155         * toward stabilization are done.
156         * 
157         * @param value
158         *            A number in [0..1].
159         */
160        void setForce(double value);
161
162        /**
163         * Change the stabilization limit for this layout algorithm.
164         * 
165         * <p>
166         * The stabilization is a number between 0 and 1 that indicates how close to
167         * stabilization (no nodes need to move) the layout is. The value 1 means
168         * the layout is fully stabilized. Naturally this is often only an
169         * indication only, for some algorithms, it is difficult to determine if the
170         * layout is correct or acceptable enough. You can get the actual
171         * stabilization limit using {@link #getStabilizationLimit()}. You can get
172         * the actual stabilization using {@link #getStabilization()}.
173         * </p>
174         * 
175         * <p>
176         * Be careful, most layout classes do not use the stabilization limit, this
177         * number is mostly used the process that control the layout, like the
178         * {@link LayoutRunner} for example. The stabilization limit is only an
179         * indication with a default set for each layout algorithm. However this
180         * default can be changed using this method, or by storing on the graph an
181         * attribute "layout.stabilization-limit" (or "layout.stabilisation-limit").
182         * </p>
183         * 
184         * <p>
185         * The convention is that the value 0 means that the process controlling the
186         * layout will not stop the layout (will therefore not consider the
187         * stabilization limit). In other words the layout will compute endlessly.
188         * </p>
189         * 
190         * @param value
191         *            The new stabilization limit, 0 means no need to stabilize.
192         *            Else a value larger than zero or equal to 1 is accepted.
193         */
194        void setStabilizationLimit(double value);
195
196        /**
197         * Set the overall quality level, a number between 0 and 1 with 1 the
198         * highest quality available, but often with a slower computation.
199         * 
200         * @param qualityLevel
201         *            The quality level, a number between 0 and 1.
202         */
203        void setQuality(double qualityLevel);
204
205        /**
206         * If true, node informations messages are sent for every node. This is
207         * mainly for debugging and slows down the process a lot. The contents of
208         * the node information is specific to the algorithm, and sent via a
209         * specific "layout.info" attribute.
210         * 
211         * @param send
212         *            If true, send node informations to a "layout.info" attribute.
213         */
214        void setSendNodeInfos(boolean send);
215
216        /**
217         * Add a random vector whose length is 10% of the size of the graph to all
218         * node positions.
219         */
220        void shake();
221
222        /**
223         * Move a node by force to a new location. It is preferable to first freeze
224         * the node before moving it by force, and then un-freeze it.
225         * 
226         * @param id
227         *            The node identifier.
228         * @param x
229         *            The node new X.
230         * @param y
231         *            The node new Y.
232         * @param z
233         *            The node new Z.
234         */
235        void moveNode(String id, double x, double y, double z);
236
237        /**
238         * Freeze or un-freeze a node. The freezed node position will not be changed
239         * by the algorithm until un-freezed.
240         * 
241         * @param id
242         *            The node identifier.
243         * @param frozen
244         *            If true the node is frozen.
245         */
246        void freezeNode(String id, boolean frozen);
247
248        /**
249         * Method to call repeatedly to compute the layout.
250         * 
251         * <p>
252         * This method implements the layout algorithm proper. It must be called in
253         * a loop, until the layout stabilizes. You can know if the layout is stable
254         * by using the {@link #getNodeMovedCount()} method that returns the number
255         * of node that have moved during the last call to step().
256         * </p>
257         * 
258         * <p>
259         * The listener is called by this method, therefore each call to step() will
260         * also trigger layout events, allowing to reproduce the layout process
261         * graphically for example. You can insert the listener only when the layout
262         * stabilized, and then call step() anew if you do not want to observe the
263         * layout process.
264         * </p>
265         */
266        void compute();
267}