mev-4.0.01/source/org/tigr/microarray/mev/cluster/gui/impl/lem/LEMGraphViewer.java

Code
Comments
Other
Rev Date Author Line
2 26 Feb 07 jari 1 /*
2 26 Feb 07 jari 2  Copyright @ 1999-2006, 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 package org.tigr.microarray.mev.cluster.gui.impl.lem;
2 26 Feb 07 jari 7
2 26 Feb 07 jari 8 import java.awt.AlphaComposite;
2 26 Feb 07 jari 9 import java.awt.BasicStroke;
2 26 Feb 07 jari 10 import java.awt.Color;
2 26 Feb 07 jari 11 import java.awt.Component;
2 26 Feb 07 jari 12 import java.awt.Composite;
2 26 Feb 07 jari 13 import java.awt.Cursor;
2 26 Feb 07 jari 14 import java.awt.Dimension;
2 26 Feb 07 jari 15 import java.awt.Font;
2 26 Feb 07 jari 16 import java.awt.FontMetrics;
2 26 Feb 07 jari 17 import java.awt.Graphics;
2 26 Feb 07 jari 18 import java.awt.Graphics2D;
2 26 Feb 07 jari 19 import java.awt.Rectangle;
2 26 Feb 07 jari 20 import java.awt.RenderingHints;
2 26 Feb 07 jari 21 import java.awt.Stroke;
2 26 Feb 07 jari 22 import java.awt.event.MouseEvent;
2 26 Feb 07 jari 23 import java.awt.image.BufferedImage;
2 26 Feb 07 jari 24 import java.beans.Expression;
2 26 Feb 07 jari 25 import java.text.DecimalFormat;
2 26 Feb 07 jari 26 import java.util.Hashtable;
2 26 Feb 07 jari 27 import java.util.Vector;
2 26 Feb 07 jari 28
2 26 Feb 07 jari 29 import javax.swing.JComponent;
2 26 Feb 07 jari 30 import javax.swing.JPanel;
2 26 Feb 07 jari 31 import javax.swing.JViewport;
2 26 Feb 07 jari 32
2 26 Feb 07 jari 33 import org.tigr.microarray.mev.cluster.clusterUtil.Cluster;
2 26 Feb 07 jari 34 import org.tigr.microarray.mev.cluster.gui.Experiment;
2 26 Feb 07 jari 35 import org.tigr.microarray.mev.cluster.gui.IData;
2 26 Feb 07 jari 36 import org.tigr.microarray.mev.cluster.gui.IDisplayMenu;
2 26 Feb 07 jari 37 import org.tigr.microarray.mev.cluster.gui.IFramework;
2 26 Feb 07 jari 38 import org.tigr.microarray.mev.cluster.gui.IViewer;
2 26 Feb 07 jari 39
2 26 Feb 07 jari 40
2 26 Feb 07 jari 41 /**
2 26 Feb 07 jari 42  * @author braisted
2 26 Feb 07 jari 43  * 
2 26 Feb 07 jari 44  * Basic JPanel extension for rendering a graph
2 26 Feb 07 jari 45  * 
2 26 Feb 07 jari 46  */
2 26 Feb 07 jari 47 public class LEMGraphViewer extends JPanel implements IViewer {
2 26 Feb 07 jari 48
2 26 Feb 07 jari 49   protected LEMGraphHeader header;
2 26 Feb 07 jari 50   
2 26 Feb 07 jari 51   protected Experiment experiment;
2 26 Feb 07 jari 52   protected IFramework framework;
2 26 Feb 07 jari 53   protected IDisplayMenu displayMenu;
2 26 Feb 07 jari 54   protected IData data;
2 26 Feb 07 jari 55   protected int clusterIndex;
2 26 Feb 07 jari 56
2 26 Feb 07 jari 57   protected int yRangeOption;
2 26 Feb 07 jari 58
2 26 Feb 07 jari 59   protected float[][] means;
2 26 Feb 07 jari 60   protected String [] locusNames;
2 26 Feb 07 jari 61   protected int [] start;
2 26 Feb 07 jari 62   protected int [] end;
2 26 Feb 07 jari 63
2 26 Feb 07 jari 64   protected float minValue, maxValue, midValue = 0.0f;
2 26 Feb 07 jari 65   //protected float minDisplayValue, maxDisplayValue;
2 26 Feb 07 jari 66   protected float ticInterval;
2 26 Feb 07 jari 67   
2 26 Feb 07 jari 68   protected boolean drawReferenceBlock = true;
2 26 Feb 07 jari 69   protected int xref = 0;
2 26 Feb 07 jari 70   protected int yref = 0;
2 26 Feb 07 jari 71   protected int currLocusIndex;
2 26 Feb 07 jari 72   protected boolean showRefLine = false;
2 26 Feb 07 jari 73   
2 26 Feb 07 jari 74   protected boolean [] showSample;
2 26 Feb 07 jari 75   protected Color [] sampleColors;
2 26 Feb 07 jari 76   protected boolean showLocusInfo = false;
2 26 Feb 07 jari 77   protected boolean shadeLocusRanges;
2 26 Feb 07 jari 78   
2 26 Feb 07 jari 79   protected Vector sampleLineColors;
2 26 Feb 07 jari 80   protected Vector sampleMarkerColors;
2 26 Feb 07 jari 81   protected String title;
2 26 Feb 07 jari 82   protected int numberOfSamples;
2 26 Feb 07 jari 83   protected boolean overlay = false;
2 26 Feb 07 jari 84   protected FontMetrics fm;
2 26 Feb 07 jari 85   protected int MIN_GRAPH_WIDTH = 400;
2 26 Feb 07 jari 86   
2 26 Feb 07 jari 87   //y Range variables
2 26 Feb 07 jari 88   protected int yRangeMode;
2 26 Feb 07 jari 89   protected boolean useSymetricYRange;
2 26 Feb 07 jari 90   protected boolean showXAxis = true;
2 26 Feb 07 jari 91   protected BasicStroke xAxisStroke;
2 26 Feb 07 jari 92   protected Color xAxisColor = Color.lightGray;
2 26 Feb 07 jari 93   protected float xAxisCrossPoint = 0f;
2 26 Feb 07 jari 94   
2 26 Feb 07 jari 95   protected Vector yLabels;
2 26 Feb 07 jari 96   protected int xGraphInset = 40;
2 26 Feb 07 jari 97   protected boolean xGraphInsetInitialized = false;
2 26 Feb 07 jari 98   
2 26 Feb 07 jari 99   //related to offset mode
2 26 Feb 07 jari 100   protected boolean offsetLinesMode = true;
2 26 Feb 07 jari 101   protected Color posColor = Color.red;
2 26 Feb 07 jari 102   protected Color negColor = Color.green;
2 26 Feb 07 jari 103   protected float offsetGraphMidpoint = 0f;
2 26 Feb 07 jari 104   
2 26 Feb 07 jari 105   //related to digitized option
2 26 Feb 07 jari 106   protected boolean showOverlay = false;
2 26 Feb 07 jari 107   protected float upperCutoff;
2 26 Feb 07 jari 108   protected float lowerCutoff;
2 26 Feb 07 jari 109   protected float neutralPoint = 0f;
2 26 Feb 07 jari 110   
2 26 Feb 07 jari 111   protected boolean cursorOn = false;
2 26 Feb 07 jari 112   
2 26 Feb 07 jari 113   //to support zoom feature
2 26 Feb 07 jari 114   boolean inDragMode = false;  
2 26 Feb 07 jari 115   protected int startIndex;
2 26 Feb 07 jari 116   protected int endIndex;
2 26 Feb 07 jari 117   protected int dragStartX;
2 26 Feb 07 jari 118   protected int dragStopX;
2 26 Feb 07 jari 119   
2 26 Feb 07 jari 120   private int exptID = 0;
2 26 Feb 07 jari 121   
2 26 Feb 07 jari 122   public LEMGraphViewer() { }
2 26 Feb 07 jari 123   
2 26 Feb 07 jari 124   public LEMGraphViewer(Experiment experiment, float [][] data, String title, Hashtable properties, String [] locusNames, int [] start, int [] end) {
2 26 Feb 07 jari 125     if (experiment == null) {
2 26 Feb 07 jari 126       throw new IllegalArgumentException("experiment == null");
2 26 Feb 07 jari 127     }
2 26 Feb 07 jari 128     this.experiment = experiment;
2 26 Feb 07 jari 129     this.exptID = experiment.getId();
2 26 Feb 07 jari 130     numberOfSamples = this.experiment.getNumberOfSamples();
2 26 Feb 07 jari 131     this.means = data;
2 26 Feb 07 jari 132     this.showSample = new boolean[experiment.getNumberOfSamples()];
2 26 Feb 07 jari 133     this.title = title;
2 26 Feb 07 jari 134     this.locusNames = locusNames;
2 26 Feb 07 jari 135     this.start = start;
2 26 Feb 07 jari 136     this.end = end;
2 26 Feb 07 jari 137     
2 26 Feb 07 jari 138     this.header = new LEMGraphHeader();
2 26 Feb 07 jari 139     
2 26 Feb 07 jari 140     startIndex = 0;
2 26 Feb 07 jari 141     endIndex = data.length-1;
2 26 Feb 07 jari 142     
2 26 Feb 07 jari 143     setBackground(Color.white);
2 26 Feb 07 jari 144     setFont(new Font("monospaced", Font.BOLD, 10));
2 26 Feb 07 jari 145     //this.maxExperimentValue = experiment.getMaxAbsValue();
2 26 Feb 07 jari 146
2 26 Feb 07 jari 147     this.yRangeMode = ((Integer)(properties.get("y-range-mode"))).intValue();
2 26 Feb 07 jari 148     this.useSymetricYRange = ((Boolean)(properties.get("y-axis-symetry"))).booleanValue();
2 26 Feb 07 jari 149     
2 26 Feb 07 jari 150     this.showXAxis = ((Boolean)(properties.get("show-x-axis"))).booleanValue();
2 26 Feb 07 jari 151     this.xAxisColor = (Color) (properties.get("x-axis-color"));
2 26 Feb 07 jari 152     this.xAxisStroke = (BasicStroke)(properties.get("x-axis-stroke"));
2 26 Feb 07 jari 153     
2 26 Feb 07 jari 154     this.overlay = ((Boolean)(properties.get("is-overlay-mode"))).booleanValue();        
2 26 Feb 07 jari 155     this.offsetLinesMode = ((Boolean)(properties.get("offset-lines-mode"))).booleanValue();
2 26 Feb 07 jari 156     this.offsetGraphMidpoint = ((Float)(properties.get("offset-graph-midpoint"))).floatValue();
2 26 Feb 07 jari 157     this.neutralPoint = offsetGraphMidpoint;    
2 26 Feb 07 jari 158     this.lowerCutoff = ((Float)(properties.get("offset-graph-min"))).floatValue();
2 26 Feb 07 jari 159     this.upperCutoff = ((Float)(properties.get("offset-graph-max"))).floatValue();
2 26 Feb 07 jari 160     this.showOverlay = ((Boolean)(properties.get("show-discrete-overlay"))).booleanValue();
2 26 Feb 07 jari 161     
2 26 Feb 07 jari 162     constructYAxisLabels();
2 26 Feb 07 jari 163
2 26 Feb 07 jari 164     GraphListener listener = new GraphListener();
2 26 Feb 07 jari 165     this.addMouseMotionListener(listener);                  
2 26 Feb 07 jari 166     this.addMouseListener(listener);    
2 26 Feb 07 jari 167   }
2 26 Feb 07 jari 168   
2 26 Feb 07 jari 169   /* (non-Javadoc)
2 26 Feb 07 jari 170    * @see org.tigr.microarray.mev.cluster.gui.IViewer#getExpression()
2 26 Feb 07 jari 171    */
2 26 Feb 07 jari 172   public Expression getExpression() {
2 26 Feb 07 jari 173     return null;
2 26 Feb 07 jari 174   } 
2 26 Feb 07 jari 175
2 26 Feb 07 jari 176   /* (non-Javadoc)
2 26 Feb 07 jari 177    * @see org.tigr.microarray.mev.cluster.gui.IViewer#setExperiment(org.tigr.microarray.mev.cluster.gui.Experiment)
2 26 Feb 07 jari 178    */
2 26 Feb 07 jari 179   public void setExperiment(Experiment e) {
2 26 Feb 07 jari 180     this.experiment = e;
2 26 Feb 07 jari 181     this.exptID = e.getId();
2 26 Feb 07 jari 182     numberOfSamples = this.experiment.getNumberOfSamples();
2 26 Feb 07 jari 183     this.showSample = new boolean[experiment.getNumberOfSamples()];
2 26 Feb 07 jari 184     this.header = new LEMGraphHeader();
2 26 Feb 07 jari 185     startIndex = 0;
2 26 Feb 07 jari 186     endIndex = means.length-1;
2 26 Feb 07 jari 187
2 26 Feb 07 jari 188     GraphListener listener = new GraphListener();
2 26 Feb 07 jari 189     this.addMouseMotionListener(listener);                  
2 26 Feb 07 jari 190     this.addMouseListener(listener);    
2 26 Feb 07 jari 191   }
2 26 Feb 07 jari 192   /**
2 26 Feb 07 jari 193    * Sets means values.
2 26 Feb 07 jari 194    */
2 26 Feb 07 jari 195   public void setMeans(float[][] means) {
2 26 Feb 07 jari 196     this.means = means;
2 26 Feb 07 jari 197   }
2 26 Feb 07 jari 198   
2 26 Feb 07 jari 199   
2 26 Feb 07 jari 200   /**
2 26 Feb 07 jari 201    * Sets overlay mode
2 26 Feb 07 jari 202    * @param overlayEnabled value to set overlay mode
2 26 Feb 07 jari 203    */
2 26 Feb 07 jari 204   public void enableOverlay(boolean overlayEnabled) {
2 26 Feb 07 jari 205     overlay = overlayEnabled;
2 26 Feb 07 jari 206     if(!overlay) {
2 26 Feb 07 jari 207       setSize(MIN_GRAPH_WIDTH, numberOfSamples*190+40);
2 26 Feb 07 jari 208       setPreferredSize(new Dimension(getWidth(), numberOfSamples*190+40));
2 26 Feb 07 jari 209     } else {
2 26 Feb 07 jari 210       setSize(MIN_GRAPH_WIDTH, 400);
2 26 Feb 07 jari 211       setPreferredSize(new Dimension(getWidth(), 400));        
2 26 Feb 07 jari 212     }      
2 26 Feb 07 jari 213   }
2 26 Feb 07 jari 214   
2 26 Feb 07 jari 215     
2 26 Feb 07 jari 216   /**
2 26 Feb 07 jari 217    * Updates data, mode and some the viewer attributes.
2 26 Feb 07 jari 218    */
2 26 Feb 07 jari 219   public void onSelected(IFramework framework) {
2 26 Feb 07 jari 220     this.framework = framework;
2 26 Feb 07 jari 221     this.displayMenu = framework.getDisplayMenu();
2 26 Feb 07 jari 222     setData(framework.getData());
2 26 Feb 07 jari 223         
2 26 Feb 07 jari 224     //update scale if it comes from the display menu
2 26 Feb 07 jari 225     if(yRangeMode == 0) {  //display mode
2 26 Feb 07 jari 226       this.maxValue = framework.getDisplayMenu().getMaxRatioScale();
2 26 Feb 07 jari 227       this.minValue = framework.getDisplayMenu().getMinRatioScale();
2 26 Feb 07 jari 228     }
2 26 Feb 07 jari 229
2 26 Feb 07 jari 230     refreshGraph();
2 26 Feb 07 jari 231   }
2 26 Feb 07 jari 232   
2 26 Feb 07 jari 233   /**
2 26 Feb 07 jari 234    * Sets data.
2 26 Feb 07 jari 235    */
2 26 Feb 07 jari 236   public void setData(IData data) {
2 26 Feb 07 jari 237     this.data = data;
2 26 Feb 07 jari 238   }
2 26 Feb 07 jari 239   
2 26 Feb 07 jari 240   /**
2 26 Feb 07 jari 241    * Returns a current cluster.
2 26 Feb 07 jari 242    */
2 26 Feb 07 jari 243   public int[] getCluster() {
2 26 Feb 07 jari 244     return null;
2 26 Feb 07 jari 245     //return this.clusters[this.clusterIndex];
2 26 Feb 07 jari 246   }
2 26 Feb 07 jari 247   
2 26 Feb 07 jari 248   /**
2 26 Feb 07 jari 249    * Returns all clusters.
2 26 Feb 07 jari 250    */
2 26 Feb 07 jari 251   public int[][] getClusters() {
2 26 Feb 07 jari 252     return null;
2 26 Feb 07 jari 253     //return clusters;
2 26 Feb 07 jari 254   }
2 26 Feb 07 jari 255   
2 26 Feb 07 jari 256   /**
2 26 Feb 07 jari 257    * refreshes graph to current y limits
2 26 Feb 07 jari 258    */
2 26 Feb 07 jari 259   public void refreshGraph() {
2 26 Feb 07 jari 260     this.constructYAxisLabels();
2 26 Feb 07 jari 261     repaint();
2 26 Feb 07 jari 262   }
2 26 Feb 07 jari 263
2 26 Feb 07 jari 264   /**
2 26 Feb 07 jari 265    * Sets the y range mode, custom or menu driven
2 26 Feb 07 jari 266    * @param mode
2 26 Feb 07 jari 267    */
2 26 Feb 07 jari 268   public void setYAxisRangeMode(int mode) {
2 26 Feb 07 jari 269     this.yRangeMode = mode;
2 26 Feb 07 jari 270     if(mode == 0) {  //display menu
2 26 Feb 07 jari 271       maxValue = displayMenu.getMaxRatioScale();
2 26 Feb 07 jari 272       minValue = displayMenu.getMinRatioScale();
2 26 Feb 07 jari 273       refreshGraph();
2 26 Feb 07 jari 274     }
2 26 Feb 07 jari 275   }
2 26 Feb 07 jari 276   
2 26 Feb 07 jari 277   private void updateYRangeAutoScale() {
2 26 Feb 07 jari 278     if(this.useSymetricYRange) {
2 26 Feb 07 jari 279       maxValue = experiment.getMaxAbsValue();
2 26 Feb 07 jari 280       minValue = maxValue*-1f;
2 26 Feb 07 jari 281     } else {
2 26 Feb 07 jari 282       float [] minAndMax = experiment.getMinAndMax(); 
2 26 Feb 07 jari 283       minValue = minAndMax[0];
2 26 Feb 07 jari 284       maxValue = minAndMax[1];
2 26 Feb 07 jari 285     }
2 26 Feb 07 jari 286   }
2 26 Feb 07 jari 287   
2 26 Feb 07 jari 288   /**
2 26 Feb 07 jari 289    * sets y range limits
2 26 Feb 07 jari 290    * @param min min limit
2 26 Feb 07 jari 291    * @param max max limit
2 26 Feb 07 jari 292    */
2 26 Feb 07 jari 293   public void setYRange(float min, float max) {
2 26 Feb 07 jari 294     minValue = min;
2 26 Feb 07 jari 295     maxValue = max;
2 26 Feb 07 jari 296   }
2 26 Feb 07 jari 297   
2 26 Feb 07 jari 298   /**
2 26 Feb 07 jari 299    * Sets tick interval
2 26 Feb 07 jari 300    * @param ticInterval tick interval
2 26 Feb 07 jari 301    */
2 26 Feb 07 jari 302   public void setTicInterval(float ticInterval) {
2 26 Feb 07 jari 303     this.ticInterval = ticInterval;
2 26 Feb 07 jari 304   }
2 26 Feb 07 jari 305   
2 26 Feb 07 jari 306   /**
2 26 Feb 07 jari 307    * True if selected to show x axis line.
2 26 Feb 07 jari 308    * @param showXAxis
2 26 Feb 07 jari 309    */
2 26 Feb 07 jari 310   public void setShowXAxis(boolean showXAxis) {
2 26 Feb 07 jari 311     this.showXAxis = showXAxis;
2 26 Feb 07 jari 312   }
2 26 Feb 07 jari 313   
2 26 Feb 07 jari 314   /**
2 26 Feb 07 jari 315    * Sets x axis stroke options
2 26 Feb 07 jari 316    * @param stroke basic stroke
2 26 Feb 07 jari 317    */
2 26 Feb 07 jari 318   public void setXAxisStroke(BasicStroke stroke) {
2 26 Feb 07 jari 319     this.xAxisStroke = stroke;
2 26 Feb 07 jari 320   }
2 26 Feb 07 jari 321   
2 26 Feb 07 jari 322   /**
2 26 Feb 07 jari 323    * sets  the y-value that the x axix crosses (often 0)
2 26 Feb 07 jari 324    * @param xAxisCrossPoint
2 26 Feb 07 jari 325    */
2 26 Feb 07 jari 326   public void setXAxisCrossPoint(float xAxisCrossPoint) {
2 26 Feb 07 jari 327     this.xAxisCrossPoint = xAxisCrossPoint;
2 26 Feb 07 jari 328   }
2 26 Feb 07 jari 329   
2 26 Feb 07 jari 330   /**
2 26 Feb 07 jari 331    * sets the x axis color
2 26 Feb 07 jari 332    * @param axisColor
2 26 Feb 07 jari 333    */
2 26 Feb 07 jari 334   public void setXAxisColor(Color axisColor) {
2 26 Feb 07 jari 335     this.xAxisColor = axisColor;
2 26 Feb 07 jari 336   }
2 26 Feb 07 jari 337   
2 26 Feb 07 jari 338   /**
2 26 Feb 07 jari 339    * sets y axis symitric for auto-scale mode
2 26 Feb 07 jari 340    * 
2 26 Feb 07 jari 341    * (Auto scale mode is not utilized as an option
2 26 Feb 07 jari 342    * at this time)
2 26 Feb 07 jari 343    * 
2 26 Feb 07 jari 344    * @param isSymetric
2 26 Feb 07 jari 345    */
2 26 Feb 07 jari 346   public void setYAxisSymetry(boolean isSymetric) {
2 26 Feb 07 jari 347     this.useSymetricYRange = isSymetric;
2 26 Feb 07 jari 348   }
2 26 Feb 07 jari 349     
2 26 Feb 07 jari 350   /**
2 26 Feb 07 jari 351    * enables offset line mode for viewer mode option
2 26 Feb 07 jari 352    * alternative is the connected points option
2 26 Feb 07 jari 353    * @param enable
2 26 Feb 07 jari 354    */
2 26 Feb 07 jari 355   public void enableOffsetLinesMode(boolean enable) {
2 26 Feb 07 jari 356     this.offsetLinesMode = enable;
2 26 Feb 07 jari 357   }
2 26 Feb 07 jari 358   
2 26 Feb 07 jari 359   /**
2 26 Feb 07 jari 360    * Sets the midpoint or 'anchor value' for offset lines option
2 26 Feb 07 jari 361    * @param val 'anchor' values
2 26 Feb 07 jari 362    */
2 26 Feb 07 jari 363   public void setOffsetLinesMidpoint(float val) {
2 26 Feb 07 jari 364     this.offsetGraphMidpoint = val;
2 26 Feb 07 jari 365   }
2 26 Feb 07 jari 366   
2 26 Feb 07 jari 367   /**
2 26 Feb 07 jari 368    * sets the limits for rendering offset line color
2 26 Feb 07 jari 369    * @param val
2 26 Feb 07 jari 370    */
2 26 Feb 07 jari 371   public void setOffsetLinesMin(float val) {
2 26 Feb 07 jari 372     this.lowerCutoff = val;
2 26 Feb 07 jari 373   }
2 26 Feb 07 jari 374   
2 26 Feb 07 jari 375   /**
2 26 Feb 07 jari 376    * Sets the offset lines option's max offset to render line color
2 26 Feb 07 jari 377    * @param val
2 26 Feb 07 jari 378    */
2 26 Feb 07 jari 379   public void setOffsetLinesMax(float val) {
2 26 Feb 07 jari 380     this.upperCutoff = val;
2 26 Feb 07 jari 381   }
2 26 Feb 07 jari 382
2 26 Feb 07 jari 383   /**
2 26 Feb 07 jari 384    * Enables or disables discrete value overlay mode
2 26 Feb 07 jari 385    * @param enable
2 26 Feb 07 jari 386    */
2 26 Feb 07 jari 387   public void enableDiscreteValueOverlay(boolean enable) {
2 26 Feb 07 jari 388     this.showOverlay = enable;
2 26 Feb 07 jari 389   }
2 26 Feb 07 jari 390     
2 26 Feb 07 jari 391   /**
2 26 Feb 07 jari 392    * Toggles the reference line option
2 26 Feb 07 jari 393    */
2 26 Feb 07 jari 394     public void toggleReferenceLine() {
2 26 Feb 07 jari 395     showRefLine = !showRefLine;
2 26 Feb 07 jari 396     if(showRefLine)
2 26 Feb 07 jari 397       this.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
2 26 Feb 07 jari 398     else
2 26 Feb 07 jari 399       this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
2 26 Feb 07 jari 400     repaint();
2 26 Feb 07 jari 401   }
2 26 Feb 07 jari 402   
2 26 Feb 07 jari 403   /**
2 26 Feb 07 jari 404    * Sets the current graph to be displayed
2 26 Feb 07 jari 405    * @param index
2 26 Feb 07 jari 406    */
2 26 Feb 07 jari 407   public void setCurrentGraph(int index) {
2 26 Feb 07 jari 408     //dump graphs
2 26 Feb 07 jari 409     clearGraphs();
2 26 Feb 07 jari 410     //set current graph
2 26 Feb 07 jari 411     this.showSample[index] = true;
2 26 Feb 07 jari 412   }
2 26 Feb 07 jari 413   
2 26 Feb 07 jari 414   /**
2 26 Feb 07 jari 415    * sets the graphs to display as a list of graph indices
2 26 Feb 07 jari 416    * @param graphIndexList list o graph indices.
2 26 Feb 07 jari 417    */
2 26 Feb 07 jari 418   public void setGraphsToDisplay(int [] graphIndexList) {
2 26 Feb 07 jari 419     clearGraphs();
2 26 Feb 07 jari 420     for(int i = 0; i < graphIndexList.length; i++) {
2 26 Feb 07 jari 421       showSample[graphIndexList[i]] = true;
2 26 Feb 07 jari 422     }
2 26 Feb 07 jari 423     repaint();
2 26 Feb 07 jari 424   }
2 26 Feb 07 jari 425   
2 26 Feb 07 jari 426   /**
2 26 Feb 07 jari 427    * Resets the x range to show all loci points
2 26 Feb 07 jari 428    * (Zoom out)
2 26 Feb 07 jari 429    */
2 26 Feb 07 jari 430   public void resetXRange() {
2 26 Feb 07 jari 431     startIndex = 0;
2 26 Feb 07 jari 432     endIndex = means.length-1;
2 26 Feb 07 jari 433     header.resetLimits();
2 26 Feb 07 jari 434     repaint();
2 26 Feb 07 jari 435   }
2 26 Feb 07 jari 436   
2 26 Feb 07 jari 437   /**
2 26 Feb 07 jari 438    * Returns a <code>Hashtable</code> of graph properties
2 26 Feb 07 jari 439    * @return hash of current proerties
2 26 Feb 07 jari 440    */
2 26 Feb 07 jari 441   public Hashtable getGraphProperties() {
2 26 Feb 07 jari 442     Hashtable props = new Hashtable();
2 26 Feb 07 jari 443     
2 26 Feb 07 jari 444     props.put("is-overlay-mode", new Boolean(overlay));
2 26 Feb 07 jari 445     props.put("y-range-mode", new Integer(this.yRangeMode));      
2 26 Feb 07 jari 446     props.put("y-axis-min", new Float(this.minValue));
2 26 Feb 07 jari 447     props.put("y-axis-max", new Float(this.maxValue));
2 26 Feb 07 jari 448     props.put("y-axis-tic-interval", new Float(this.ticInterval));
2 26 Feb 07 jari 449     props.put("y-axis-symetry", new Boolean(this.useSymetricYRange));
2 26 Feb 07 jari 450     
2 26 Feb 07 jari 451     props.put("show-x-axis", new Boolean(this.showXAxis));      
2 26 Feb 07 jari 452     props.put("x-axis-color", this.xAxisColor);
2 26 Feb 07 jari 453     props.put("x-axis-stroke", this.xAxisStroke);
2 26 Feb 07 jari 454     props.put("x-axis-cross-point", new Float(this.xAxisCrossPoint));
2 26 Feb 07 jari 455     
2 26 Feb 07 jari 456     props.put("offset-lines-mode", new Boolean(this.offsetLinesMode));
2 26 Feb 07 jari 457     props.put("offset-graph-midpoint", new Float(this.offsetGraphMidpoint));
2 26 Feb 07 jari 458     props.put("offset-graph-min", new Float(this.lowerCutoff));
2 26 Feb 07 jari 459     props.put("offset-graph-max", new Float(this.upperCutoff));
2 26 Feb 07 jari 460     props.put("show-discrete-overlay", new Boolean(this.showOverlay));          
2 26 Feb 07 jari 461
2 26 Feb 07 jari 462     return props;
2 26 Feb 07 jari 463   }
2 26 Feb 07 jari 464   
2 26 Feb 07 jari 465   /**
2 26 Feb 07 jari 466    * resets showSample field to all false
2 26 Feb 07 jari 467    */
2 26 Feb 07 jari 468   public void clearGraphs() {
2 26 Feb 07 jari 469     for(int i = 0; i < showSample.length; i++)
2 26 Feb 07 jari 470       showSample[i] = false;
2 26 Feb 07 jari 471   }
2 26 Feb 07 jari 472
2 26 Feb 07 jari 473   /**
2 26 Feb 07 jari 474    * Returns the experiment data (ratio values).
2 26 Feb 07 jari 475    */
2 26 Feb 07 jari 476   public Experiment getExperiment() {
2 26 Feb 07 jari 477     return experiment;
2 26 Feb 07 jari 478   }
2 26 Feb 07 jari 479   
2 26 Feb 07 jari 480   /**
2 26 Feb 07 jari 481    * Returns data values.
2 26 Feb 07 jari 482    */
2 26 Feb 07 jari 483   public IData getData() {
2 26 Feb 07 jari 484     return data;
2 26 Feb 07 jari 485   }
2 26 Feb 07 jari 486   
2 26 Feb 07 jari 487   /**
2 26 Feb 07 jari 488    * Returns component to be displayed in the framework scroll pane.
2 26 Feb 07 jari 489    */
2 26 Feb 07 jari 490   public JComponent getContentComponent() {
2 26 Feb 07 jari 491     return this;
2 26 Feb 07 jari 492   }
2 26 Feb 07 jari 493   
2 26 Feb 07 jari 494   /**
2 26 Feb 07 jari 495    * Paints chart into specified graphics.  Splits on overlay vs. tile option
2 26 Feb 07 jari 496    * 
2 26 Feb 07 jari 497    */
2 26 Feb 07 jari 498   public void paint(Graphics g) {
2 26 Feb 07 jari 499     super.paint(g);
2 26 Feb 07 jari 500     
2 26 Feb 07 jari 501     g.setFont(new Font("Monospaced", Font.BOLD, 18));            
2 26 Feb 07 jari 502     fm = g.getFontMetrics();
2 26 Feb 07 jari 503     
2 26 Feb 07 jari 504     //use FontMetrics to determine graph left inset
2 26 Feb 07 jari 505     if(!xGraphInsetInitialized)
2 26 Feb 07 jari 506       this.setXGraphInset();
2 26 Feb 07 jari 507     
2 26 Feb 07 jari 508     Graphics2D g2 = (Graphics2D)g;
2 26 Feb 07 jari 509     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
2 26 Feb 07 jari 510     g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
2 26 Feb 07 jari 511     
2 26 Feb 07 jari 512     if(overlay)
2 26 Feb 07 jari 513       overlayPaint(g);
2 26 Feb 07 jari 514     else
2 26 Feb 07 jari 515       multiGraphPaint(g);
2 26 Feb 07 jari 516   }
2 26 Feb 07 jari 517   
2 26 Feb 07 jari 518   /** Defines a view rectangle and clip rectangle for rendering graphs in
2 26 Feb 07 jari 519    * overlay mode.
2 26 Feb 07 jari 520    * 
2 26 Feb 07 jari 521    * @param g <code>Graphics</code> object
2 26 Feb 07 jari 522    */
2 26 Feb 07 jari 523   public void overlayPaint(Graphics g) {
2 26 Feb 07 jari 524     Rectangle rect = new Rectangle(xGraphInset, 40, getWidth()-xGraphInset-40, getHeight()-50);
2 26 Feb 07 jari 525
2 26 Feb 07 jari 526     Rectangle clipRect = ((JViewport)(this.getParent())).getViewRect();
2 26 Feb 07 jari 527     g.setColor(Color.black);
2 26 Feb 07 jari 528     g.drawString(title, getWidth()/2 - fm.stringWidth(title)/2, rect.y - 15);
2 26 Feb 07 jari 529     paint((Graphics2D)g, rect, true, true, clipRect);      
2 26 Feb 07 jari 530   }
2 26 Feb 07 jari 531   
2 26 Feb 07 jari 532   /** Defines a viewer rectangle and a clip rectangle for rendering graphs
2 26 Feb 07 jari 533    * in a tile view.  Iterates over several Samples to tile the view.
2 26 Feb 07 jari 534    * 
2 26 Feb 07 jari 535    * @param g <code>Graphics</code> object
2 26 Feb 07 jari 536    */
2 26 Feb 07 jari 537   public void multiGraphPaint(Graphics g) {
2 26 Feb 07 jari 538     int yOffset = 40;    
2 26 Feb 07 jari 539     int yGraphH = 150;
2 26 Feb 07 jari 540     
2 26 Feb 07 jari 541     Rectangle clipRect = ((JViewport)(this.getParent().getParent())).getViewRect();
2 26 Feb 07 jari 542     
2 26 Feb 07 jari 543     Component c = this.getParent();
2 26 Feb 07 jari 544     
2 26 Feb 07 jari 545     for(int plot = 0; plot < numberOfSamples; plot++) {
2 26 Feb 07 jari 546       setCurrentGraph(plot);        
2 26 Feb 07 jari 547       
2 26 Feb 07 jari 548       Rectangle rect = new Rectangle(xGraphInset, (plot*(yGraphH+40))+40, getWidth()-xGraphInset-40, yGraphH); 
2 26 Feb 07 jari 549       //g.clearRect(40, (plot*(yGraphH+40))+1, getWidth()-80, yGraphH+40);
2 26 Feb 07 jari 550       g.setColor(Color.black);
2 26 Feb 07 jari 551       g.drawString(data.getSampleName(plot)+" -- "+title, xGraphInset + getWidth()/2 - fm.stringWidth(data.getSampleName(plot)+" -- "+title)/2, rect.y - 15);
2 26 Feb 07 jari 552       
2 26 Feb 07 jari 553       if(clipRect.intersects(rect)) {        
2 26 Feb 07 jari 554         //paint((Graphics2D)g, rect, true, clipRect.contains(rect), clipRect);              
2 26 Feb 07 jari 555         paint((Graphics2D)g, rect, true, true, clipRect);                          
2 26 Feb 07 jari 556       }        
2 26 Feb 07 jari 557     }
2 26 Feb 07 jari 558   }
2 26 Feb 07 jari 559   
2 26 Feb 07 jari 560   /**
2 26 Feb 07 jari 561    * Sets the line colors
2 26 Feb 07 jari 562    * @param lineColors line colors
2 26 Feb 07 jari 563    */
2 26 Feb 07 jari 564   public void setSampleLineColors(Vector lineColors) {
2 26 Feb 07 jari 565     this.sampleLineColors = lineColors;
2 26 Feb 07 jari 566   }
2 26 Feb 07 jari 567   
2 26 Feb 07 jari 568   /**
2 26 Feb 07 jari 569    * sets the marker colors
2 26 Feb 07 jari 570    * @param markerColors marker colors
2 26 Feb 07 jari 571    */
2 26 Feb 07 jari 572   public void setSampleMarkerColors(Vector markerColors) {
2 26 Feb 07 jari 573     this.sampleMarkerColors = markerColors;
2 26 Feb 07 jari 574   }
2 26 Feb 07 jari 575   
2 26 Feb 07 jari 576   /**
2 26 Feb 07 jari 577    * Paints chart into specified graphics and with specified bounds.
2 26 Feb 07 jari 578    */
2 26 Feb 07 jari 579   public void paint(Graphics2D g, Rectangle rect, boolean drawMarks, boolean applyClip, Rectangle originalClip) {
2 26 Feb 07 jari 580     
2 26 Feb 07 jari 581     final int left = rect.x;
2 26 Feb 07 jari 582     final int top = rect.y;
2 26 Feb 07 jari 583     final int width  = rect.width;
2 26 Feb 07 jari 584     final int height = rect.height;
2 26 Feb 07 jari 585     
2 26 Feb 07 jari 586     if (width < 5 || height < 5) {
2 26 Feb 07 jari 587       return;
2 26 Feb 07 jari 588     }
2 26 Feb 07 jari 589     
2 26 Feb 07 jari 590     final int numberOfSamples  = experiment.getNumberOfSamples();        
2 26 Feb 07 jari 591     final float factor = height/(maxValue - minValue);    
2 26 Feb 07 jari 592     final int zeroValue = top + (int)Math.round(factor*(maxValue-0f));            
2 26 Feb 07 jari 593     final float stepX  = width/(float)((endIndex-startIndex)-1);    
2 26 Feb 07 jari 594     final int   stepsY = (int)maxValue+1;    
2 26 Feb 07 jari 595     float fValue, sValue = 0, yInterval, lineHeight;
2 26 Feb 07 jari 596     Color lineColor = Color.gray;
2 26 Feb 07 jari 597     Color markerColor = Color.blue;
2 26 Feb 07 jari 598     
2 26 Feb 07 jari 599     //clip computation        
2 26 Feb 07 jari 600     int clipX = Math.max(rect.x-2, originalClip.x);
2 26 Feb 07 jari 601     int clipY = Math.max(rect.y, originalClip.y);
2 26 Feb 07 jari 602     int clipRectWidth = Math.min(rect.width+5, originalClip.width-Math.max(0,rect.x-2-originalClip.x));//-rect.width-clipX);        
2 26 Feb 07 jari 603     int clipRectHeight = Math.min(rect.height+rect.y-clipY, originalClip.y+originalClip.height-clipY);
2 26 Feb 07 jari 604     
2 26 Feb 07 jari 605     if(applyClip)
2 26 Feb 07 jari 606       g.setClip(clipX, clipY, clipRectWidth, clipRectHeight);
2 26 Feb 07 jari 607     
2 26 Feb 07 jari 608     Graphics2D g2 = (Graphics2D)g;
2 26 Feb 07 jari 609     Composite defaultComp = g2.getComposite();    
2 26 Feb 07 jari 610     Composite overlayComp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
2 26 Feb 07 jari 611     Stroke defaultStroke = g2.getStroke();
2 26 Feb 07 jari 612     BasicStroke overlayStroke = new BasicStroke(2f);
2 26 Feb 07 jari 613     
2 26 Feb 07 jari 614     g2.setComposite(defaultComp);
2 26 Feb 07 jari 615     g2.setColor(Color.black);
2 26 Feb 07 jari 616     
2 26 Feb 07 jari 617     int x1 = 0, x2 = 0;
2 26 Feb 07 jari 618     float prevY = this.offsetGraphMidpoint;
2 26 Feb 07 jari 619     float currY = this.offsetGraphMidpoint;
2 26 Feb 07 jari 620     
2 26 Feb 07 jari 621     for(int sample = 0; sample < numberOfSamples; sample++) {
2 26 Feb 07 jari 622       
2 26 Feb 07 jari 623       if(overlay) {
2 26 Feb 07 jari 624         lineColor = (Color)sampleLineColors.get(sample);          
2 26 Feb 07 jari 625         markerColor = (Color)sampleMarkerColors.get(sample);
2 26 Feb 07 jari 626       }
2 26 Feb 07 jari 627       
2 26 Feb 07 jari 628       //short circuit if the sample is not to be displayed
2 26 Feb 07 jari 629       if(!this.showSample[sample])
2 26 Feb 07 jari 630         continue;
2 26 Feb 07 jari 631       
2 26 Feb 07 jari 632       if(!this.offsetLinesMode) {
2 26 Feb 07 jari 633         for(int gene = startIndex; gene < endIndex-1; gene++) {
2 26 Feb 07 jari 634           
2 26 Feb 07 jari 635           fValue = means[gene][sample];
2 26 Feb 07 jari 636           sValue = means[gene+1][sample];
2 26 Feb 07 jari 637           
2 26 Feb 07 jari 638           if(Float.isNaN(fValue)) {
2 26 Feb 07 jari 639             continue;
2 26 Feb 07 jari 640           }
2 26 Feb 07 jari 641           
2 26 Feb 07 jari 642           g.setColor((Color)(lineColor));
2 26 Feb 07 jari 643           
2 26 Feb 07 jari 644           if(!Float.isNaN(sValue)) {
2 26 Feb 07 jari 645             g.drawLine(left+(int)Math.round((gene-startIndex)*stepX), zeroValue - (int)Math.round(fValue*factor),
2 26 Feb 07 jari 646                 left+(int)Math.round(((gene-startIndex)+1)*stepX), zeroValue - (int)Math.round(sValue*factor));
2 26 Feb 07 jari 647             
2 26 Feb 07 jari 648             if(showOverlay)
2 26 Feb 07 jari 649               prevY = drawOverlayLine(g2, prevY, sValue, left+(int)Math.round((gene-startIndex)*stepX), left+(int)Math.round(((gene-startIndex)+1)*stepX), factor, zeroValue, 
2 26 Feb 07 jari 650                   defaultStroke, overlayStroke, overlayComp, defaultComp);              
2 26 Feb 07 jari 651           }
2 26 Feb 07 jari 652           
2 26 Feb 07 jari 653           g.setColor((Color)(markerColor));
2 26 Feb 07 jari 654           g.fillOval(left+(int)Math.round((gene-startIndex)*stepX)-2, zeroValue - (int)Math.round(fValue*factor)-2, 4,4);                    
2 26 Feb 07 jari 655         }
2 26 Feb 07 jari 656         
2 26 Feb 07 jari 657         // last point, must be a valid number and there has to be at least point rendered
2 26 Feb 07 jari 658         if(!Float.isNaN(sValue) && startIndex > endIndex-1)
2 26 Feb 07 jari 659               g.fillOval(left+(int)Math.round((endIndex-startIndex-1)*stepX)-1, zeroValue - (int)Math.round(sValue*factor)-2, 4,4);    
2 26 Feb 07 jari 660       } else {  //offset lines mode
2 26 Feb 07 jari 661         
2 26 Feb 07 jari 662         for(int gene = startIndex; gene < endIndex; gene++) {
2 26 Feb 07 jari 663           
2 26 Feb 07 jari 664           fValue = means[gene][sample];
2 26 Feb 07 jari 665           if(gene+1 < means.length)
2 26 Feb 07 jari 666             sValue = means[gene+1][sample];
2 26 Feb 07 jari 667           else
2 26 Feb 07 jari 668             sValue = Float.NaN;
2 26 Feb 07 jari 669           
2 26 Feb 07 jari 670           if(Float.isNaN(fValue)) {
2 26 Feb 07 jari 671             continue;
2 26 Feb 07 jari 672           }
2 26 Feb 07 jari 673           
2 26 Feb 07 jari 674           g.setColor((Color)(lineColor));
2 26 Feb 07 jari 675           
2 26 Feb 07 jari 676           if(fValue >= upperCutoff)
2 26 Feb 07 jari 677             g.setColor(posColor);
2 26 Feb 07 jari 678           else if(fValue <= lowerCutoff)
2 26 Feb 07 jari 679             g.setColor(negColor);
2 26 Feb 07 jari 680           else
2 26 Feb 07 jari 681             g.setColor(Color.black);          
2 26 Feb 07 jari 682           
2 26 Feb 07 jari 683           g.drawLine(left+(int)Math.round((gene-startIndex)*stepX), zeroValue - (int)Math.round(fValue*factor),
2 26 Feb 07 jari 684               left+(int)Math.round((gene-startIndex)*stepX), zeroValue - (int)Math.round(this.offsetGraphMidpoint*factor));
2 26 Feb 07 jari 685           
2 26 Feb 07 jari 686           g.setColor(Color.darkGray);
2 26 Feb 07 jari 687           g.fillOval(left+(int)Math.round((gene-startIndex)*stepX)-2, zeroValue - (int)Math.round(fValue*factor)-2, 4,4);                    
2 26 Feb 07 jari 688           
2 26 Feb 07 jari 689           if(showOverlay && !Float.isNaN(sValue))
2 26 Feb 07 jari 690             prevY = drawOverlayLine(g2, prevY, sValue, left+(int)Math.round((gene-startIndex)*stepX), left+(int)Math.round(((gene-startIndex)+1)*stepX), factor, zeroValue, defaultStroke, overlayStroke, overlayComp, defaultComp);          
2 26 Feb 07 jari 691           
2 26 Feb 07 jari 692         }        
2 26 Feb 07 jari 693       }      
2 26 Feb 07 jari 694     }
2 26 Feb 07 jari 695     
2 26 Feb 07 jari 696     //reset stroke
2 26 Feb 07 jari 697     g2.setStroke(defaultStroke);
2 26 Feb 07 jari 698     //reset composite
2 26 Feb 07 jari 699     g2.setComposite(defaultComp);
2 26 Feb 07 jari 700     
2 26 Feb 07 jari 701     //reset clip    
2 26 Feb 07 jari 702     if(applyClip)
2 26 Feb 07 jari 703       g.setClip(originalClip);
2 26 Feb 07 jari 704
2 26 Feb 07 jari 705     // draw rectangle
2 26 Feb 07 jari 706     g.setColor(Color.black);
2 26 Feb 07 jari 707     g.drawRect(left, top, width, height);
2 26 Feb 07 jari 708       
2 26 Feb 07 jari 709     String str;
2 26 Feb 07 jari 710     int strWidth;
2 26 Feb 07 jari 711     
2 26 Feb 07 jari 712     float val;
2 26 Feb 07 jari 713     int yOffset;
2 26 Feb 07 jari 714     for(int i = 0; i < yLabels.size(); i++) {
2 26 Feb 07 jari 715       str = (String)(yLabels.get(i));
2 26 Feb 07 jari 716       val = Float.parseFloat(str);
2 26 Feb 07 jari 717       strWidth = fm.stringWidth(str);
2 26 Feb 07 jari 718       g.drawString(str, left-10-strWidth, zeroValue+5-(int)Math.round(val*factor));
2 26 Feb 07 jari 719       g.drawLine(left-5, zeroValue - (int)Math.round(val*factor), left, zeroValue-(int)Math.round(val*factor));            
2 26 Feb 07 jari 720     }
2 26 Feb 07 jari 721     
2 26 Feb 07 jari 722     
2 26 Feb 07 jari 723     //if show zero line
2 26 Feb 07 jari 724     if(this.showXAxis) {
2 26 Feb 07 jari 725       Stroke stroke = g.getStroke();
2 26 Feb 07 jari 726       Color initColor = g.getColor();
2 26 Feb 07 jari 727       
2 26 Feb 07 jari 728       g.setStroke(this.xAxisStroke);
2 26 Feb 07 jari 729       g.setColor(this.xAxisColor);
2 26 Feb 07 jari 730       g.drawLine(clipX, zeroValue - (int)Math.round(xAxisCrossPoint*factor), clipRectWidth+clipX, zeroValue - (int)Math.round(xAxisCrossPoint*factor));
2 26 Feb 07 jari 731       
2 26 Feb 07 jari 732       g.setColor(initColor);
2 26 Feb 07 jari 733       g.setStroke(stroke);
2 26 Feb 07 jari 734     }
2 26 Feb 07 jari 735     
2 26 Feb 07 jari 736     //drag shading
2 26 Feb 07 jari 737     if(inDragMode) {
2 26 Feb 07 jari 738       g.setColor(new Color(244, 250, 152));
2 26 Feb 07 jari 739       g.setComposite(java.awt.AlphaComposite.getInstance(java.awt.AlphaComposite.SRC_OVER, 0.8f));                  
2 26 Feb 07 jari 740       //g.fillRect(Math.max(left, Math.min(dragStartX, dragStopX)), top, Math.min(Math.max(dragStopX-dragStartX, dragStartX - dragStopX), Math.max((left+width)-dragStopX,(left+width)-dragStartX)), height);        
2 26 Feb 07 jari 741       g.fillRect(Math.max(left+1, Math.min(dragStartX, dragStopX)), top, Math.max(dragStopX-dragStartX-1, dragStartX - dragStopX), height);                
2 26 Feb 07 jari 742       g.setComposite(defaultComp);    
2 26 Feb 07 jari 743     }
2 26 Feb 07 jari 744     
2 26 Feb 07 jari 745     
2 26 Feb 07 jari 746     //reference line
2 26 Feb 07 jari 747     if(this.showRefLine && this.drawReferenceBlock  && xref >= left && xref <= left+width){          
2 26 Feb 07 jari 748       
2 26 Feb 07 jari 749       //add locus and coordinates if in a graph
2 26 Feb 07 jari 750       if(rect.contains(xref, yref)) {
2 26 Feb 07 jari 751         
2 26 Feb 07 jari 752         g.setFont(new Font("Monospaced", Font.BOLD, 12));            
2 26 Feb 07 jari 753         fm = g.getFontMetrics();
2 26 Feb 07 jari 754         
2 26 Feb 07 jari 755         g.setComposite(java.awt.AlphaComposite.getInstance(java.awt.AlphaComposite.SRC_OVER, 0.8f));          
2 26 Feb 07 jari 756         g.setColor(new Color(209, 213, 254));
2 26 Feb 07 jari 757         
2 26 Feb 07 jari 758         int boxWidth = Math.max(fm.stringWidth(locusNames[currLocusIndex]), Math.max(fm.stringWidth(String.valueOf(start[currLocusIndex])), fm.stringWidth(String.valueOf(start[currLocusIndex])))) + 10;
2 26 Feb 07 jari 759         int boxHeight = 3 * fm.getHeight() + 2;
2 26 Feb 07 jari 760         
2 26 Feb 07 jari 761         int boxX = xref;        
2 26 Feb 07 jari 762         int boxY = yref - boxHeight;
2 26 Feb 07 jari 763         
2 26 Feb 07 jari 764         if(left + width < xref + boxWidth)
2 26 Feb 07 jari 765           boxX = xref - boxWidth;
2 26 Feb 07 jari 766         
2 26 Feb 07 jari 767         if(top > yref - boxHeight)
2 26 Feb 07 jari 768           boxY = yref;
2 26 Feb 07 jari 769         
2 26 Feb 07 jari 770         g.fillRect(boxX, boxY, boxWidth, boxHeight);
2 26 Feb 07 jari 771         
2 26 Feb 07 jari 772         g.setColor(Color.black);
2 26 Feb 07 jari 773         g.setComposite(defaultComp);        
2 26 Feb 07 jari 774         g.drawString(locusNames[currLocusIndex], boxX+5, boxY- 2 + fm.getHeight());        
2 26 Feb 07 jari 775         g.drawString(String.valueOf(start[currLocusIndex]), boxX+5, boxY - 2 + 2*(fm.getHeight()));
2 26 Feb 07 jari 776         g.drawString(String.valueOf(end[currLocusIndex]), boxX+5, boxY - 2 + 3*(fm.getHeight()));
2 26 Feb 07 jari 777         
2 26 Feb 07 jari 778         
2 26 Feb 07 jari 779         g.setFont(new Font("Monospaced", Font.BOLD, 18));            
2 26 Feb 07 jari 780         fm = g.getFontMetrics();
2 26 Feb 07 jari 781         
2 26 Feb 07 jari 782       }
2 26 Feb 07 jari 783       
2 26 Feb 07 jari 784       //vert ref line
2 26 Feb 07 jari 785       g.setColor(Color.blue);
2 26 Feb 07 jari 786       g.setComposite(defaultComp);
2 26 Feb 07 jari 787       g.drawLine(xref, top, xref, top+height);        
2 26 Feb 07 jari 788     }
2 26 Feb 07 jari 789     
2 26 Feb 07 jari 790   }
2 26 Feb 07 jari 791   
2 26 Feb 07 jari 792   /**
2 26 Feb 07 jari 793    * Draws the overlay line while making the main view apha value lower
2 26 Feb 07 jari 794    * 
2 26 Feb 07 jari 795    * @param g graphics object on which to paint
2 26 Feb 07 jari 796    * @param prevY previous rectangle y
2 26 Feb 07 jari 797    * @param currY current rectangle y
2 26 Feb 07 jari 798    * @param prevX previous rectangle x
2 26 Feb 07 jari 799    * @param currX current rectangle x
2 26 Feb 07 jari 800    * @param factor x scaling factor
2 26 Feb 07 jari 801    * @param zeroValue zero factor also for scaling
2 26 Feb 07 jari 802    * @param defaultStroke default <code>BasicStroke</code>
2 26 Feb 07 jari 803    * @param overlayStroke overlay <code>BasicStroke</code>
2 26 Feb 07 jari 804    * @param transparentComp semi-transparent <code>Composite</code>
2 26 Feb 07 jari 805    * @param solidComp default alpha = 1, <code>Composite</code>
2 26 Feb 07 jari 806    * @return returns the current y base to provide as prevY in the next iteration
2 26 Feb 07 jari 807    */
2 26 Feb 07 jari 808   public float drawOverlayLine(Graphics2D g, float prevY, float currY, int prevX, int currX, float factor, int zeroValue, Stroke defaultStroke, BasicStroke overlayStroke, Composite transparentComp, Composite solidComp) {
2 26 Feb 07 jari 809         
2 26 Feb 07 jari 810     Color color = g.getColor();
2 26 Feb 07 jari 811     g.setColor(Color.black);
2 26 Feb 07 jari 812     g.setComposite(solidComp);
2 26 Feb 07 jari 813     g.setStroke(overlayStroke);
2 26 Feb 07 jari 814     
2 26 Feb 07 jari 815     //set current y position
2 26 Feb 07 jari 816     if(currY >= upperCutoff)
2 26 Feb 07 jari 817       currY = upperCutoff;
2 26 Feb 07 jari 818     else if(currY <= lowerCutoff)
2 26 Feb 07 jari 819       currY = lowerCutoff;
2 26 Feb 07 jari 820     else
2 26 Feb 07 jari 821       currY = this.neutralPoint;
2 26 Feb 07 jari 822     
2 26 Feb 07 jari 823     if(currY == prevY) {
2 26 Feb 07 jari 824       //draw a horizontal line from currY to prevY              
2 26 Feb 07 jari 825       g.drawLine(prevX, zeroValue - (int)Math.round(prevY*factor), currX, zeroValue - (int)Math.round(currY*factor));
2 26 Feb 07 jari 826     } else if(prevY == this.neutralPoint) {
2 26 Feb 07 jari 827       //draw horizontal on mid
2 26 Feb 07 jari 828       g.drawLine(prevX, zeroValue - (int)Math.round(prevY*factor), currX, zeroValue - (int)Math.round(prevY*factor));              
2 26 Feb 07 jari 829       //draw vertical line from mid to currY
2 26 Feb 07 jari 830       g.drawLine(currX, zeroValue - (int)Math.round(prevY*factor), currX, zeroValue - (int)Math.round(currY*factor));
2 26 Feb 07 jari 831     } else if(currY == this.neutralPoint) {
2 26 Feb 07 jari 832       //draw vertical line from prevY to mid              
2 26 Feb 07 jari 833       g.drawLine(prevX, zeroValue - (int)Math.round(prevY*factor), prevX, zeroValue - (int)Math.round(neutralPoint*factor));
2 26 Feb 07 jari 834       //draw horizontal line from mid to mid
2 26 Feb 07 jari 835       g.drawLine(prevX, zeroValue - (int)Math.round(neutralPoint*factor), currX, zeroValue - (int)Math.round(neutralPoint*factor));
2 26 Feb 07 jari 836     } else {
2 26 Feb 07 jari 837       //draw vertical line from prevY to mid
2 26 Feb 07 jari 838       g.drawLine(prevX, zeroValue - (int)Math.round(prevY*factor), prevX, zeroValue - (int)Math.round(neutralPoint*factor));
2 26 Feb 07 jari 839       //draw horizontal line from mid to mid
2 26 Feb 07 jari 840       g.drawLine(prevX, zeroValue - (int)Math.round(neutralPoint*factor), currX, zeroValue - (int)Math.round(neutralPoint*factor));
2 26 Feb 07 jari 841       //draw vertical line from mid to currY
2 26 Feb 07 jari 842       g.drawLine(currX, zeroValue - (int)Math.round(neutralPoint*factor), currX, zeroValue - (int)Math.round(currY*factor));
2 26 Feb 07 jari 843     }
2 26 Feb 07 jari 844         
2 26 Feb 07 jari 845     g.setColor(color);
2 26 Feb 07 jari 846     g.setStroke(defaultStroke);
2 26 Feb 07 jari 847     g.setComposite(transparentComp);
2 26 Feb 07 jari 848     return currY;    
2 26 Feb 07 jari 849   }
2 26 Feb 07 jari 850   
2 26 Feb 07 jari 851   
2 26 Feb 07 jari 852   /**
2 26 Feb 07 jari 853    * Constructs the YAxisLabels and determins required inset.
2 26 Feb 07 jari 854    */
2 26 Feb 07 jari 855   private void constructYAxisLabels() {
2 26 Feb 07 jari 856     yLabels = new Vector();
2 26 Feb 07 jari 857     int yInset = 40;
2 26 Feb 07 jari 858     float val = minValue;
2 26 Feb 07 jari 859     
2 26 Feb 07 jari 860     
2 26 Feb 07 jari 861     String str;
2 26 Feb 07 jari 862     int strWidth;
2 26 Feb 07 jari 863     
2 26 Feb 07 jari 864     DecimalFormat format = new DecimalFormat();
2 26 Feb 07 jari 865     format.setMaximumFractionDigits(1);
2 26 Feb 07 jari 866     
2 26 Feb 07 jari 867     if(yRangeMode == 1) { //custom mode        
2 26 Feb 07 jari 868       
2 26 Feb 07 jari 869       while(val < maxValue) {
2 26 Feb 07 jari 870         str = format.format(val);      
2 26 Feb 07 jari 871         yLabels.add(str);          
2 26 Feb 07 jari 872         val += ticInterval;
2 26 Feb 07 jari 873       }
2 26 Feb 07 jari 874       str = format.format(maxValue);      
2 26 Feb 07 jari 875       yLabels.add(str);
2 26 Feb 07 jari 876       
2 26 Feb 07 jari 877     } else {
2 26 Feb 07 jari 878       
2 26 Feb 07 jari 879       int stepsY;
2 26 Feb 07 jari 880       float yRange = maxValue-minValue;
2 26 Feb 07 jari 881       if(yRange <= 8 && yRange >=4) {
2 26 Feb 07 jari 882         stepsY = (int)yRange+1;
2 26 Feb 07 jari 883         ticInterval = 1.0f;        
2 26 Feb 07 jari 884       } else if(yRange < 4) {
2 26 Feb 07 jari 885         stepsY = (int)(yRange/0.5);
2 26 Feb 07 jari 886         ticInterval = 0.5f;
2 26 Feb 07 jari 887       } else {
2 26 Feb 07 jari 888         stepsY = 11;
2 26 Feb 07 jari 889         ticInterval = (yRange/10f);
2 26 Feb 07 jari 890       }
2 26 Feb 07 jari 891       
2 26 Feb 07 jari 892       val = minValue;
2 26 Feb 07 jari 893       
2 26 Feb 07 jari 894       
2 26 Feb 07 jari 895       for (int i=0; i<stepsY; i++) {
2 26 Feb 07 jari 896         str = format.format(val);
2 26 Feb 07 jari 897         val += ticInterval;
2 26 Feb 07 jari 898         yLabels.add(str);
2 26 Feb 07 jari 899       }        
2 26 Feb 07 jari 900     }
2 26 Feb 07 jari 901     setXGraphInset();      
2 26 Feb 07 jari 902   }
2 26 Feb 07 jari 903   
2 26 Feb 07 jari 904   /**
2 26 Feb 07 jari 905    * sets an X inset based on <code>FontMetrics</code> and the y labels
2 26 Feb 07 jari 906    * start of the graph box has to permit full view of the y labels
2 26 Feb 07 jari 907    *
2 26 Feb 07 jari 908    */
2 26 Feb 07 jari 909   private void setXGraphInset() {
2 26 Feb 07 jari 910     if(fm != null) {
2 26 Feb 07 jari 911       this.xGraphInsetInitialized = true;
2 26 Feb 07 jari 912       this.xGraphInset = 0;
2 26 Feb 07 jari 913       for(int i = 0; i < yLabels.size(); i++) {
2 26 Feb 07 jari 914         xGraphInset = Math.max(xGraphInset, fm.stringWidth((String)yLabels.get(i)));
2 26 Feb 07 jari 915       }
2 26 Feb 07 jari 916       xGraphInset += 20; //buffer
2 26 Feb 07 jari 917     } 
2 26 Feb 07 jari 918   }
2 26 Feb 07 jari 919   
2 26 Feb 07 jari 920   
2 26 Feb 07 jari 921   /**
2 26 Feb 07 jari 922    * @return returns the header
2 26 Feb 07 jari 923    */
2 26 Feb 07 jari 924   public JComponent getHeaderComponent() {
2 26 Feb 07 jari 925     return header;
2 26 Feb 07 jari 926   }
2 26 Feb 07 jari 927   
2 26 Feb 07 jari 928   /**
2 26 Feb 07 jari 929    * Updates the viewer data.
2 26 Feb 07 jari 930    */
2 26 Feb 07 jari 931   public void onDataChanged(IData data) {
2 26 Feb 07 jari 932     setData(data);
2 26 Feb 07 jari 933   }
2 26 Feb 07 jari 934   
2 26 Feb 07 jari 935   /**
2 26 Feb 07 jari 936    * Updates some viewer attributes.
2 26 Feb 07 jari 937    */
2 26 Feb 07 jari 938   public void onMenuChanged(IDisplayMenu menu) {
2 26 Feb 07 jari 939     this.displayMenu = menu;
2 26 Feb 07 jari 940     
2 26 Feb 07 jari 941     if(yRangeMode == 0) {  //display mode
2 26 Feb 07 jari 942       this.maxValue = menu.getMaxRatioScale();
2 26 Feb 07 jari 943       this.minValue = menu.getMinRatioScale();
2 26 Feb 07 jari 944       refreshGraph();      
2 26 Feb 07 jari 945     }
2 26 Feb 07 jari 946     repaint();
2 26 Feb 07 jari 947   }
2 26 Feb 07 jari 948   
2 26 Feb 07 jari 949   public void onDeselected() {}
2 26 Feb 07 jari 950   public void onClosed() {}
2 26 Feb 07 jari 951   
2 26 Feb 07 jari 952   /**
2 26 Feb 07 jari 953    * @return null
2 26 Feb 07 jari 954    */
2 26 Feb 07 jari 955   public BufferedImage getImage() {
2 26 Feb 07 jari 956     return null;
2 26 Feb 07 jari 957   }
2 26 Feb 07 jari 958   
2 26 Feb 07 jari 959   /**
2 26 Feb 07 jari 960    * Calculate experiment max value for scale purpose.
2 26 Feb 07 jari 961    */
2 26 Feb 07 jari 962   private float calculateMaxValue(int[] probes) {
2 26 Feb 07 jari 963     float max = 0f;
2 26 Feb 07 jari 964     float value;
2 26 Feb 07 jari 965     final int samples = experiment.getNumberOfSamples();
2 26 Feb 07 jari 966     for (int sample=0; sample<samples; sample++) {
2 26 Feb 07 jari 967       for (int probe=0; probe<probes.length; probe++) {
2 26 Feb 07 jari 968         value = experiment.get(probes[probe], sample);
2 26 Feb 07 jari 969         if (!Float.isNaN(value)) {
2 26 Feb 07 jari 970           max = Math.max(max, Math.abs(value));
2 26 Feb 07 jari 971         }
2 26 Feb 07 jari 972       }
2 26 Feb 07 jari 973     }
2 26 Feb 07 jari 974     return max;
2 26 Feb 07 jari 975   }
2 26 Feb 07 jari 976   
2 26 Feb 07 jari 977   /**
2 26 Feb 07 jari 978    * Returns max width of experiment names.
2 26 Feb 07 jari 979    */
2 26 Feb 07 jari 980   protected int getNamesWidth(FontMetrics metrics) {
2 26 Feb 07 jari 981     int maxWidth = 0;
2 26 Feb 07 jari 982     for (int i=0; i<experiment.getNumberOfSamples(); i++) {
2 26 Feb 07 jari 983       maxWidth = Math.max(maxWidth, metrics.stringWidth(data.getSampleName(experiment.getSampleIndex(i))));
2 26 Feb 07 jari 984     }
2 26 Feb 07 jari 985     return maxWidth;
2 26 Feb 07 jari 986   }
2 26 Feb 07 jari 987   
2 26 Feb 07 jari 988   /** Returns a component to be inserted into the scroll pane row header
2 26 Feb 07 jari 989    */
2 26 Feb 07 jari 990   public JComponent getRowHeaderComponent() {
2 26 Feb 07 jari 991     return null;
2 26 Feb 07 jari 992   }    
2 26 Feb 07 jari 993   
2 26 Feb 07 jari 994   /** Returns the corner component corresponding to the indicated corner,
2 26 Feb 07 jari 995    * posibly null
2 26 Feb 07 jari 996    */
2 26 Feb 07 jari 997   public JComponent getCornerComponent(int cornerIndex) {
2 26 Feb 07 jari 998     return null;
2 26 Feb 07 jari 999   }
2 26 Feb 07 jari 1000   
2 26 Feb 07 jari 1001   /** Returns int value indicating viewer type
2 26 Feb 07 jari 1002    * Cluster.GENE_CLUSTER, Cluster.EXPERIMENT_CLUSTER, or -1 for both or unspecified
2 26 Feb 07 jari 1003    */
2 26 Feb 07 jari 1004   public int getViewerType() {
2 26 Feb 07 jari 1005     return Cluster.GENE_CLUSTER;
2 26 Feb 07 jari 1006   }
2 26 Feb 07 jari 1007   
2 26 Feb 07 jari 1008   /**
2 26 Feb 07 jari 1009    * Handles mouse event in viewer
2 26 Feb 07 jari 1010    */
2 26 Feb 07 jari 1011   public class GraphListener extends java.awt.event.MouseAdapter implements java.awt.event.MouseMotionListener{
2 26 Feb 07 jari 1012     int x = 0, y = 0;
2 26 Feb 07 jari 1013   
2 26 Feb 07 jari 1014     public void mouseReleased(MouseEvent me) {
2 26 Feb 07 jari 1015       if(me.getModifiers() != MouseEvent.BUTTON1_MASK)
2 26 Feb 07 jari 1016         return;
2 26 Feb 07 jari 1017
2 26 Feb 07 jari 1018       if(inDragMode) {
2 26 Feb 07 jari 1019         int initialStart = startIndex;
2 26 Feb 07 jari 1020         startIndex = startIndex + Math.round((endIndex-startIndex - 1) * ((Math.min(dragStartX,dragStopX)-40f)/(getWidth()-80f)));        
2 26 Feb 07 jari 1021         endIndex = initialStart + Math.round((endIndex-initialStart) * ((Math.max(dragStopX,dragStartX)-40f)/(getWidth()-80f)));                
2 26 Feb 07 jari 1022         startIndex = Math.min(startIndex, endIndex);
2 26 Feb 07 jari 1023         endIndex = Math.max(startIndex, endIndex);      
2 26 Feb 07 jari 1024         if(startIndex < 0)
2 26 Feb 07 jari 1025           startIndex = 0;
2 26 Feb 07 jari 1026         if(endIndex > means.length-1)
2 26 Feb 07 jari 1027           endIndex = means.length-1;
2 26 Feb 07 jari 1028         header.setLimits( (float)startIndex/(float)means.length, (float)endIndex/(float)means.length);
2 26 Feb 07 jari 1029       }
2 26 Feb 07 jari 1030       inDragMode = false;
2 26 Feb 07 jari 1031       repaint();
2 26 Feb 07 jari 1032     }
2 26 Feb 07 jari 1033     
2 26 Feb 07 jari 1034     public void mouseDragged(java.awt.event.MouseEvent me) {  
2 26 Feb 07 jari 1035       if(me.getModifiers() != MouseEvent.BUTTON1_MASK)
2 26 Feb 07 jari 1036         return;
2 26 Feb 07 jari 1037       
2 26 Feb 07 jari 1038       if(!inDragMode) {
2 26 Feb 07 jari 1039         dragStartX = me.getX();        
2 26 Feb 07 jari 1040       }
2 26 Feb 07 jari 1041       dragStopX = me.getX();
2 26 Feb 07 jari 1042       
2 26 Feb 07 jari 1043       if(dragStopX < 40)
2 26 Feb 07 jari 1044         dragStopX = 41;
2 26 Feb 07 jari 1045       if(dragStopX > getWidth()-40)
2 26 Feb 07 jari 1046         dragStopX = getWidth()-39;
2 26 Feb 07 jari 1047       
2 26 Feb 07 jari 1048       inDragMode = true;      
2 26 Feb 07 jari 1049       mouseMoved(me);
2 26 Feb 07 jari 1050     }
2 26 Feb 07 jari 1051     
2 26 Feb 07 jari 1052     
2 26 Feb 07 jari 1053     public void mouseMoved(java.awt.event.MouseEvent me) {
2 26 Feb 07 jari 1054       
2 26 Feb 07 jari 1055       int newX = me.getX();            
2 26 Feb 07 jari 1056       int newY = me.getY();
2 26 Feb 07 jari 1057       int refX = newX;
2 26 Feb 07 jari 1058       
2 26 Feb 07 jari 1059       if(inDragMode) {
2 26 Feb 07 jari 1060         cursorOn = true;
2 26 Feb 07 jari 1061         if(newX < 40)
2 26 Feb 07 jari 1062           newX = 41;
2 26 Feb 07 jari 1063         if(newX > getWidth()-40)
2 26 Feb 07 jari 1064           newX = getWidth()-39;
2 26 Feb 07 jari 1065         xref = newX; 
2 26 Feb 07 jari 1066         yref = newY;
2 26 Feb 07 jari 1067         currLocusIndex = startIndex + Math.round((endIndex-startIndex - 1) * ((newX-40f)/(getWidth()-80f)));
2 26 Feb 07 jari 1068         repaint();
2 26 Feb 07 jari 1069       }
2 26 Feb 07 jari 1070       
2 26 Feb 07 jari 1071       int numberOfSamples  = experiment.getNumberOfSamples();
2 26 Feb 07 jari 1072       if(refX < 40 || refX > getWidth()- 40 || numberOfSamples <= 1){
2 26 Feb 07 jari 1073         drawReferenceBlock = false;
2 26 Feb 07 jari 1074         repaint();
2 26 Feb 07 jari 1075         return;
2 26 Feb 07 jari 1076       }
2 26 Feb 07 jari 1077       
2 26 Feb 07 jari 1078       drawReferenceBlock = true;    
2 26 Feb 07 jari 1079       
2 26 Feb 07 jari 1080       currLocusIndex = startIndex + Math.round((endIndex-startIndex - 1) * ((newX-40f)/(getWidth()-80f)));
2 26 Feb 07 jari 1081       xref = newX;
2 26 Feb 07 jari 1082       yref = newY;
2 26 Feb 07 jari 1083       repaint();        
2 26 Feb 07 jari 1084     }
2 26 Feb 07 jari 1085     
2 26 Feb 07 jari 1086                
2 26 Feb 07 jari 1087     }
2 26 Feb 07 jari 1088
2 26 Feb 07 jari 1089
2 26 Feb 07 jari 1090   /* (non-Javadoc)
2 26 Feb 07 jari 1091    * @see org.tigr.microarray.mev.cluster.gui.IViewer#getExperimentID()
2 26 Feb 07 jari 1092    */
2 26 Feb 07 jari 1093   public int getExperimentID() {
2 26 Feb 07 jari 1094     return this.exptID;
2 26 Feb 07 jari 1095   }
2 26 Feb 07 jari 1096
2 26 Feb 07 jari 1097   /* (non-Javadoc)
2 26 Feb 07 jari 1098    * @see org.tigr.microarray.mev.cluster.gui.IViewer#setExperimentID(int)
2 26 Feb 07 jari 1099    */
2 26 Feb 07 jari 1100   public void setExperimentID(int id) {
2 26 Feb 07 jari 1101     this.exptID = id;
2 26 Feb 07 jari 1102   }
2 26 Feb 07 jari 1103
2 26 Feb 07 jari 1104
2 26 Feb 07 jari 1105 }