| 
 | JGraph X 1.4.1.0 | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectcom.mxgraph.layout.mxGraphLayout
com.mxgraph.layout.mxOrganicLayout
public class mxOrganicLayout
An implementation of a simulated annealing layout, based on "Drawing Graphs Nicely Using Simulated Annealing" by Davidson and Harel (1996). This paper describes these criteria as being favourable in a graph layout: (1) distributing nodes evenly, (2) making edge-lengths uniform, (3) minimizing cross-crossings, and (4) keeping nodes from coming too close to edges. These criteria are translated into energy cost functions in the layout. Nodes or edges breaking these criteria create a larger cost function , the total cost they contribute related to the extent that they break it. The idea of the algorithm is to minimise the total system energy. Factors are assigned to each of the criteria describing how important that criteria is. Higher factors mean that those criteria are deemed to be relatively preferable in the final layout. Most of the criteria conflict with the others to some extent and so the setting of the factors determines the general look of the resulting graph.
 In addition to the four aesthetic criteria the concept of a border line
 which induces an energy cost to nodes in proximity to the graph bounds is
 introduced to attempt to restrain the graph. All of the 5 factors can be
 switched on or off using the isOptimize... variables.
 
Simulated Annealing is a force-directed layout and is one of the more expensive, but generally effective layouts of this type. Layouts like the spring layout only really factor in edge length and inter-node distance being the lowest CPU intensive for the most aesthetic gain. The additional factors are more expensive but can have very attractive results.
 The main loop of the algorithm consist of processing the nodes in a 
 deterministic order. During the processing of each node a circle of radius
 moveRadius is made around the node and split into
 triesPerCell equal segments. Each point between neighbour
 segments is determined and the new energy of the system if the node were
 moved to that position calculated. Only the necessary nodes and edges are
 processed new energy values resulting in quadratic performance, O(VE),
 whereas calculating the total system energy would be cubic. The default
 implementation only checks 8 points around the radius of the circle, as
 opposed to the suggested 30 in the paper. Doubling the number of points
 double the CPU load and 8 works almost as well as 30.
 
 The moveRadius replaces the temperature as the influencing
 factor in the way the graph settles in later iterations. If the user does
 not set the initial move radius it is set to half the maximum dimension
 of the graph. Thus, in 2 iterations a node may traverse the entire graph,
 and it is more sensible to find minima this way that uphill moves, which
 are little more than an expensive 'tilt' method. The factor by which
 the radius is multiplied by after each iteration is important, lowering
 it improves performance but raising it towards 1.0 can improve the
 resulting graph aesthetics. When the radius hits the minimum move radius
 defined, the layout terminates. The minimum move radius should be set
 a value where the move distance is too minor to be of interest.
 
 Also, the idea of a fine tuning phase is used, as described in the paper.
 This involves only calculating the edge to node distance energy cost
 at the end of the algorithm since it is an expensive calculation and
 it really an 'optimizating' function. fineTuningRadius
 defines the radius value that, when reached, causes the edge to node
 distance to be calculated.
 
 There are other special cases that are processed after each iteration.
 unchangedEnergyRoundTermination defines the number of
 iterations, after which the layout terminates. If nothing is being moved
 it is assumed a good layout has been found. In addition to this if
 no nodes are moved during an iteration the move radius is halved, presuming
 that a finer granularity is required.
| Nested Class Summary | |
|---|---|
|  class | mxOrganicLayout.CellWrapperInternal representation of a node or edge that holds cached information to enable the layout to perform more quickly and to simplify the code | 
| Field Summary | |
|---|---|
| protected  boolean | approxNodeDimensionsWhether or not to use approximate node dimensions or not. | 
| protected  double | averageNodeAreaThe average amount of area allocated per node. | 
| protected  double | borderLineCostFactorCost factor applied to energy calculations for node promixity to the notional border of the graph. | 
| protected  double | boundsHeightThe height coordinate of the final graph | 
| protected  double | boundsWidthThe width coordinate of the final graph | 
| protected  double | boundsXThe x coordinate of the final graph | 
| protected  double | boundsYThe y coordinate of the final graph | 
| protected  mxOrganicLayout.CellWrapper[] | eInternal models collection of edges to be laid out | 
| protected  double | edgeCrossingCostFactorCost factor applied to energy calculations involving edges that cross over one another. | 
| protected  double | edgeDistanceCostFactorCost factor applied to energy calculations involving the distance nodes and edges. | 
| protected  double | edgeLengthCostFactorCost factor applied to energy calculations for the edge lengths. | 
| protected  double | fineTuningRadiusThe radius below which fine tuning of the layout should start This involves allowing the distance between nodes and edges to be taken into account in the total energy calculation. | 
| protected  double | initialMoveRadiusThe initial value of moveRadius. | 
| protected  boolean | isFineTuningWhether or not fine tuning is on. | 
| protected  boolean | isOptimizeBorderLineWhether or not nodes will contribute an energy cost as they approach the bound of the graph. | 
| protected  boolean | isOptimizeEdgeCrossingWhether or not edges crosses will be calculated as an energy cost function. | 
| protected  boolean | isOptimizeEdgeDistanceWhether or not the distance between edge and nodes will be calculated as an energy cost function. | 
| protected  boolean | isOptimizeEdgeLengthWhether or not edge lengths will be calculated as an energy cost function. | 
| protected  boolean | isOptimizeNodeDistributionWhether or not node distribute will contribute an energy cost where nodes are close together. | 
| protected  int | iterationcurrent iteration number of the layout | 
| protected  double | maxDistanceLimitdistance limit beyond which energy costs due to object repulsive is not calculated as it would be too insignificant | 
| protected  double | maxDistanceLimitSquaredcached version of maxDistanceLimitsquared | 
| protected  int | maxIterationsLimit to the number of iterations that may take place. | 
| protected  double | minDistanceLimitprevents from dividing with zero and from creating excessive energy values | 
| protected  double | minDistanceLimitSquaredcached version of minDistanceLimitsquared | 
| protected  double | minMoveRadiuswhen moveRadiusreaches this value, the algorithm is terminated | 
| protected  double | moveRadiusThe current radius around each node where the next position energy values will be calculated for a possible move | 
| protected  double | nodeDistributionCostFactorCost factor applied to energy calculations involving the general node distribution of the graph. | 
| protected  double | radiusScaleFactorThe factor by which the moveRadiusis multiplied by after
 every iteration. | 
| protected  int | triesPerCelldetermines, in how many segments the circle around cells is divided, to find a new position for the cell. | 
| protected  int | unchangedEnergyRoundCountKeeps track of how many consecutive round have passed without any energy changes | 
| protected  int | unchangedEnergyRoundTerminationThe number of round of no node moves taking placed that the layout terminates | 
| protected  mxOrganicLayout.CellWrapper[] | vInternal models collection of nodes ( vertices ) to be laid out | 
| protected  double[] | xNormTryArray of the x portion of the normalised test vectors that are tested for a lower energy around each vertex. | 
| protected  double[] | yNormTryArray of the y portion of the normalised test vectors that are tested for a lower energy around each vertex. | 
| Fields inherited from class com.mxgraph.layout.mxGraphLayout | 
|---|
| graph, useBoundingBox | 
| Constructor Summary | |
|---|---|
| mxOrganicLayout(mxGraph graph)Constructor for mxOrganicLayout. | |
| mxOrganicLayout(mxGraph graph,
                Rectangle2D bounds)Constructor for mxOrganicLayout. | |
| Method Summary | |
|---|---|
| protected  double | calcEnergyDelta(int index,
                double oldNodeDistribution,
                double oldEdgeDistance,
                double oldEdgeCrossing,
                double oldBorderLine,
                double oldEdgeLength,
                double oldAdditionalFactorsEnergy)Calculates the change in energy for the specified node. | 
|  void | execute(Object parent)Implements | 
| protected  double | getAdditionFactorsEnergy(int i)Hook method to adding additional energy factors into the layout. | 
|  double | getAverageNodeArea() | 
| protected  double | getBorderline(int i)This method calculates the energy of the distance of the specified node to the notional border of the graph. | 
|  double | getBorderLineCostFactor() | 
| protected  int[] | getConnectedEdges(int cellIndex)Returns all Edges that are connected with the specified cell | 
| protected  double | getEdgeCrossing(int i)This method calculates the energy of the distance from the specified edge crossing any other edges. | 
| protected  double | getEdgeCrossingAffectedEdges(int node)Obtains the energy cost function for the specified node being moved. | 
|  double | getEdgeCrossingCostFactor() | 
| protected  double | getEdgeDistanceAffectedNodes(int node)Obtains the energy cost function for the specified node being moved. | 
|  double | getEdgeDistanceCostFactor() | 
| protected  double | getEdgeDistanceFromEdge(int i)This method calculates the energy of the distance between Cells and Edges. | 
| protected  double | getEdgeDistanceFromNode(int i)This method calculates the energy of the distance between Cells and Edges. | 
| protected  double | getEdgeLength(int i)This method calculates the energy due to the length of the specified edge. | 
| protected  double | getEdgeLengthAffectedEdges(int node)Obtains the energy cost function for the specified node being moved. | 
|  double | getEdgeLengthCostFactor() | 
|  double | getFineTuningRadius() | 
|  double | getInitialMoveRadius() | 
|  double | getMaxDistanceLimit() | 
|  int | getMaxIterations() | 
|  double | getMinDistanceLimit() | 
|  double | getMinMoveRadius() | 
| protected  double | getNodeDistribution(int i)Calculates the energy cost of the specified node relative to all other nodes. | 
|  double | getNodeDistributionCostFactor() | 
|  double | getRadiusScaleFactor() | 
| protected  int[] | getRelevantEdges(int cellIndex)Returns all Edges that are not connected to the specifed cell | 
|  int | getTriesPerCell() | 
|  int | getUnchangedEnergyRoundTermination() | 
|  boolean | isApproxNodeDimensions() | 
|  boolean | isFineTuning() | 
|  boolean | isOptimizeBorderLine() | 
|  boolean | isOptimizeEdgeCrossing() | 
|  boolean | isOptimizeEdgeDistance() | 
|  boolean | isOptimizeEdgeLength() | 
|  boolean | isOptimizeNodeDistribution() | 
|  boolean | isVertexIgnored(Object vertex)Returns true if the given vertex has no connected edges. | 
| protected  void | performRound()The main round of the algorithm. | 
|  void | setApproxNodeDimensions(boolean approxNodeDimensions) | 
|  void | setAverageNodeArea(double averageNodeArea) | 
|  void | setBorderLineCostFactor(double borderLineCostFactor) | 
|  void | setEdgeCrossingCostFactor(double edgeCrossingCostFactor) | 
|  void | setEdgeDistanceCostFactor(double edgeDistanceCostFactor) | 
|  void | setEdgeLengthCostFactor(double edgeLengthCostFactor) | 
|  void | setFineTuning(boolean isFineTuning) | 
|  void | setFineTuningRadius(double fineTuningRadius) | 
|  void | setInitialMoveRadius(double initialMoveRadius) | 
|  void | setMaxDistanceLimit(double maxDistanceLimit) | 
|  void | setMaxIterations(int maxIterations) | 
|  void | setMinDistanceLimit(double minDistanceLimit) | 
|  void | setMinMoveRadius(double minMoveRadius) | 
|  void | setNodeDistributionCostFactor(double nodeDistributionCostFactor) | 
|  void | setOptimizeBorderLine(boolean isOptimizeBorderLine) | 
|  void | setOptimizeEdgeCrossing(boolean isOptimizeEdgeCrossing) | 
|  void | setOptimizeEdgeDistance(boolean isOptimizeEdgeDistance) | 
|  void | setOptimizeEdgeLength(boolean isOptimizeEdgeLength) | 
|  void | setOptimizeNodeDistribution(boolean isOptimizeNodeDistribution) | 
|  void | setRadiusScaleFactor(double radiusScaleFactor) | 
|  void | setTriesPerCell(int triesPerCell) | 
|  void | setUnchangedEnergyRoundTermination(int unchangedEnergyRoundTermination) | 
|  String | toString()Returns Organic, the name of this algorithm. | 
| Methods inherited from class com.mxgraph.layout.mxGraphLayout | 
|---|
| getConstraint, getConstraint, getGraph, getVertexBounds, isEdgeIgnored, isUseBoundingBox, isVertexMovable, moveCell, setEdgePoints, setEdgeStyleEnabled, setUseBoundingBox, setVertexLocation | 
| Methods inherited from class java.lang.Object | 
|---|
| clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait | 
| Field Detail | 
|---|
protected boolean isOptimizeEdgeDistance
protected boolean isOptimizeEdgeCrossing
protected boolean isOptimizeEdgeLength
protected boolean isOptimizeBorderLine
protected boolean isOptimizeNodeDistribution
protected double minMoveRadius
moveRadiusreaches this value, the algorithm is terminated
protected double moveRadius
protected double initialMoveRadius
moveRadius. If this is set to zero
 the layout will automatically determine a suitable value.
protected double radiusScaleFactor
moveRadius is multiplied by after
 every iteration. A value of 0.75 is a good balance between performance
 and aesthetics. Increasing the value provides more chances to find
 minimum energy positions and decreasing it causes the minimum radius
 termination condition to occur more quickly.
protected double averageNodeArea
 bounds
 is not set this value mutiplied by the number of nodes to find
 the total graph area. The graph is assumed square.
protected double fineTuningRadius
protected int maxIterations
protected double edgeDistanceCostFactor
isOptimizeEdgeDistance must be true for edge to nodes
 distances to be taken into account.
protected double edgeCrossingCostFactor
isOptimizeEdgeCrossing must be true for edge crossings
 to be taken into account.
protected double nodeDistributionCostFactor
isOptimizeNodeDistribution must be true for this general
 distribution to be applied.
protected double borderLineCostFactor
isOptimizeBorderLine must be true for border
 repulsion to be applied.
protected double edgeLengthCostFactor
isOptimizeEdgeLength must be true for edge length
 shortening to be applied.
protected double boundsX
protected double boundsY
protected double boundsWidth
protected double boundsHeight
protected int iteration
protected int triesPerCell
performRound method might further improve accuracy for a
 small performance hit. The change is described in the method comment.
protected double minDistanceLimit
protected double minDistanceLimitSquared
minDistanceLimit squared
protected double maxDistanceLimit
protected double maxDistanceLimitSquared
maxDistanceLimit squared
protected int unchangedEnergyRoundCount
protected int unchangedEnergyRoundTermination
protected boolean approxNodeDimensions
protected mxOrganicLayout.CellWrapper[] v
protected mxOrganicLayout.CellWrapper[] e
protected double[] xNormTry
protected double[] yNormTry
protected boolean isFineTuning
isFineTuning is switched to
 true if and when the fineTuningRadius
 radius is reached. Switching this variable to true
 before the algorithm runs mean the node to edge cost function
 is always calculated.
| Constructor Detail | 
|---|
public mxOrganicLayout(mxGraph graph)
public mxOrganicLayout(mxGraph graph,
                       Rectangle2D bounds)
| Method Detail | 
|---|
public boolean isVertexIgnored(Object vertex)
isVertexIgnored in class mxGraphLayoutvertex - Object that represents the vertex to be tested.
public void execute(Object parent)
parent - Parent cell that contains the children to be layed out.protected void performRound()
moveRadius are
 selected and the total energy of the system calculated if that node
 were moved to that new position. If a lower energy position is found
 this is accepted and the algorithm moves onto the next node. There
 may be a slightly lower energy value yet to be found, but forcing
 the loop to check all possible positions adds nearly the current
 processing time again, and for little benefit. Another possible
 strategy would be to take account of the fact that the energy values
 around the circle decrease for half the loop and increase for the
 other, as a general rule. If part of the decrease were seen, then
 when the energy of a node increased, the previous node position was
 almost always the lowest energy position. This adds about two loop
 iterations to the inner loop and only makes sense with 16 tries or more.
protected double calcEnergyDelta(int index,
                                 double oldNodeDistribution,
                                 double oldEdgeDistance,
                                 double oldEdgeCrossing,
                                 double oldBorderLine,
                                 double oldEdgeLength,
                                 double oldAdditionalFactorsEnergy)
index - The index of the node in the vertices arrayoldNodeDistribution - The previous node distribution energy cost of this nodeoldEdgeDistance - The previous edge distance energy cost of this nodeoldEdgeCrossing - The previous edge crossing energy cost for edges connected to
            this nodeoldBorderLine - The previous border line energy cost for this nodeoldEdgeLength - The previous edge length energy cost for edges connected to
            this nodeoldAdditionalFactorsEnergy - The previous energy cost for additional factors from
            sub-classes
protected double getNodeDistribution(int i)
i - the index of the node in the array v
protected double getBorderline(int i)
i - the index of the node in the array v
protected double getEdgeLengthAffectedEdges(int node)
getEdgeLength for all
 edges connected to the specified node
node - the node whose connected edges cost functions are to be
                                calculated
protected double getEdgeLength(int i)
i - the index of the edge in the array e
protected double getEdgeCrossingAffectedEdges(int node)
getEdgeCrossing for all
 edges connected to the specified node
node - the node whose connected edges cost functions are to be
                                calculated
protected double getEdgeCrossing(int i)
i - the index of the edge in the array e
protected double getEdgeDistanceFromNode(int i)
i - the index of the node in the array v
protected double getEdgeDistanceAffectedNodes(int node)
getEdgeDistanceFromEdge for all
 edges connected to the specified node
node - the node whose connected edges cost functions are to be
                                calculated
protected double getEdgeDistanceFromEdge(int i)
i - the index of the edge in the array e
protected double getAdditionFactorsEnergy(int i)
i - the nodes whose energy is being calculated
protected int[] getRelevantEdges(int cellIndex)
cellIndex - the cell index to which the edges are not connected
protected int[] getConnectedEdges(int cellIndex)
cellIndex - the cell index to which the edges are connected
public String toString()
Organic, the name of this algorithm.
toString in class Objectpublic double getAverageNodeArea()
public void setAverageNodeArea(double averageNodeArea)
averageNodeArea - The averageNodeArea to set.public double getBorderLineCostFactor()
public void setBorderLineCostFactor(double borderLineCostFactor)
borderLineCostFactor - The borderLineCostFactor to set.public double getEdgeCrossingCostFactor()
public void setEdgeCrossingCostFactor(double edgeCrossingCostFactor)
edgeCrossingCostFactor - The edgeCrossingCostFactor to set.public double getEdgeDistanceCostFactor()
public void setEdgeDistanceCostFactor(double edgeDistanceCostFactor)
edgeDistanceCostFactor - The edgeDistanceCostFactor to set.public double getEdgeLengthCostFactor()
public void setEdgeLengthCostFactor(double edgeLengthCostFactor)
edgeLengthCostFactor - The edgeLengthCostFactor to set.public double getFineTuningRadius()
public void setFineTuningRadius(double fineTuningRadius)
fineTuningRadius - The fineTuningRadius to set.public double getInitialMoveRadius()
public void setInitialMoveRadius(double initialMoveRadius)
initialMoveRadius - The initialMoveRadius to set.public boolean isFineTuning()
public void setFineTuning(boolean isFineTuning)
isFineTuning - The isFineTuning to set.public boolean isOptimizeBorderLine()
public void setOptimizeBorderLine(boolean isOptimizeBorderLine)
isOptimizeBorderLine - The isOptimizeBorderLine to set.public boolean isOptimizeEdgeCrossing()
public void setOptimizeEdgeCrossing(boolean isOptimizeEdgeCrossing)
isOptimizeEdgeCrossing - The isOptimizeEdgeCrossing to set.public boolean isOptimizeEdgeDistance()
public void setOptimizeEdgeDistance(boolean isOptimizeEdgeDistance)
isOptimizeEdgeDistance - The isOptimizeEdgeDistance to set.public boolean isOptimizeEdgeLength()
public void setOptimizeEdgeLength(boolean isOptimizeEdgeLength)
isOptimizeEdgeLength - The isOptimizeEdgeLength to set.public boolean isOptimizeNodeDistribution()
public void setOptimizeNodeDistribution(boolean isOptimizeNodeDistribution)
isOptimizeNodeDistribution - The isOptimizeNodeDistribution to set.public int getMaxIterations()
public void setMaxIterations(int maxIterations)
maxIterations - The maxIterations to set.public double getMinDistanceLimit()
public void setMinDistanceLimit(double minDistanceLimit)
minDistanceLimit - The minDistanceLimit to set.public double getMinMoveRadius()
public void setMinMoveRadius(double minMoveRadius)
minMoveRadius - The minMoveRadius to set.public double getNodeDistributionCostFactor()
public void setNodeDistributionCostFactor(double nodeDistributionCostFactor)
nodeDistributionCostFactor - The nodeDistributionCostFactor to set.public double getRadiusScaleFactor()
public void setRadiusScaleFactor(double radiusScaleFactor)
radiusScaleFactor - The radiusScaleFactor to set.public int getTriesPerCell()
public void setTriesPerCell(int triesPerCell)
triesPerCell - The triesPerCell to set.public int getUnchangedEnergyRoundTermination()
public void setUnchangedEnergyRoundTermination(int unchangedEnergyRoundTermination)
unchangedEnergyRoundTermination - The unchangedEnergyRoundTermination to set.public double getMaxDistanceLimit()
public void setMaxDistanceLimit(double maxDistanceLimit)
maxDistanceLimit - The maxDistanceLimit to set.public boolean isApproxNodeDimensions()
public void setApproxNodeDimensions(boolean approxNodeDimensions)
approxNodeDimensions - the approxNodeDimensions to set| 
 | JGraph X 1.4.1.0 | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||