| 
 | Search this API | ||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Objecty.layout.hierarchic.AbstractDrawer
y.layout.hierarchic.PendularDrawer
public class PendularDrawer
This class implements the drawing phase of the hierarchic layout algorithm
 (that is the assignment of nodes' coordinates) as described in "Visualisierungstechniken für den Compilerbau" 
 (Georg Sander) mixed with techniques described in "A technique for drawing directed graphs"
 (Gansner et al).
 
 
| Field Summary | |
|---|---|
| protected  NodeMap | leftA NodeMapthat holds for each node anObjectrepresenting its left-hand side node in a layer 
 ornullif it is the leftmost node. | 
| protected  NodeMap | rightA NodeMapthat holds for each node anObjectrepresenting its right-hand side node in a layer 
 ornullif it is the rightmost node. | 
| Fields inherited from class y.layout.hierarchic.AbstractDrawer | 
|---|
| distanceToNextNode, dummyMap, edgeLengthKey, graph, minimalEdgeDistance, minimalLayerDistance, minimalMultiEdgeDistance, minimalNodeDistance | 
| Fields inherited from interface y.layout.hierarchic.Drawer | 
|---|
| NODE_BORDER_BOTTOM, NODE_BORDER_LEFT, NODE_BORDER_RIGHT, NODE_BORDER_TOP, NODE_DISTANCE | 
| Constructor Summary | |
|---|---|
| PendularDrawer()Creates a new instance of PendularDrawerwith default settings. | |
| Method Summary | |
|---|---|
| protected  void | assignCoordinates(NodeList[] layerLists,
                  DataProvider layerID)This is the main loop of this layout algorithm. | 
| protected  void | disposeStructures()Cleans up previously allocated structures that were constructed by a call to initStructures(). | 
| protected  YList | findChains()Finds chains of nodes, i.e., the maximum number of adjacent nodes (real ones and dummy nodes) with in-degree and out-degree 1. | 
| protected  double | getEdgeWeight(Edge edge)Returns a non-negative value representing the weight of a given edge. | 
| protected  double | getMaximumExtent(Node node,
                 boolean toLeft)Calculates the maximum or minimum x-coordinate to which a given node can be assigned without violating the constraints. | 
| protected  double | getMinimalLayerDistance(Node node,
                        boolean toLeft)Returns the minimum distance between two nodes of the same layer according to AbstractDrawer.getMinimalNodeDistance(),AbstractDrawer.getMinimalEdgeDistance()andAbstractDrawer.getMinimalMultiEdgeDistance(). | 
| protected  double | getPendulumForce(Node node,
                 EdgeCursor edges)Calculates the force applied to a given node by nodes provided by an EdgeCursorinstance. | 
| protected  double | getPendulumForce(YCursor nodes,
                 int direction)Calculates the force acting on all nodes given by the cursor. | 
| protected  double | getZ()Calculates the value of the function that this algorithm should minimize. | 
| protected  void | initializePositions(NodeList[] layerLists)Helper method which initializes the positions of the nodes of all layers. | 
| protected  void | initStructures()Initializes internal structures. | 
| protected  boolean | isSegmentNode(Node node)Determines whether or not a node is a so-called segment node. | 
| protected  void | minNode()Performs the minNodephase, i.e., a local optimization on one node at a time. | 
| protected  boolean | minPath(YList segments)Performs the minPathphase. | 
| protected  void | move(Node node,
     double distance)Moves a given node by a given distance. | 
| protected  void | move(YCursor cursor,
     double distance)Moves the nodes provided by the cursorby the given distance. | 
| protected  YList | partitionLayer(NodeList layer,
               int direction)Partitions a layer given by a NodeListby calculating the forces according to the given direction. | 
| protected  void | setLayoutGraph(LayoutGraph graph)Specifies the given graph. | 
| protected  void | shakePartition(YList partition,
               int direction)Shakes a given partition of a layer, i.e., it calculates the forces for each part of the partition and applies them if possible. | 
| protected  boolean | straightenPath(ListCell firstCell,
               ListCell lastCell,
               double[] range)Assigns the same x-coordinate to all the nodes given the first and the last cell in NodeList. | 
| protected  boolean | touches(Node node1,
        Node node2)Checks whether or not two adjacent nodes of a layer touch each other, i.e., their distance is smaller than the minimum layer distance. | 
| protected  double | verifyMovement(Node node,
               double distance)Assures that if a specific distance is applied to the x-coordinate of a given node, no given constraint will be violated. | 
| Methods inherited from class java.lang.Object | 
|---|
| clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait | 
| Field Detail | 
|---|
protected NodeMap right
NodeMap that holds for each node an Object representing its right-hand side node in a layer 
 or null if it is the rightmost node.
protected NodeMap left
NodeMap that holds for each node an Object representing its left-hand side node in a layer 
 or null if it is the leftmost node.
| Constructor Detail | 
|---|
public PendularDrawer()
PendularDrawer with default settings.
| Method Detail | 
|---|
protected void initStructures()
   This method is called first in assignCoordinates(NodeList[], DataProvider) and calculates the 
   width of the grid for the bends (based on the maximum of the minimum multi-edge distance and the minimum edge 
   distance) and the width of the grid for the nodes (based on the minimum node distance and the width of the grid 
   for bends). It also initializes the NodeMaps that hold the right(left)-hand side nodes in a layer.
 
It may be overridden for custom calculation of the width of the grid for bends or for nodes.
NodeMaps do not yet contain any values unless method 
 initializePositions(NodeList[]) is called.
protected void assignCoordinates(NodeList[] layerLists,
                                 DataProvider layerID)
partitionLayer(layerList[i] , -1)
          and shakePartition(partition,-1) for each layer in top-down order.
       partitionLayer(layerList[i] , -1) 
          and shakePartition(partition,-1) for each layer in bottom-up order.
       partitionLayer(layerList[i] , 0)
          and shakePartition(partition,0) for each layer in top-down order.
       findChains() and minPath(YList).
   Subclasses that wish to override this function to implement different behavior should
   implement a call to initStructures() and 
   initializePositions(NodeList[]) before using the provided methods.
 
   After the work is done, they should call disposeStructures().
 
assignCoordinates in class AbstractDrawerlayerLists - the array of NodeLists each of which contains nodes that belong to the same layerlayerID - the DataProvider that returns the zero-based index of the layer to which each node belongsprotected void disposeStructures()
initStructures().
 
 
   It should be called after method assignCoordinates(NodeList[], DataProvider) has assigned the node 
   coordinates. 
 
initStructures()protected boolean minPath(YList segments)
minPath phase.
 
   This method is called by assignCoordinates(NodeList[], DataProvider) as a final step and 
   tries to straighten the chains given by a list of NodeLists, by sequentially assigning
   the same x-coordinate to as many adjacent nodes of each chain as possible, without violating the constraints and 
   without changing the coordinates of the nodes in the neighborhood of each segment. It may be overridden to 
   support custom straightening of node chains.
 
segments - a list of NodeLists each containing a chain of nodes
true if a change in any coordinate of the graph has occurred, false 
         otherwisefindChains()protected YList findChains()
1.
 
   This method is called in assignCoordinates(NodeList[], DataProvider) during the 
   minPath(YList) MinPath} phase. It may be overridden for custom chain finding.
 
list of NodeLists containing each more than one nodesminPath(YList)
protected boolean straightenPath(ListCell firstCell,
                                 ListCell lastCell,
                                 double[] range)
NodeList.
 
   The x-coordinates must lie within a range determined by range. If the first value of 
   range is -Double.MAX_VALUE, the minimum distance between the nodes is used for the 
   left border. Similarly, if the second value of 
   range is Double.MAX_VALUE, the maximum distance between the nodes is used for the 
   right border.
 
   This method is called by minPath(YList) and performs the straightening of node chains. It may be overridden for
   custom implementations.
 
firstCell - the first node in a NodeList that should be assigned a new x-coordinatelastCell - the last node in a NodeList (which must refer to same list as the one for firstCell) 
 that should be assigned a new x-coordinaterange - an interval providing information of the legal range of x-coordinates that could be set
true if this method has done any change to the coordinates, false otherwiseminPath(YList)protected boolean isSegmentNode(Node node)
   A node is called segment node if (in-degree == 1 && out-degree < 2) or
   (in-degree < 2 && out-degree == 1).
 
   This method is called by findChains() method in order to distinguish the segment nodes. It may be 
   overridden for custom segment node definitions.
 
node - the given node
true if the given node is a segment node, false otherwiseprotected void minNode()
minNode phase, i.e., a local optimization on one node at a time.
 It uses a queue, which is initially filled with all nodes in the layout graph.
   For each Node n that is popped off the queue, it performs a call to:
   
force = getPendulumForce(n, n.edges)force = verifyMovement(n, force)move(n, force)If the x-coordinate of a node has changed, all its neighbors are re-queued, if not already in the queue.
   This method is called in assignCoordinates(NodeList[], DataProvider) after calling method
   partitionLayer(NodeList, int) and before minPath(YList). It may be overridden for custom 
   implementations.
 
protected void shakePartition(YList partition,
                              int direction)
It uses the functionality of the following methods:
   This method is called by assignCoordinates(NodeList[], DataProvider) after 
   a layer has been partitioned and may be overridden for custom 
   implementations.
 
partition - a YList of NodeLists each containing at least one node
 belonging to a single layerdirection - -1 if nodes in higher layers should be used for calculating
 the forces, 1 if nodes in lower layers should be used, 0 if both
 surrounding layers should be usedpartitionLayer(NodeList,int), 
getPendulumForce(YCursor, int)
protected YList partitionLayer(NodeList layer,
                               int direction)
NodeList by calculating the forces according to the given direction.
 
   It is intended to be used with shakePartition(YList, int) method.
 
   This method is called in assignCoordinates(NodeList[], DataProvider) during:
   
partitionLayer(layerList[i] , -1) for each layer in top-down order.partitionLayer(layerList[i] , -1) for each layer in bottom-up order.partitionLayer(layerList[i] , 0) for each layer in top-down order.It may be overridden for custom implementations.
layer - the NodeList containing the nodes of a single layerdirection - -1 if nodes in higher layers should be used for calculating
 the forces, 1 if nodes in lower layers should be used, 0 if both
 surrounding layers should be used
NodeLists each containing adjacent nodes of a given layer,
 which can be treated as a single unit when movinggetPendulumForce(YCursor, int), 
touches(Node, Node), 
shakePartition(YList, int)protected void setLayoutGraph(LayoutGraph graph)
graph - the graph
protected double getPendulumForce(Node node,
                                  EdgeCursor edges)
EdgeCursor instance.
 
   This method is called by minNode() and getPendulumForce(YCursor, int) to calculate the force as 
   the sum of the weighted differences of the x-coordinates. It may be overridden for custom calculations of the 
   force on every node.
 
node - the given node for which the force will be calculatededges - the EdgeCursor instance which determines which edges should be considered for the calculation
v) would minimize, if applied,
 the force on vgetEdgeWeight(Edge)
protected boolean touches(Node node1,
                          Node node2)
minimum layer distance.
 
 
   This method is called in partitionLayer(NodeList, int) when the forces are calculated and checks whether 
   or not the distance between two nodes is smaller than the minimum layer distance.
   It may be overridden if a different calculation of touching nodes is needed.
 
node1 - the first nodenode2 - the second node
true if the distance is smaller than the minimum layer distance, 
         false otherwisegetMinimalLayerDistance(Node,boolean)
protected double verifyMovement(Node node,
                                double distance)
   It makes extensive use of getMinimalLayerDistance(Node, boolean)
 
   This method is called in minNode() after the getPendulumForce(YCursor, int) is calculated.
   It may be overridden for custom verifications of the node movement.
 
node - the given node to be moveddistance - the distance which should be verified
getMinimalLayerDistance(Node,boolean)
protected double getPendulumForce(YCursor nodes,
                                  int direction)
cursor.
 
   This method is called by shakePartition(YList, int) to return the sum of the results of calls to 
   getPendulumForce(Node, EdgeCursor) divided by the number of the nodes.
 
nodes - the nodes for which the force will be calculateddirection - -1 if nodes in higher layers should be used for calculating
 the forces, 1 if nodes in lower layers should be used, 0 if both
 surrounding layers should be used
cursor, 
 would minimize the force acting on them
protected void move(Node node,
                    double distance)
   This method is called in minNode() after the force of each node has been calculated. It is also called
   by move(YCursor, double) in order to move the nodes provided by the YCursor by the given 
   distance. 
 
For the movement, the distance and the width of the grid size for nodes and bends are taken into consideration. It may be overridden for custom calculation of the nodes' positions.
node - the given nodedistance - the distance by which the x-coordinate should be modified
protected void move(YCursor cursor,
                    double distance)
cursor by the given distance.
 
   This method in turn calls move(Node, double) to delegate its work. It is called by 
   shakePartition(YList, int) after the movement of the nodes based on the calculated forces is 
   verified.
 
cursor - the nodes to be moveddistance - the distance by which the x-coordinate should be modifiedmove(Node,double)protected double getZ()
protected double getEdgeWeight(Edge edge)
In this implementation:
1.segmentEndFactor * 1.segmentFactor * 1.
 One could implement edge weights by supplying an EdgeMap that maps a non-negative double value for 
 each edge.
 
edge - the given edge
protected double getMaximumExtent(Node node,
                                  boolean toLeft)
node - the given nodetoLeft - true if the minimum x-coordinate should be calculated; 
               false if the maximum x-coordinate should be calculated
protected double getMinimalLayerDistance(Node node,
                                         boolean toLeft)
AbstractDrawer.getMinimalNodeDistance(),AbstractDrawer.getMinimalEdgeDistance() and AbstractDrawer.getMinimalMultiEdgeDistance().
node - the given nodetoLeft - true if the minimum x-coordinate should be calculated; 
               false if the maximum x-coordinate should be calculated
AbstractDrawer.getMinimalMultiEdgeDistance(), 
AbstractDrawer.getMinimalNodeDistance(), 
AbstractDrawer.getMinimalEdgeDistance()protected void initializePositions(NodeList[] layerLists)
   This method respects getMinimalLayerDistance(Node,boolean) and compacts the graph to the 
   leftmost position (0).
 
layerLists - an array of NodeLists each containing nodes that belong to the same layer| 
 | © Copyright 2000-2025, yWorks GmbH. All rights reserved. | ||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||