mev-4.0.01/source/org/tigr/microarray/mev/cluster/gui/impl/sota/SOTATree.java

Code
Comments
Other
Rev Date Author Line
2 26 Feb 07 jari 1 /*
2 26 Feb 07 jari 2 Copyright @ 1999-2005, The Institute for Genomic Research (TIGR).
2 26 Feb 07 jari 3 All rights reserved.
2 26 Feb 07 jari 4 */
2 26 Feb 07 jari 5 /*
2 26 Feb 07 jari 6  * $RCSfile: SOTATree.java,v $
2 26 Feb 07 jari 7  * $Revision: 1.5 $
2 26 Feb 07 jari 8  * $Date: 2006/03/24 15:51:44 $
2 26 Feb 07 jari 9  * $Author: eleanorahowe $
2 26 Feb 07 jari 10  * $State: Exp $
2 26 Feb 07 jari 11  */
2 26 Feb 07 jari 12 package org.tigr.microarray.mev.cluster.gui.impl.sota;
2 26 Feb 07 jari 13
2 26 Feb 07 jari 14 import java.awt.Color;
2 26 Feb 07 jari 15 import java.awt.Dimension;
2 26 Feb 07 jari 16 import java.awt.Graphics;
2 26 Feb 07 jari 17 import java.awt.Graphics2D;
2 26 Feb 07 jari 18
2 26 Feb 07 jari 19 import javax.swing.JPanel;
2 26 Feb 07 jari 20
2 26 Feb 07 jari 21 import org.tigr.microarray.mev.cluster.gui.IData;
2 26 Feb 07 jari 22 import org.tigr.microarray.mev.cluster.gui.IDisplayMenu;
2 26 Feb 07 jari 23 import org.tigr.microarray.mev.cluster.gui.IFramework;
2 26 Feb 07 jari 24
2 26 Feb 07 jari 25 public class SOTATree extends JPanel {
2 26 Feb 07 jari 26     
2 26 Feb 07 jari 27     
2 26 Feb 07 jari 28     private int TREE_X_ORIGIN = 10;
2 26 Feb 07 jari 29     public static final int HORIZONTAL = 0;
2 26 Feb 07 jari 30     public static final int VERTICAL   = 1;
2 26 Feb 07 jari 31     private int orientation = 0;
2 26 Feb 07 jari 32     protected Color lineColor = new Color(0, 0, 128);
2 26 Feb 07 jari 33     protected Color extenderColor = Color.lightGray;
2 26 Feb 07 jari 34     
2 26 Feb 07 jari 35     private int numberOfClusters;
2 26 Feb 07 jari 36     private double  maxLeafToRootPath;
2 26 Feb 07 jari 37     private int treeHeight;
2 26 Feb 07 jari 38     int maxXPosition;
2 26 Feb 07 jari 39     
2 26 Feb 07 jari 40     private int maxNodeHeight;
2 26 Feb 07 jari 41     private int minNodeHeight;
2 26 Feb 07 jari 42     private int height;
2 26 Feb 07 jari 43     private int width;  //based on numClusters*element height
2 26 Feb 07 jari 44     private int elementHeight = 10;
2 26 Feb 07 jari 45     private int elementWidth = 20;
2 26 Feb 07 jari 46     private int paintElementHeight;
2 26 Feb 07 jari 47     private int FACTOR = 20;
2 26 Feb 07 jari 48     private int origX;
2 26 Feb 07 jari 49     private int origY;
2 26 Feb 07 jari 50     private int utilCounter;
2 26 Feb 07 jari 51     private SOTATreeData sotaTreeData;
2 26 Feb 07 jari 52     
2 26 Feb 07 jari 53     protected IData data;
2 26 Feb 07 jari 54     
2 26 Feb 07 jari 55     int sign = 1;
2 26 Feb 07 jari 56     
2 26 Feb 07 jari 57     float [] nodeHeights;
2 26 Feb 07 jari 58     int [] leftChild;
2 26 Feb 07 jari 59     int [] rightChild;
2 26 Feb 07 jari 60     int [] nodePopulation;
2 26 Feb 07 jari 61     public boolean getGeneTree(){
2 26 Feb 07 jari 62       if(this.orientation == SOTATree.VERTICAL)
2 26 Feb 07 jari 63         return true;
2 26 Feb 07 jari 64       return false;
2 26 Feb 07 jari 65     }
2 26 Feb 07 jari 66     public SOTATreeData getSotaTreeData(){return sotaTreeData;}
2 26 Feb 07 jari 67     
2 26 Feb 07 jari 68     /**
2 26 Feb 07 jari 69      * Used by SOTATreePersistenceDelegate to recreate a SOTATree from saved data
2 26 Feb 07 jari 70      */
2 26 Feb 07 jari 71     public SOTATree(SOTATreeData sotaTreeData, Boolean geneTree){
2 26 Feb 07 jari 72       this(sotaTreeData, geneTree.booleanValue());
2 26 Feb 07 jari 73     }
2 26 Feb 07 jari 74     
2 26 Feb 07 jari 75     /** Creates new SOTATree */
2 26 Feb 07 jari 76     public SOTATree(SOTATreeData sotaTreeData, boolean geneTree){
2 26 Feb 07 jari 77       this.sotaTreeData = sotaTreeData;
2 26 Feb 07 jari 78         setBackground(Color.white);
2 26 Feb 07 jari 79         if(!geneTree)
2 26 Feb 07 jari 80             this.orientation = SOTATree.VERTICAL;
2 26 Feb 07 jari 81         this.nodeHeights = sotaTreeData.nodeHeights;
2 26 Feb 07 jari 82         this.leftChild = sotaTreeData.leftChild;
2 26 Feb 07 jari 83         this.rightChild = sotaTreeData.rightChild;
2 26 Feb 07 jari 84         this.nodePopulation = sotaTreeData.nodePopulation;
2 26 Feb 07 jari 85         
2 26 Feb 07 jari 86         numberOfClusters = nodeHeights.length/2;
2 26 Feb 07 jari 87         
2 26 Feb 07 jari 88         maxNodeHeight = 40;
2 26 Feb 07 jari 89         minNodeHeight = 5;
2 26 Feb 07 jari 90         
2 26 Feb 07 jari 91         width = getTreeHeight();
2 26 Feb 07 jari 92         height = getTreeWidth();
2 26 Feb 07 jari 93         
2 26 Feb 07 jari 94         if(orientation == SOTATree.HORIZONTAL)            
2 26 Feb 07 jari 95             setSizes(width, height);
2 26 Feb 07 jari 96         else
2 26 Feb 07 jari 97             setSizes(height, width);
2 26 Feb 07 jari 98     }
2 26 Feb 07 jari 99     
2 26 Feb 07 jari 100     
2 26 Feb 07 jari 101     public void paint(Graphics g){
2 26 Feb 07 jari 102         super.paint(g);
2 26 Feb 07 jari 103         height = numberOfClusters*elementHeight;
2 26 Feb 07 jari 104         width = getTreeHeight();  //sets maxXPosition
2 26 Feb 07 jari 105         paintSotaTree(g);
2 26 Feb 07 jari 106     }
2 26 Feb 07 jari 107     
2 26 Feb 07 jari 108     
2 26 Feb 07 jari 109     private void paintSotaTree(Graphics g){
2 26 Feb 07 jari 110         Color startColor = g.getColor();
2 26 Feb 07 jari 111         origX = TREE_X_ORIGIN;
2 26 Feb 07 jari 112         
2 26 Feb 07 jari 113         g.setColor(lineColor);
2 26 Feb 07 jari 114         this.paintElementHeight = elementHeight;
2 26 Feb 07 jari 115         if(this.orientation == SOTATree.VERTICAL){
2 26 Feb 07 jari 116             ((Graphics2D)g).rotate(-Math.PI/2.0);
2 26 Feb 07 jari 117             //     this.elementHeight = -elementWidth;
2 26 Feb 07 jari 118             this.paintElementHeight = elementWidth;
2 26 Feb 07 jari 119             sign = -1;
2 26 Feb 07 jari 120             origY = getSubTreeSize(rightChild[0]) * elementWidth;
2 26 Feb 07 jari 121             paintSotaTree(g, 0, origX, origY+10);
2 26 Feb 07 jari 122         }
2 26 Feb 07 jari 123         else{
2 26 Feb 07 jari 124             origY = getSubTreeSize(rightChild[0]) * elementHeight;
2 26 Feb 07 jari 125             paintSotaTree(g, 0, origX, origY);
2 26 Feb 07 jari 126         }
2 26 Feb 07 jari 127         g.setColor(startColor);
2 26 Feb 07 jari 128         sign = 1;
2 26 Feb 07 jari 129     }
2 26 Feb 07 jari 130     
2 26 Feb 07 jari 131     
2 26 Feb 07 jari 132     private void paintSotaTree(Graphics g, int index, int xPos, int yPosCenter){
2 26 Feb 07 jari 133         
2 26 Feb 07 jari 134         if(nodePopulation[index] == 0)
2 26 Feb 07 jari 135             return;
2 26 Feb 07 jari 136         
2 26 Feb 07 jari 137         int xPosition = xPos;
2 26 Feb 07 jari 138         int y1, y2;
2 26 Feb 07 jari 139         y1 = y2 = yPosCenter;
2 26 Feb 07 jari 140         
2 26 Feb 07 jari 141         //leaf, draw one line back to parent node lemvel
2 26 Feb 07 jari 142         if(leftChild[index] == -1){// && nodeHeights[index] > -1){
2 26 Feb 07 jari 143             xPosition += FACTOR * nodeHeights[index];
2 26 Feb 07 jari 144             if(xPosition - xPos < minNodeHeight)
2 26 Feb 07 jari 145                 xPosition = xPos + minNodeHeight;
2 26 Feb 07 jari 146             else if(xPosition - xPos > maxNodeHeight)
2 26 Feb 07 jari 147                 xPosition = xPos + maxNodeHeight;
2 26 Feb 07 jari 148             
2 26 Feb 07 jari 149             g.drawLine(xPos*sign, yPosCenter, xPosition*sign, yPosCenter);
2 26 Feb 07 jari 150             g.setColor(this.extenderColor);
2 26 Feb 07 jari 151             g.drawLine(xPosition*sign, yPosCenter, maxXPosition*sign, yPosCenter);
2 26 Feb 07 jari 152             g.setColor(this.lineColor);
2 26 Feb 07 jari 153             return;
2 26 Feb 07 jari 154         }
2 26 Feb 07 jari 155         
2 26 Feb 07 jari 156         //root node
2 26 Feb 07 jari 157         if(index == 0) //set the
2 26 Feb 07 jari 158             xPosition = xPos;      //origin x
2 26 Feb 07 jari 159         
2 26 Feb 07 jari 160         //this is not the root, nor a leaf
2 26 Feb 07 jari 161         else{
2 26 Feb 07 jari 162             xPosition += FACTOR * nodeHeights[index];
2 26 Feb 07 jari 163             if(xPosition - xPos < minNodeHeight)
2 26 Feb 07 jari 164                 xPosition = xPos + minNodeHeight;
2 26 Feb 07 jari 165             else if(xPosition - xPos > maxNodeHeight)
2 26 Feb 07 jari 166                 xPosition = xPos + maxNodeHeight;
2 26 Feb 07 jari 167             
2 26 Feb 07 jari 168             maxXPosition = max(maxXPosition, xPosition);
2 26 Feb 07 jari 169             g.drawLine(xPos*sign, yPosCenter, xPosition*sign, yPosCenter);
2 26 Feb 07 jari 170         }
2 26 Feb 07 jari 171         
2 26 Feb 07 jari 172         //know subroot has two children
2 26 Feb 07 jari 173         int widthLeft = 1;
2 26 Feb 07 jari 174         int widthRight = 1;
2 26 Feb 07 jari 175         
2 26 Feb 07 jari 176         if(rightChild[leftChild[index]] != -1 && nodePopulation[rightChild[leftChild[index]]] != -1){
2 26 Feb 07 jari 177             widthLeft = getSubTreeSize(rightChild[leftChild[index]]);
2 26 Feb 07 jari 178             widthLeft = (int) (widthLeft * paintElementHeight);
2 26 Feb 07 jari 179             y1 = yPosCenter + widthLeft;
2 26 Feb 07 jari 180         }
2 26 Feb 07 jari 181         else{
2 26 Feb 07 jari 182             y1 = yPosCenter + (int)(paintElementHeight/2.0);
2 26 Feb 07 jari 183         }
2 26 Feb 07 jari 184         
2 26 Feb 07 jari 185         if(leftChild[rightChild[index]] != -1 && nodePopulation[leftChild[rightChild[index]]] != -1){
2 26 Feb 07 jari 186             widthRight = getSubTreeSize(leftChild[rightChild[index]]);
2 26 Feb 07 jari 187             widthRight = (int)(widthRight * paintElementHeight);
2 26 Feb 07 jari 188             y2 = yPosCenter - widthRight;
2 26 Feb 07 jari 189         }
2 26 Feb 07 jari 190         else{
2 26 Feb 07 jari 191             y2 = yPosCenter - (int)(paintElementHeight/2.0);
2 26 Feb 07 jari 192         }
2 26 Feb 07 jari 193         g.drawLine(xPosition*sign, yPosCenter, xPosition*sign, y1);
2 26 Feb 07 jari 194         paintSotaTree(g, leftChild[index], xPosition ,y1 );
2 26 Feb 07 jari 195         
2 26 Feb 07 jari 196         g.drawLine(xPosition*sign, yPosCenter, xPosition*sign, y2);
2 26 Feb 07 jari 197         paintSotaTree(g, rightChild[index], xPosition, y2);
2 26 Feb 07 jari 198     }
2 26 Feb 07 jari 199     
2 26 Feb 07 jari 200     
2 26 Feb 07 jari 201     private int getSubTreeSize(int index){
2 26 Feb 07 jari 202         utilCounter = 0;
2 26 Feb 07 jari 203         getNumberOfSubtreeNodes(index);
2 26 Feb 07 jari 204         return utilCounter;
2 26 Feb 07 jari 205     }
2 26 Feb 07 jari 206     
2 26 Feb 07 jari 207     private void getNumberOfSubtreeNodes(int index){
2 26 Feb 07 jari 208         if(leftChild[index] != -1)
2 26 Feb 07 jari 209             getNumberOfSubtreeNodes(leftChild[index]);
2 26 Feb 07 jari 210         if(rightChild[index] != -1)
2 26 Feb 07 jari 211             getNumberOfSubtreeNodes(rightChild[index]);
2 26 Feb 07 jari 212         else
2 26 Feb 07 jari 213             utilCounter++;
2 26 Feb 07 jari 214     }
2 26 Feb 07 jari 215     
2 26 Feb 07 jari 216     private int max(int n, int m){
2 26 Feb 07 jari 217         if(n > m)
2 26 Feb 07 jari 218             return n;
2 26 Feb 07 jari 219         else
2 26 Feb 07 jari 220             return m;
2 26 Feb 07 jari 221     }
2 26 Feb 07 jari 222     
2 26 Feb 07 jari 223     public int getTreeWidth(){
2 26 Feb 07 jari 224         return elementHeight * numberOfClusters;
2 26 Feb 07 jari 225     }
2 26 Feb 07 jari 226     
2 26 Feb 07 jari 227     public int getTreeHeight(){
2 26 Feb 07 jari 228         maxXPosition = TREE_X_ORIGIN;
2 26 Feb 07 jari 229         getTreeHeight(0, TREE_X_ORIGIN);
2 26 Feb 07 jari 230         return maxXPosition;
2 26 Feb 07 jari 231     }
2 26 Feb 07 jari 232     
2 26 Feb 07 jari 233     private void getTreeHeight(int index, int xPos){
2 26 Feb 07 jari 234         
2 26 Feb 07 jari 235         if(index < 0) return;
2 26 Feb 07 jari 236         int xPosition = xPos;
2 26 Feb 07 jari 237         
2 26 Feb 07 jari 238         //leaf
2 26 Feb 07 jari 239         if(leftChild[index] == -1){  // && subRoot.parent != null){
2 26 Feb 07 jari 240             xPosition += FACTOR * nodeHeights[index];
2 26 Feb 07 jari 241             if(xPosition - xPos < minNodeHeight)
2 26 Feb 07 jari 242                 xPosition = xPos + minNodeHeight;
2 26 Feb 07 jari 243             else if(xPosition - xPos > maxNodeHeight)
2 26 Feb 07 jari 244                 xPosition = xPos + maxNodeHeight;
2 26 Feb 07 jari 245             maxXPosition = max(maxXPosition, xPosition);
2 26 Feb 07 jari 246             return;
2 26 Feb 07 jari 247         }
2 26 Feb 07 jari 248         
2 26 Feb 07 jari 249         //root node
2 26 Feb 07 jari 250         if(index == 0) //set the
2 26 Feb 07 jari 251             xPosition = xPos;      //origin x
2 26 Feb 07 jari 252         
2 26 Feb 07 jari 253         //this is not the root, nor a leaf
2 26 Feb 07 jari 254         else{
2 26 Feb 07 jari 255             xPosition += FACTOR * nodeHeights[index];
2 26 Feb 07 jari 256             if(xPosition - xPos < minNodeHeight)
2 26 Feb 07 jari 257                 xPosition = xPos + minNodeHeight;
2 26 Feb 07 jari 258             else if(xPosition - xPos > maxNodeHeight)
2 26 Feb 07 jari 259                 xPosition = xPos + maxNodeHeight;
2 26 Feb 07 jari 260             maxXPosition = max(maxXPosition, xPosition);
2 26 Feb 07 jari 261         }
2 26 Feb 07 jari 262         getTreeHeight(leftChild[index], xPosition);
2 26 Feb 07 jari 263         getTreeHeight(rightChild[index], xPosition);
2 26 Feb 07 jari 264     }
2 26 Feb 07 jari 265     
2 26 Feb 07 jari 266     /**
2 26 Feb 07 jari 267      * Updates the tree size, if element size was changed.
2 26 Feb 07 jari 268      */
2 26 Feb 07 jari 269     public void onSelected(IFramework framework) {
2 26 Feb 07 jari 270         this.data = framework.getData();
2 26 Feb 07 jari 271         updateSize(framework.getDisplayMenu().getElementSize());
2 26 Feb 07 jari 272         repaint();
2 26 Feb 07 jari 273     }
2 26 Feb 07 jari 274     
2 26 Feb 07 jari 275     /**
2 26 Feb 07 jari 276      * Updates the tree size, if element size was changed.
2 26 Feb 07 jari 277      */
2 26 Feb 07 jari 278     public void onMenuChanged(IDisplayMenu menu) {
2 26 Feb 07 jari 279         updateSize(menu.getElementSize());
2 26 Feb 07 jari 280     }
2 26 Feb 07 jari 281     
2 26 Feb 07 jari 282     /**
2 26 Feb 07 jari 283      * Updates the tree size with specified element size.
2 26 Feb 07 jari 284      */
2 26 Feb 07 jari 285     private void updateSize(Dimension elementSize) {
2 26 Feb 07 jari 286         
2 26 Feb 07 jari 287         elementHeight = elementSize.height;
2 26 Feb 07 jari 288         elementWidth = elementSize.width;
2 26 Feb 07 jari 289         
2 26 Feb 07 jari 290         switch (this.orientation) {
2 26 Feb 07 jari 291             case HORIZONTAL:
2 26 Feb 07 jari 292                 if (this.elementHeight == elementSize.height) {
2 26 Feb 07 jari 293                     return;
2 26 Feb 07 jari 294                 }
2 26 Feb 07 jari 295                 this.elementHeight = elementSize.height;
2 26 Feb 07 jari 296                 setSizes(getTreeHeight(), elementHeight * this.numberOfClusters);
2 26 Feb 07 jari 297                 break;
2 26 Feb 07 jari 298             case VERTICAL:
2 26 Feb 07 jari 299                 if (elementWidth == elementSize.width) {
2 26 Feb 07 jari 300                     return;
2 26 Feb 07 jari 301                 }
2 26 Feb 07 jari 302                 elementWidth = elementSize.width;
2 26 Feb 07 jari 303                 setSizes(this.elementWidth * this.numberOfClusters, getTreeHeight());
2 26 Feb 07 jari 304                 break;
2 26 Feb 07 jari 305         }
2 26 Feb 07 jari 306     }
2 26 Feb 07 jari 307     
2 26 Feb 07 jari 308     /**
2 26 Feb 07 jari 309      * Sets the tree sizes.
2 26 Feb 07 jari 310      */
2 26 Feb 07 jari 311     private void setSizes(int width, int height) {
2 26 Feb 07 jari 312         setSize(width, height);
2 26 Feb 07 jari 313         setPreferredSize(new Dimension(width, height));
2 26 Feb 07 jari 314     }
2 26 Feb 07 jari 315     
2 26 Feb 07 jari 316     public int getMinDistance(){
2 26 Feb 07 jari 317         return minNodeHeight;
2 26 Feb 07 jari 318     }
2 26 Feb 07 jari 319     
2 26 Feb 07 jari 320     public int getMaxDistance(){
2 26 Feb 07 jari 321         return maxNodeHeight;
2 26 Feb 07 jari 322     }
2 26 Feb 07 jari 323     
2 26 Feb 07 jari 324     public void setProperties(float zeroThreshold, int min, int max){
2 26 Feb 07 jari 325         minNodeHeight = min;
2 26 Feb 07 jari 326         maxNodeHeight = max;
2 26 Feb 07 jari 327         treeHeight = getTreeHeight();  //resets to current height
2 26 Feb 07 jari 328         if(orientation == SOTATree.HORIZONTAL)            
2 26 Feb 07 jari 329             setSizes(getTreeHeight(), getTreeWidth());
2 26 Feb 07 jari 330         else
2 26 Feb 07 jari 331             setSizes(getTreeWidth(), getTreeHeight());
2 26 Feb 07 jari 332     }
2 26 Feb 07 jari 333     
2 26 Feb 07 jari 334     
2 26 Feb 07 jari 335 }