net.sourceforge.olduvai.treejuxtaposer.drawer
Class TreeNode

java.lang.Object
  extended by net.sourceforge.olduvai.treejuxtaposer.drawer.TreeNode
All Implemented Interfaces:
java.lang.Comparable, CellGeom

public class TreeNode
extends java.lang.Object
implements CellGeom, java.lang.Comparable

A class representing a node of a (phylognenetic) tree. The tree that this node belongs to is of type Tree. Nodes have fields that store a pre- and post-ordering. A TreeNode has a list of children, a unique key, a leftmostleaf and a rightmost leaf

Version:
2.2
Author:
Tamara Munzner, Li Zhang, Yunhong Zhou
See Also:
Tree, GridCell

Field Summary
private  java.lang.Double bcnScore
          Score for a node in [0,1] that corresponds to the topological similarity between two tree drawers.
 GridCell cell
          The GridCell that this node is attached to.
protected  java.util.ArrayList children
          Array of child nodes that are attached below this internal node.
protected  int computedFrame
          The last frame that had a computed midYPosition, for caching.
private  int fontSize
          Height of font in font points used to draw the label.
protected  int height
          Distance from this node to the root node.
 int key
          key is unique for nodes in one tree.
 java.lang.String label
          The text that appears when the node is highlighted or has a name displayed.
 TreeNode leftmostLeaf
          Leftmost (minimum) leaf node under this internal node (or this node for leaves).
private  double midYPosition
          Cached location (world-space) of the mid point in the vertical of a cell where the horizontal tree edge is drawn.
protected  java.lang.String name
          Node name with default "".
 int numberLeaves
          The number of leaves under this internal node (or 1 for leaves).
 TreeNode parent
          The parent of this node.
 TreeNode posorderNext
          The next postorder node.
 TreeNode preorderNext
          The next preorder node.
 TreeNode rightmostLeaf
          Rightmost (maximum) leaf node under this internal node (or this node for leaves).
 float weight
          Weight is the horizontal edge length for the edge immediately above the node.
 
Constructor Summary
TreeNode()
          Default tree node constructor.
 
Method Summary
 void addChild(TreeNode n)
          Add a child to the end of the list of children.
 void close()
          Clean this node of children.
 int compareTo(java.lang.Object o)
          Implements Comparable interface - sorts on key field.
 void drawAscend(int frameNum, float plane)
          Don't draw self, just call this on parents after calling drawDescend ascend drawing until the root is drawn or the node drew in the frame already.
 void drawDescend(int frameNum, float plane, int min, int max, Tree tree)
          Descend from this node and draw children down to leaves.
 void drawInCell(java.util.ArrayList col, double plane)
          The color and drawing depth determining function that calls down to drawInCell(Color, double), for edge splitting (horizontal and vertical)
 void drawInCell(java.awt.Color col, double plane)
          Draws this node inside cell, the GridCell that it is attached to.
private  void drawInCell(java.awt.Color col, double plane, boolean horiz)
          Main drawing function for tree nodes, draws one edge.
 void drawLabelBig(int fontheight, boolean horiz)
          Draw label of this TreeEdge at maximum size (intended for mouseover highlighting).
private  void drawLabelBox(LabelBox lb, int fontheight, boolean drawBig)
          Draw a LabelBox.
 boolean equals(TreeNode n)
          Tests nodes for equality, based on the name of the node.
protected  void finalize()
          Destroy this node.
protected  TreeNode firstChild()
          Get the first child of this node.
private  LabelBox fitLabelBox(java.lang.String label, float[] posStart, float[] posEnd, AccordionTreeDrawer atd)
          Fitting function for labels given a range of label sizes, first, check smallest font, to see if anything at all can fit.
 java.lang.Double getBcnScore()
          Get the BCN score for this treenode.
 GridCell getCell()
          Gets the grid cell that surrounds this node.
 TreeNode getChild(int i)
          Get a given child for this node, with range checking and casting.
protected  boolean getEdge(int xy)
          Tests to see if this node has a vertical or horizontal edge component.
 int getKey()
          Returns the key for this node.
 int getLindex()
          Assuming this is a leaf, return the leaf index (the split position in Y direction, actually)
 int getMax()
          Returns the maximum key value of nodes in the subtree rooted but this node.
 SplitLine getMaxLine(int xy)
          Stub function.
 double getMaxY()
          Get the vertical endpoint (world-space) for the vertical tree edge for this node.
 double getMidY()
          Get the position of the vertical world-space position of the horizontal tree edge for this node.
 int getMin()
          Returns the minimum key value of nodes in the subtree rooted by this node.
 SplitLine getMinLine(int xy)
          Stub function.
private  double getMinY()
          Get the vertical starting point (world-space) for the vertical tree edge for this node.
 java.lang.String getName()
          Returns the label for this node, which is name.
private  double getSize(int xy)
          Gets the cell world-space size (max - min) for this node's cell in the given direction.
 float getWeight()
          Get the weight of this treenode, which encodes the length of the horizontal edge.
private  java.util.ArrayList intersectLabelBox(LabelBox lb, java.util.ArrayList checkLabels)
          Occlusion check of LabelBox against array of all drawn labels.
 boolean isAncestorOf(TreeNode that)
          Test function for determining if one node is an ancestor of another.
 boolean isLeaf()
          Tests to determine if this node is a leaf.
 boolean isNodePicked(double x, double y, double xFuzz, double yFuzz)
          Test function to determine if this tree node is picked.
 boolean isRoot()
          Tests to determine if this node is the root of its tree.
 TreeNode lastChild()
          Get the last child of this node.
 TreeNode lca(TreeNode that)
          Compute the lowest common ancestor between this node and that.
 TreeNode leafLca(TreeNode that)
          Compute the lowest common ancestor between this leaf and "that" The two nodes must belong to the same tree and must be leaves
 void linkNodesInPostorder()
          Leaf->root traversal, starting at leftmost leaf of tree.
 void linkNodesInPreorder()
          root->leaf traversal, depth first in direction of leftmost leaf.
protected  LabelBox makeLabelBox(int fontheight, int x, int y, float[] start, float[] end, boolean labelAtLeaves)
          Create a LabelBox for the given fontheight and positioning information.
 int numberChildren()
          Get the number of children under this node.
 TreeNode parent()
          Get the parent for this node.
 TreeNode pickDescend(double x, double y, double xFuzz, double yFuzz)
          Non-recursion method used to descend the tree structure, finding the node close enough to the given cursor position.
 void print()
          Long form printing for a single node.
private  void printSubtree()
          For debugging, prints the subtree contents, recursive.
 void setBcnScore(float n)
          Set the bcnScore for this node.
protected  void setCell(GridCell c)
          Sets the grid cell for this node to the given value.
 void setExtremeLeaves()
          Set the extreme leaves for this node.
private  java.awt.Color setGLColor(AccordionTreeDrawer atd, java.awt.Color col)
          Draws this TreeEdge inside the GridCell to which it is attached, and its label if appropriate.
 void setName(java.lang.String s)
          Set the name for this node, the name is usually the label drawn with this node.
 int setNumberLeaves()
          Sets the number of leaves, must be run on leaves first (pre-order)
protected  void setPositions(float[] start, float[] end, boolean horiz)
          Sets positions for a tree edge, starting and ending points for the lines that make a single edge.
 void setWeight(double w)
          Set the weight of this treenode, which encodes the length of the horizontal edge.
 java.lang.String toString()
          String value of this node, name + key + tree height information.
private  boolean xyInRange(double value, double fuzz, int xy)
          Test function for cursor proximity to a given world-space position.
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

children

protected java.util.ArrayList children
Array of child nodes that are attached below this internal node. Null if this is a leaf.


key

public int key
key is unique for nodes in one tree. Keys are pre-ordered (root = 0, depth-traversal ordering).


cell

public GridCell cell
The GridCell that this node is attached to. 4 split lines make up the cell boundaries.


fontSize

private int fontSize
Height of font in font points used to draw the label.


bcnScore

private java.lang.Double bcnScore
Score for a node in [0,1] that corresponds to the topological similarity between two tree drawers.

See Also:
TreePairs.getBestCorrNodeScore(Tree, TreeNode, Tree, int)

computedFrame

protected int computedFrame
The last frame that had a computed midYPosition, for caching.


midYPosition

private double midYPosition
Cached location (world-space) of the mid point in the vertical of a cell where the horizontal tree edge is drawn. This is (1/2 of cell size + minY) for leaves, midway between first and last child edge for internal nodes.


parent

public TreeNode parent
The parent of this node. This is null for the root node.


name

protected java.lang.String name
Node name with default "". Most internal nodes have no name and all leaf nodes have a name. This becomes the long version of the node name when fully qualified names are used.


label

public java.lang.String label
The text that appears when the node is highlighted or has a name displayed.


height

protected int height
Distance from this node to the root node. The root is at height 1.


weight

public float weight
Weight is the horizontal edge length for the edge immediately above the node. Edge lengths are not determined by this number currently; all edges are stretched to make leaves right aligned, with minimal integral lengths.


leftmostLeaf

public TreeNode leftmostLeaf
Leftmost (minimum) leaf node under this internal node (or this node for leaves).


rightmostLeaf

public TreeNode rightmostLeaf
Rightmost (maximum) leaf node under this internal node (or this node for leaves).


numberLeaves

public int numberLeaves
The number of leaves under this internal node (or 1 for leaves).


preorderNext

public TreeNode preorderNext
The next preorder node.


posorderNext

public TreeNode posorderNext
The next postorder node.

Constructor Detail

TreeNode

public TreeNode()
Default tree node constructor. Children list initially set to capacity 2 as in most case binary. Used in 2 places: create the root when creating the tree; the parser uses this to create nodes attached to the root.

Method Detail

getMin

public int getMin()
Returns the minimum key value of nodes in the subtree rooted by this node.

Returns:
The index of the smallest descendant node (which is the key for this node).

getMax

public int getMax()
Returns the maximum key value of nodes in the subtree rooted but this node.

Returns:
The index of the smallest descendant node (which is the key for the rightmost leaf node).

getKey

public int getKey()
Returns the key for this node.

Specified by:
getKey in interface CellGeom
Returns:
The value of key for this node.

getName

public java.lang.String getName()
Returns the label for this node, which is name.

Specified by:
getName in interface CellGeom
Returns:
The value of name for this node.

drawInCell

public void drawInCell(java.awt.Color col,
                       double plane)
Draws this node inside cell, the GridCell that it is attached to. Size checks are done before this step. Labels are drawn if there is no label overlap with previously drawn nodes. This function splits the edges into horizontal and vertical components for drawInCell(Color, double, boolean), the edge drawing drawInCell. This function gets input from drawInCell(ArrayList, double), the color and drawing depth function.

Specified by:
drawInCell in interface CellGeom
Parameters:
col - The color to draw this node, determined by the calls from drawInCell(ArrayList, double), which is responsible for picking color and plane.
plane - The plane to draw this node in, determined by drawInCell(ArrayList, double).
See Also:
GridCell, drawInCell(ArrayList, double), drawInCell(Color, double, boolean)

drawInCell

public void drawInCell(java.util.ArrayList col,
                       double plane)
The color and drawing depth determining function that calls down to drawInCell(Color, double), for edge splitting (horizontal and vertical)

Parameters:
col - An array of colors from AccordionDrawer.getColorsForCellGeom(CellGeom)
plane - The drawing plane for this cell

setCell

protected void setCell(GridCell c)
Sets the grid cell for this node to the given value. Cells bound nodes in all directions.

Parameters:
c - The cell for this node.

getCell

public GridCell getCell()
Gets the grid cell that surrounds this node.

Specified by:
getCell in interface CellGeom
Returns:
A grid cell that contains this node. This is for referencing additional information not stored in each node (such as the drawer object), so we don't store more pointers than necessary for common objects.

getEdge

protected boolean getEdge(int xy)
Tests to see if this node has a vertical or horizontal edge component.

Parameters:
xy - 0/X for horizontal, 1/Y for vertical nodes.
Returns:
True if this node has an edge in the chosen direction. Only root nodes don't have a horizontal edge, and only leaves don't have vertical edges.

compareTo

public int compareTo(java.lang.Object o)
Implements Comparable interface - sorts on key field.

Specified by:
compareTo in interface java.lang.Comparable
Parameters:
o - The other object to compare this node to.
Returns:
-1 if this is smaller than the object's key, +1 if greater, 0 if equal.

drawLabelBig

public void drawLabelBig(int fontheight,
                         boolean horiz)
Draw label of this TreeEdge at maximum size (intended for mouseover highlighting). Uses current flash label box for drawing (check to make sure this isn't null before calling this function).

Parameters:
fontheight - Size of text to draw label.
horiz - Label is only drawn if the current edge being drawn is horizontal, this must be true.

drawInCell

private void drawInCell(java.awt.Color col,
                        double plane,
                        boolean horiz)
Main drawing function for tree nodes, draws one edge. Draws either the horizontal or vertical tree edge for this node. Calls label drawing functions after finished if this is a horizontal edge.

Parameters:
col - Color to draw edge.
plane - Plane in which to draw edges.
horiz - True for horizontal edges, false for vertical.

fitLabelBox

private LabelBox fitLabelBox(java.lang.String label,
                             float[] posStart,
                             float[] posEnd,
                             AccordionTreeDrawer atd)
Fitting function for labels given a range of label sizes, first, check smallest font, to see if anything at all can fit. If it does, then do binary search to find largest possible box that fits. after we know which box size to use, draw it. This algorithm means drawing order will have a radical effect on how labels look! We should set min to one less than the real bound. new real bound is minFontSize+1 (because we already tested minFontSize), so leave min set to current value of (minFontSize+1)-1 = minFontSize

Parameters:
label - String to place in label.
posStart - starting location for label, in world-space.
posEnd - ending location for label, in world-space.
atd - Drawer for this tree node.
Returns:
Biggest label box that can fit in the given remaining space. Null if no possible label fits.

close

public void close()
Clean this node of children.


finalize

protected void finalize()
                 throws java.lang.Throwable
Destroy this node. Runs close().

Overrides:
finalize in class java.lang.Object
Throws:
java.lang.Throwable

setName

public void setName(java.lang.String s)
Set the name for this node, the name is usually the label drawn with this node.

Parameters:
s - The new value of name, the name for this node.

numberChildren

public int numberChildren()
Get the number of children under this node.

Returns:
Number of nodes stored in the children array children.

getChild

public TreeNode getChild(int i)
Get a given child for this node, with range checking and casting.

Parameters:
i - The child index to get.
Returns:
The i(th) child for this node.

isLeaf

public boolean isLeaf()
Tests to determine if this node is a leaf. Does not work for nodes not in the tree structure.

Returns:
True if this node has no linked children, and therefore is a leaf node for the tree.

isRoot

public boolean isRoot()
Tests to determine if this node is the root of its tree. Does not work for nodes not in the tree structure.

Returns:
True if this node has no linked parent, and therefore is the root of the tree.

equals

public boolean equals(TreeNode n)
Tests nodes for equality, based on the name of the node.

Parameters:
n - Second node to test vs. this node.
Returns:
True if the names of both nodes are the same, false otherwise.

addChild

public void addChild(TreeNode n)
Add a child to the end of the list of children. Note there is no remove child method, this is permanent. Additional processing for linking nodes (setting up pointers and leaf properties, for example) is done later.

Parameters:
n - New child node for this node.

parent

public TreeNode parent()
Get the parent for this node.

Returns:
Value of parent.

setWeight

public void setWeight(double w)
Set the weight of this treenode, which encodes the length of the horizontal edge. Edge weights are not implemented currently for drawing.

Parameters:
w - New edge weight for this node, weight.

getWeight

public float getWeight()
Get the weight of this treenode, which encodes the length of the horizontal edge. Edge weights are not implemented currently for drawing.

Returns:
Edge weight for this node, weight.

firstChild

protected TreeNode firstChild()
Get the first child of this node. Doesn't work with leaf nodes.

Returns:
First child of this internal node.

lastChild

public TreeNode lastChild()
Get the last child of this node. Doesn't work with leaf nodes.

Returns:
Last child of this internal node.

isAncestorOf

public boolean isAncestorOf(TreeNode that)
Test function for determining if one node is an ancestor of another.

Parameters:
that - Another TreeNode object
Returns:
true if this is an ancestor of that

lca

public TreeNode lca(TreeNode that)
Compute the lowest common ancestor between this node and that. The two nodes must belong to the same tree.

Parameters:
that - A TreeNode in the Tree that this TreeNode belongs to
Returns:
the lowest common ancestor between this node and "that"

leafLca

public TreeNode leafLca(TreeNode that)
Compute the lowest common ancestor between this leaf and "that" The two nodes must belong to the same tree and must be leaves

Parameters:
that - A TreeNode in the Tree that this TreeNode belongs to
Returns:
the lowest common ancestor between this leaf and that, null if one of the nodes is not a leaf

print

public void print()
Long form printing for a single node. Used in conjunction with printSubtree() to display a whole subtree.


printSubtree

private void printSubtree()
For debugging, prints the subtree contents, recursive.


setExtremeLeaves

public void setExtremeLeaves()
Set the extreme leaves for this node. This is done in leaf->root direction, so all linking can be done in O(n) time.


linkNodesInPreorder

public void linkNodesInPreorder()
root->leaf traversal, depth first in direction of leftmost leaf.


linkNodesInPostorder

public void linkNodesInPostorder()
Leaf->root traversal, starting at leftmost leaf of tree.


setNumberLeaves

public int setNumberLeaves()
Sets the number of leaves, must be run on leaves first (pre-order)

Returns:
The number of leaves (numberLeaves) including the current node (leaves = 1)

toString

public java.lang.String toString()
String value of this node, name + key + tree height information.

Overrides:
toString in class java.lang.Object
Returns:
String representation of this node.

setBcnScore

public void setBcnScore(float n)
Set the bcnScore for this node.

Parameters:
n - New value of bcnScore.

getBcnScore

public java.lang.Double getBcnScore()
Get the BCN score for this treenode.

Returns:
Value of bcnScore for this node.

getMidY

public double getMidY()
Get the position of the vertical world-space position of the horizontal tree edge for this node.

Returns:
World-space vertical position of this node's horizontal edge.

getMinY

private double getMinY()
Get the vertical starting point (world-space) for the vertical tree edge for this node. Returns the position of the middle of the cell for the first child of this node.

Returns:
Vertical position of the middle of the cell for the first child of this node.

getMaxY

public double getMaxY()
Get the vertical endpoint (world-space) for the vertical tree edge for this node. Returns the position of the middle of the cell for the last child of this node.

Returns:
Vertical position of the middle of the cell for the last child of this node.

getSize

private double getSize(int xy)
Gets the cell world-space size (max - min) for this node's cell in the given direction.

Parameters:
xy - Direction for getting size.
Returns:
Size for the cell in one dimension.

isNodePicked

public boolean isNodePicked(double x,
                            double y,
                            double xFuzz,
                            double yFuzz)
Test function to determine if this tree node is picked.

Parameters:
x - Horizontal cursor world-space position.
y - Vertical cursor world-space position.
xFuzz - World-space maximum horizontal distance for cursor to this node's cell.
yFuzz - World-space maximum vertical distance for cursor to this node's cell.
Returns:
true if both x and y cursor positions are close enough to the tree edges for this node to suggest that this tree node is picked.

xyInRange

private boolean xyInRange(double value,
                          double fuzz,
                          int xy)
Test function for cursor proximity to a given world-space position.

Parameters:
value - World-space cursor position to check.
fuzz - World-space maximum distance for cursor to this node's cell.
xy - 0/1 value for X/Y
Returns:
true if cursor is close enough or inside the cell for this node.

pickDescend

public TreeNode pickDescend(double x,
                            double y,
                            double xFuzz,
                            double yFuzz)
Non-recursion method used to descend the tree structure, finding the node close enough to the given cursor position.

Parameters:
x - Cursor horizontal position.
y - Cursor vertical position.
xFuzz - Horizontal threshold for picking.
yFuzz - Vertical threshold for picking.
Returns:
Treenode close enough to x/y, within xFuzz/yFuzz.

getLindex

public int getLindex()
Assuming this is a leaf, return the leaf index (the split position in Y direction, actually)

Returns:
Leaf index of this node.

drawAscend

public void drawAscend(int frameNum,
                       float plane)
Don't draw self, just call this on parents after calling drawDescend ascend drawing until the root is drawn or the node drew in the frame already.

Parameters:
frameNum - Current frame number.
plane - Plane to draw nodes in.

drawDescend

public void drawDescend(int frameNum,
                        float plane,
                        int min,
                        int max,
                        Tree tree)
Descend from this node and draw children down to leaves. The direction of descent must draw leaves between min and max, indices into the list of leaves. This node is also drawn.

Parameters:
frameNum - Current frame number.
plane - Drawing plane for this node.
min - Index of leaf with minimum node key.
max - Index of leaf with maximum node key.
tree - Tree that this node belongs to.

setGLColor

private java.awt.Color setGLColor(AccordionTreeDrawer atd,
                                  java.awt.Color col)
Draws this TreeEdge inside the GridCell to which it is attached, and its label if appropriate. Find font size to use for drawing the label, by checking for occlusions. Don't draw it all if it's occluded even at the smallest size.

Parameters:
atd - Tree drawer for this node/tree
col - The color to draw this node in
See Also:
GridCell

setPositions

protected void setPositions(float[] start,
                            float[] end,
                            boolean horiz)
Sets positions for a tree edge, starting and ending points for the lines that make a single edge. Horizontal edges depend on the getMidY() function to compute links to a viable location between the min and max child.

Parameters:
start - Set by this function, a starting X/Y position in world-coordinates
end - Set by this function, an ending X/Y position in world-coordinates
horiz - Passed in parameter, horizontal true for edges that do not change in Y from start to end, false=vertical, X doesn't change

makeLabelBox

protected LabelBox makeLabelBox(int fontheight,
                                int x,
                                int y,
                                float[] start,
                                float[] end,
                                boolean labelAtLeaves)
Create a LabelBox for the given fontheight and positioning information.

Parameters:
fontheight - Size of the font in pixels.
x - horizontal base location in screen/pixel coordinates
y - vertical base location in screen/pixel coordinates
start - starting position for the tree node (horizontal edge), in world-space coordinates
end - ending position for the tree ndoe (horizontal edge), in world-space coordinates
labelAtLeaves - if true, we label at the leaves after the edge of the max stuck line, unlike the internal drawing that starts on the horizontal edge
See Also:
LabelBox

intersectLabelBox

private java.util.ArrayList intersectLabelBox(LabelBox lb,
                                              java.util.ArrayList checkLabels)
Occlusion check of LabelBox against array of all drawn labels. AccordionDrawer.getDrawnLabels(). Returns a list of all overlapping labels, when the label box intersects with an existing label box. 2007/02 added check for labeling leaves The list is no longer sorted. We now pass in an array of placed labels to examine, which may be all visible labels initally, and a subset as the possible overlaps are reduced in our font downsizing in fitLabelBox(String, float[], float[], AccordionTreeDrawer) Since the number of labels tends to be small (100 concurrent labels would be very difficult to read) we can search the list of existing labels with a linear scan.)

Parameters:
lb - LabelBox to check for overlaps
checkLabels - Array of labels that we may check against for overlaps.
Returns:
List of any labels that overlap the labelbox.
See Also:
LabelBox

drawLabelBox

private void drawLabelBox(LabelBox lb,
                          int fontheight,
                          boolean drawBig)
Draw a LabelBox. This includes the bounding box and label, identified by the label box input.

Parameters:
lb - LabelBox to use, which includes the string for the label and bounding box information.
fontheight - Size of font to use, in points/pixels.
drawBig - whether to draw maximum size ignoring occlusions

getMinLine

public SplitLine getMinLine(int xy)
Stub function.

Specified by:
getMinLine in interface CellGeom
Parameters:
xy - Direction.
Returns:
Splitline for minimum cell bound in direction

getMaxLine

public SplitLine getMaxLine(int xy)
Stub function.

Specified by:
getMaxLine in interface CellGeom
Parameters:
xy - Direction.
Returns:
Splitline for maximum cell bound in direction