Packagecom.yworks.yfiles.layout.hierarchic
Classpublic class PendularDrawer
InheritancePendularDrawer Inheritance AbstractDrawer Inheritance YObject Inheritance Object

This class implements the third phase of the Sugiyama layout algorithm as described in "Visualisierungstechniken für den Compilerbau" (Georg Sander) mixed with techniques as described in "A technique for drawing directed graphs" (Gansner et al).



Public Properties
 PropertyDefined By
 InheriteddummyMap : NodeMap
[write-only] Gives the drawer the opportunity to distinguish between dummy nodes and real ones.
AbstractDrawer
 InheritededgeLengthKey : Object
[write-only] Set the key to the data provider, which stores the length of the edges.
AbstractDrawer
 InheritedgraphInternal : LayoutGraph
[read-only]
AbstractDrawer
 InheritedminimalEdgeDistance : Number
Specifies the minimal distance between two edges in the same layer.
AbstractDrawer
 InheritedminimalLayerDistance : Number
Specifies the minimal distance between two layers.
AbstractDrawer
 InheritedminimalMultiEdgeDistance : Number
Specifies the minimal distance between two edges sharing source/target in the same layer.
AbstractDrawer
 InheritedminimalNodeDistance : Number
Specifies the minimal distance between two nodes in the same layer.
AbstractDrawer
Protected Properties
 PropertyDefined By
 InheriteddistanceToNextNode : NodeMap
Stores the minimal distance between the right border of a node and the left border of its right hand side neighbor in a layer.
AbstractDrawer
 Inherited_dummyMap : NodeMap
See dummyMap
AbstractDrawer
 Inherited_edgeLengthKey : Object
The key to the data provider, which stores the length of the edges.
AbstractDrawer
 Inheritedgraph : LayoutGraph
The graph bound to this drawer instance.
AbstractDrawer
  layoutGraph : LayoutGraph
[write-only]
PendularDrawer
  left : NodeMap
map that maps the left node for each node in a layer or null if it is the leftmost
PendularDrawer
 Inherited_minimalEdgeDistance : Number
The minimal distance between two edges in the same layer.
AbstractDrawer
 Inherited_minimalLayerDistance : Number
The minimal distance between two layers.
AbstractDrawer
 Inherited_minimalMultiEdgeDistance : Number
The minimal distance between two edges sharing source/target in the same layer.
AbstractDrawer
 Inherited_minimalNodeDistance : Number
The minimal distance between two nodes in the same layer.
AbstractDrawer
  right : NodeMap
map that maps the right node for each node in a layer or null if it is the rightmost
PendularDrawer
Public Methods
 MethodDefined By
  
PendularDrawer(init:Boolean = true)
empty constructor, does nothing
PendularDrawer
 Inherited
assignCoordinates(g:LayoutGraph, layerLists:Vector.<Object>, layerID:DataProvider):void
Binds the specified graph to this drawer and calls the abstract method assignFinalCoordinates()
AbstractDrawer
 Inherited
assignYCoords(graph:LayoutGraph, layerLists:Vector.<Object>):void
Assign the y coordinates to the nodes respecting the minimal layer distance.
AbstractDrawer
 Inherited
assignYCoords2(graph:LayoutGraph, layers:Vector.<Object>):void
Assign the y coordinates to the nodes respecting the minimal layer distance.
AbstractDrawer
 Inherited
equals(o:Object):Boolean
YObject
 Inherited
Returns the height of the bottom border of the given node.
AbstractDrawer
 Inherited
Returns the height of the border-obeying bottom half of the node,
AbstractDrawer
 Inherited
getBottomY(v:Node):Number
Returns the border obeying bottom y-coordinate of the given node.
AbstractDrawer
  
getClass():Class
[override]
PendularDrawer
 Inherited
Returns the border obeying full height of the given node.
AbstractDrawer
 Inherited
getFullWidth(v:Node):Number
Returns the border obeying full width of the given node.
AbstractDrawer
 Inherited
Returns the width of the left border of the given node.
AbstractDrawer
 Inherited
getLeftHalf(v:Node):Number
Returns the width of the border-obeying left half of the node,
AbstractDrawer
 Inherited
getLeftX(v:Node):Number
Returns the border obeying left x-coordinate of the given node.
AbstractDrawer
 Inherited
Returns the width of the right border of the given node.
AbstractDrawer
 Inherited
getRightHalf(v:Node):Number
Returns the width of the border-obeying right half of the node,
AbstractDrawer
 Inherited
getRightX(v:Node):Number
Returns the border obeying right x-coordinate of the given node.
AbstractDrawer
 Inherited
getTopBorder(v:Node):Number
Returns the height of the top border of the given node.
AbstractDrawer
 Inherited
getTopHalf(v:Node):Number
Returns the height of the border-obeying top half of the node,
AbstractDrawer
 Inherited
getTopY(v:Node):Number
Returns the border obeying top y-coordinate of the given node.
AbstractDrawer
 Inherited
hashCode():int
YObject
  
[static] empty constructor, does nothing
PendularDrawer
Protected Methods
 MethodDefined By
  
assignFinalCoordinates(layerLists:Vector.<Object>, layerID:DataProvider):void
[override] This is the main loop of this layout algorithm.
PendularDrawer
 Inherited
dispose():void
Frees allocated resources after the drawer is finished.
AbstractDrawer
  
Cleans up previously allocated structures, that were constructed by a call to initStructures
PendularDrawer
  
Finds chains of nodes, i.e.
PendularDrawer
 Inherited
Returns the minimal distance between the right border of the given node and the left border of its right hand side neighbor in the layer.
AbstractDrawer
  
Returns a non-negative value for each Edge e.
PendularDrawer
  
getMaximumExtent(n:Node, toLeft:Boolean):Number
Calculates the highest or lowest x-coordinate the Node n can be assigned to, without breaking the constraints.
PendularDrawer
  
getMinimalLayerDistance(n:Node, toLeft:Boolean):Number
Returns the minimum distance between two Nodes on the same layer according to getMinimalNodeDistance(), getMinimalEdgeDistance() and getMinimalMultiEdgeDistance().
PendularDrawer
  
getPendulumForce(cursor:YCursor, direction:int):Number
Helper method which calculates the force acting on all nodes given by the cursor.
PendularDrawer
  
Helper method which calculates the force that all nodes given by EdgeCursor apply to v.
PendularDrawer
  
getZ():Number
Calculates the value of the function this algorithm should minimize.
PendularDrawer
 Inherited
AbstractDrawer
 Inherited
initializeDistancesToNextNode(layerLists:Vector.<Object>):void
Initializes the minimal distances between the right border of a node and the left border of its right hand side neighbor in a layer.
AbstractDrawer
  
initializePositions(layerList:Vector.<Object>):void
Helper method which initializes the positions of the nodes in all layers.
PendularDrawer
  
Initializes this object.
PendularDrawer
  
used to initialize internal structures such as NodeMap right and NodeMap left bendGridWidth and nodeGridWidth.
PendularDrawer
  
isSegmentNode(n:Node):Boolean
Helper method that determines whether a node is a so-called segment node.
PendularDrawer
  
minNode():void
Performs the minNode phase.
PendularDrawer
  
minPath(segments:YList):Boolean
Performs the minPath phase.
PendularDrawer
  
move(n:Node, distance:Number):void
Helper method which moves a given node by a given amount if the useGrid is set to true, this method will snap the new node position to the appropriate grid, i.e.
PendularDrawer
  
moveMultiple(nodes:YCursor, distance:Number):void
Helper method which moves the nodes provided by the Cursor nodes by the given amount.
PendularDrawer
  
partitionLayer(layer:NodeList, direction:int):YList
Partitions a layer given by its NodeList by calculating the forces according to the given direction.
PendularDrawer
  
shakePartition(partition:YList, direction:int):void
Shakes a given partition of a Layer, i.e.
PendularDrawer
  
straightenPath(firstCell:ListCell, lastCell:ListCell, range:Vector.<Number>):Boolean
Helper method for use in minPath.
PendularDrawer
  
touches(v1:Node, v2:Node):Boolean
Helper method which checks whether two adjacent nodes on a layer touch each other, i.e.
PendularDrawer
  
verifyMovement(n:Node, distance:Number):Number
Assures that if distance was applied to the n's x-coordinate no given constraint gets broken.
PendularDrawer
Property Detail
layoutGraphproperty
layoutGraph:LayoutGraph  [write-only]


Implementation
    protected function set layoutGraph(value:LayoutGraph):void
leftproperty 
protected var left:NodeMap

map that maps the left node for each node in a layer or null if it is the leftmost

rightproperty 
protected var right:NodeMap

map that maps the right node for each node in a layer or null if it is the rightmost

Constructor Detail
PendularDrawer()Constructor
public function PendularDrawer(init:Boolean = true)

empty constructor, does nothing

Parameters
init:Boolean (default = true) — An internally used switch to help handle proper instance initialization in inheritance chains where classes can have multiple constructor-like factory methods. This parameter can safely be ignored/omitted when calling the constructor.
Method Detail
assignFinalCoordinates()method
override protected function assignFinalCoordinates(layerLists:Vector.<Object>, layerID:DataProvider):void

This is the main loop of this layout algorithm. For now it does the following loop:

Subclasses that wish to override this function to implement different behaviour should implement a call to initStructures() and initializePositions(layerLists) before using the provided methods. After the work is done, they should call disposeStructures(g).

Parameters

layerLists:Vector.<Object> — a list of all the nodes for each layer, to determine their relative positions
 
layerID:DataProvider

disposeStructures()method 
protected function disposeStructures():void

Cleans up previously allocated structures, that were constructed by a call to initStructures

See also

findChains()method 
protected function findChains():YList

Finds chains of nodes, i.e. maximum number of adjacent nodes (real ones and dummy nodes) have indegree and outdegree 1.

Returns
YList — a list of NodeLists containing each more than 1 nodes

See also

getClass()method 
override public function getClass():Class

Returns
Class
getEdgeWeight()method 
protected function getEdgeWeight(e:Edge):Number

Returns a non-negative value for each Edge e. In this implementation edges between two real nodes result in an edge weight of 1. Edges between one dummy and one real node result in an edge weight of segmentEndFactor * 1. Edges between two dummy nodes get an edge weight of segmentFactor * 1. One could implement edge weights by supplying an EdgeMap mapping a non-negative numeric value for each edge.

Parameters

e:Edge — the edge

Returns
Number — a non-negative value
getMaximumExtent()method 
protected function getMaximumExtent(n:Node, toLeft:Boolean):Number

Calculates the highest or lowest x-coordinate the Node n can be assigned to, without breaking the constraints.

Parameters

n:Node — the node
 
toLeft:Booleantrue if the minimum x-coordinate shall be calculated; false for the maximum x-coordinate

Returns
Number — the maximum/minimum extent of the node's center x-coordinate
getMinimalLayerDistance()method 
protected function getMinimalLayerDistance(n:Node, toLeft:Boolean):Number

Returns the minimum distance between two Nodes on the same layer according to getMinimalNodeDistance(), getMinimalEdgeDistance() and getMinimalMultiEdgeDistance().

Parameters

n:Node — the node
 
toLeft:Booleantrue if the minimum x-coordinate shall be calculated; false for the maximum x-coordinate

Returns
Number — the maximum/minimum extent of the node's center x-coordinate

See also

getPendulumForce()method 
protected function getPendulumForce(cursor:YCursor, direction:int):Number

Helper method which calculates the force acting on all nodes given by the cursor. The force is calculated by the sum of the results of calls to getPendulumForce(Node, int) divided by the number of the nodes.

Parameters

cursor:YCursor — the nodes for which the force will be calculated
 
direction:int — -1 if nodes in higher layers should be used to calculate the forces, 1 if nodes in lower layers should be used, 0 if both surrounding layers should be used

Returns
Number — a force, i.e. a signed value, which, if applied to the nodes in cursor, would minimize the force acting on them.
getPendulumForceOnNode()method 
protected function getPendulumForceOnNode(v:Node, ec:EdgeCursor):Number

Helper method which calculates the force that all nodes given by EdgeCursor apply to v. The force is calculated by the sum of the weighted differences of the x-coordinates.

Parameters

v:Node — the node for which the force will be calculated
 
ec:EdgeCursor — the EdgeCursor which determines which edges should be considered in the calculation

Returns
Number — a force, i.e. a signed value, which (if added to the x-coordinate of v) would minimize the force on v if applied.

See also

getZ()method 
protected function getZ():Number

Calculates the value of the function this algorithm should minimize.

Returns
Number — a positive value.
initializePositions()method 
protected function initializePositions(layerList:Vector.<Object>):void

Helper method which initializes the positions of the nodes in all layers. This method respects getMinimalLayerDistance(Node,boolean) and compacts the graph to the leftmost position (0)

Parameters

layerList:Vector.<Object> — an array of NodeLists each corresponding to a single layer

initPendularDrawer()method 
protected final function initPendularDrawer():void

Initializes this object. See the documentation of the corresponding factory method newPendularDrawer() for details.

See also

initStructures()method 
protected function initStructures():void

used to initialize internal structures such as NodeMap right and NodeMap left bendGridWidth and nodeGridWidth. Note that the NodeMaps do not yet contain any values unless you call initializePositions()

isSegmentNode()method 
protected function isSegmentNode(n:Node):Boolean

Helper method that determines whether a node is a so-called segment node.

Parameters

n:Node — the Node

Returns
Booleantrue iff (inDegree == 1 && outDegree < 2) || (outDegree == 1 && inDegree < 2)
minNode()method 
protected function minNode():void

Performs the minNode phase. 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

If the node has changed its x-coordinate all its neighbors are requeued, if not already in the queue.

minPath()method 
protected function minPath(segments:YList):Boolean

Performs the minPath phase. It 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, not violating the constraints and not changing coordinates of nodes in the neighborhood of each segment

Parameters

segments:YList — a list of NodeList each containing a chain of nodes

Returns
Booleantrue iff there was a change in any coordinate of the graph

See also

move()method 
protected function move(n:Node, distance:Number):void

Helper method which moves a given node by a given amount if the useGrid is set to true, this method will snap the new node position to the appropriate grid, i.e. it decides whether to use nodeGridWith or bendGridWith

Parameters

n:Node — the node
 
distance:Number — the distance that shall be added to the nodes x-coordinate

moveMultiple()method 
protected function moveMultiple(nodes:YCursor, distance:Number):void

Helper method which moves the nodes provided by the Cursor nodes by the given amount. This one in turn calls move(Node,double) to delegate its work.

Parameters

nodes:YCursor — the nodes
 
distance:Number — the distance that shall be added to the nodes x-coordinate

See also

newPendularDrawer()method 
public static function newPendularDrawer():PendularDrawer

empty constructor, does nothing

Returns
PendularDrawer
partitionLayer()method 
protected function partitionLayer(layer:NodeList, direction:int):YList

Partitions a layer given by its NodeList by calculating the forces according to the given direction. This one is intended for use with the shakePartition() method.

Parameters

layer:NodeList — the layer which shall be partitioned
 
direction:int — -1 if nodes in higher layers should be used to calculate the forces, 1 if nodes in lower layers should be used, 0 if both surrounding layers should be used

Returns
YList — a list of NodeLists each containing adjacent nodes in that layer, which can be treated as a single unit when moving

See also

shakePartition()method 
protected function shakePartition(partition:YList, direction:int):void

Shakes a given partition of a Layer, i.e. it calculates the forces for each part of the partition and applies them if possible. It uses the functionality of these methods:

Parameters

partition:YList — a List of NodeLists each containing at least one node belonging to a single layer
 
direction:int — -1 if nodes in higher layers should be used to calculate the forces, 1 if nodes in lower layers should be used, 0 if both surrounding layers should be used

See also

straightenPath()method 
protected function straightenPath(firstCell:ListCell, lastCell:ListCell, range:Vector.<Number>):Boolean

Helper method for use in minPath. It will assign the same x-coordinate to all the nodes given the first and the last cell in NodeList. Note that this method does not double-check whether the given range is valid for all nodes.

Parameters

firstCell:ListCell — this determines the first Node in a NodeList which should be assigned a new x-coordinate
 
lastCell:ListCell — this determines the last Node in a NodeList (which must be same List as the one for firstCell) which should be assigned a new x-coordinate
 
range:Vector.<Number> — an interval providing information of the legal range, the Nodes x-coordinates could be set to. The values can can be smaller than (-Double.MAX_VALUE) for the left border and greater than Double.MAX_VALUE for the right one

Returns
Booleantrue iff this method has done any change to the graphs coordinates

See also

touches()method 
protected function touches(v1:Node, v2:Node):Boolean

Helper method which checks whether two adjacent nodes on a layer touch each other, i.e. their distance is smaller than getMinimalLayerDistance(v1, ...)

Parameters

v1:Node — one node
 
v2:Node — another node

Returns
Booleantrue iff their distance is smaller than getMinimalLayerDistance+EPSILON

See also

verifyMovement()method 
protected function verifyMovement(n:Node, distance:Number):Number

Assures that if distance was applied to the n's x-coordinate no given constraint gets broken. It makes extensive use of getMinimalLayerDistance(v1, ...)

Parameters

n:Node — the node to be moved
 
distance:Number — the distance which shall be verified

Returns
Number — the distance which can be applied to n without breaking any constraint

See also