/*
 * $Id: Ruler.java,v 1.14 2003/08/22 23:02:32 dwd Exp $
 *
 * This software is provided by NOAA for full, free and open release.  It is
 * understood by the recipient/user that NOAA assumes no liability for any
 * errors contained in the code.  Although this software is released without
 * conditions or restrictions in its use, it is expected that appropriate
 * credit be given to its author and to the National Oceanic and Atmospheric
 * Administration should the software be included by the recipient as an
 * element in other product development.
 */

package sgtplot;


import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Font;
import java.awt.Color;

import org.freehep.graphics2d.VectorGraphics;
// jdk1.2
//import java.awt.geom.Rectangle2D;
//import java.awt.geom.Point2D;

import sgtplot.util.Debug;
import sgtplot.util.Point2D;
import sgtplot.util.Range2D;
import sgtplot.util.Rectangle2D;

/**
 * Description of Class Ruler
 *
 * @author Donald Denbo
 * @version $Revision: 1.14 $, $Date: 2003/08/22 23:02:32 $
 * @since 1.0
 */
public class Ruler implements Cloneable, LayerChild {
  private String ident_;
/** @directed */
  private Layer layer_;
  private int orient_;
  //
  private boolean selected_;
  private boolean selectable_;
  private boolean visible_;
    /**@label title
     * @link aggregationByValue */
    private SGLabel title_ = null;
  private String labelFormat_ = "";
  protected Range2D uRange_;
//  protected Point2D.Double uLocation_;
  protected Rectangle2D.Double pBounds_;
  protected int numSmallTics_ = 0;
  protected double largeTicHeight_ = 0.02;
  protected double smallTicHeight_ = 0.01;
  protected int ticPosition_ = NEGATIVE_SIDE;
  protected int labelPosition_ = NEGATIVE_SIDE;
  protected int labelInterval_ = 2;
  // protected Font labelFont_ = new Font("Helvetica", Font.ITALIC, 10);
     protected Font labelFont_ = new Font("SansSerif", Font.BOLD, 10);

  protected Color labelColor_ = Color.black;
  protected Color lineColor_ = Color.black;
  protected double labelHeight_ = 0.04;
  protected int sigDigits_ = 2;
  /**
   * Orient Key horizontally.
   */
  public static final int HORIZONTAL = 1;
  /**
   * Orient Key vertically.
   */
  public static final int VERTICAL = 2;
  /**
   * Place the label and/or tic on the positive side of the axis.
   * The right side of VERTICAL axes and the top of HORIZONTAL axes.
   */
  public static final int POSITIVE_SIDE = 0;
  /**
   * Place the label and/or tic on the negative side of the axis.
   * The left side of VERTICAL axes and the bottom of HORIZONTAL axes.
   */
  public static final int NEGATIVE_SIDE = 1;
  /**
   * Do not draw a label and/or tic.
   */
  public static final int NO_LABEL = 2;
  /**
   * Draw the tics on both sides of the axes.
   */
  public static final int BOTH_SIDES = 2;
  //
  static final double TIC_GAP = 0.05;
  static final double TIC_RATIO = 1.3;
  static final double LABEL_RATIO = 1.3;
  protected void drawXTic(VectorGraphics g,double xp,double yp,double ticHeight) {
    int x0, y0, y1;
    double yp0, yp1;
    if(ticPosition_ == BOTH_SIDES || ticPosition_ == POSITIVE_SIDE) {
      yp0 = yp + ticHeight;
    } else {
      yp0 = yp;
    }
    if(ticPosition_ == BOTH_SIDES || ticPosition_ == NEGATIVE_SIDE) {
      yp1 = yp - ticHeight;
    } else {
      yp1 = yp;
    }
    x0 = layer_.getXPtoD(xp);
    y0 = layer_.getYPtoD(yp0);
    y1 = layer_.getYPtoD(yp1);
    g.drawLine(x0, y0, x0, y1);
  }
  //
  protected void drawYTic(VectorGraphics g,double xp,double yp,double ticHeight) {
    int x0, x1, y0;
    double xp0, xp1;
    if(ticPosition_ == BOTH_SIDES || ticPosition_ == POSITIVE_SIDE) {
      xp0 = xp + ticHeight;
    } else {
      xp0 = xp;
    }
    if(ticPosition_ == BOTH_SIDES || ticPosition_ == NEGATIVE_SIDE) {
      xp1 = xp - ticHeight;
    } else {
      xp1 = xp;
    }
    y0 = layer_.getYPtoD(yp);
    x0 = layer_.getXPtoD(xp0);
    x1 = layer_.getXPtoD(xp1);
    g.drawLine(x0, y0, x1, y0);
  }
  //
  protected void drawSmallXTics(VectorGraphics g,double xu,double xtest,double del,double yp) {
    int x0, y0, y1, i;
    double yp0, yp1, smdel, xt;
    if(numSmallTics_ <= 0) return;
    //        yp = graph_.getYUtoP(yu);
    if(ticPosition_ == BOTH_SIDES || ticPosition_ == POSITIVE_SIDE) {
      yp0 = yp + smallTicHeight_;
    } else {
      yp0 = yp;
    }
    if(ticPosition_ == BOTH_SIDES || ticPosition_ == NEGATIVE_SIDE) {
      yp1 = yp - smallTicHeight_;
    } else {
      yp1 = yp;
    }
    y0 = layer_.getYPtoD(yp0);
    y1 = layer_.getYPtoD(yp1);
    smdel = del/(numSmallTics_ + 1);
    for(i=0; i <= numSmallTics_; i++) {
      xt = xu + smdel*i;
      if((xtest - xt)/del >= 0) {
        x0 = layer_.getXPtoD(xt);
        g.drawLine(x0, y0, x0, y1);
      }
    }
  }
  //
  protected void drawSmallYTics(VectorGraphics g,double xp,double yu,double ytest,double del) {
    int x0, x1, y0, i;
    double xp0, xp1, smdel, yt;
    if(numSmallTics_ <= 0) return;
    //        xp = graph_.getXUtoP(xu);
    if(ticPosition_ == BOTH_SIDES || ticPosition_ == POSITIVE_SIDE) {
      xp0 = xp + smallTicHeight_;
    } else {
      xp0 = xp;
    }
    if(ticPosition_ == BOTH_SIDES || ticPosition_ == NEGATIVE_SIDE) {
      xp1 = xp - smallTicHeight_;
    } else {
      xp1 = xp;
    }
    x0 = layer_.getXPtoD(xp0);
    x1 = layer_.getXPtoD(xp1);
    smdel = del/(numSmallTics_ + 1);
    for(i=0; i <= numSmallTics_; i++) {
      yt = yu + smdel*i;
      if((ytest - yt)/del >= 0) {
        y0 = layer_.getYPtoD(yt);
        g.drawLine(x0, y0, x1, y0);
      }
    }
  }
  /**
   * Default constructor for Ruler.
   */
  public Ruler() {
    this("");
}
  /**
   * Constructor for Ruler. Sets the ruler identifier and initializes
   * the defaults. Default values are:
   *
   * 
   *   numberSmallTics = 0
   *   largeTicHeightP = 0.1
   *   smallTicHeightP = 0.05
   *       ticPosition = NEGATIVE_SIDE
   *     labelPosition = NEGATIVE_SIDE
   *     labelInterval = 2
   *         labelFont = Font("Helvetica", Font.ITALIC, 10);
   *      labelHeightP = 0.15
   * significantDigits = 2;
   *       labelFormat = ""
   *             title = null
   *       orientation = HORIZONTAL
   *                Id = ""
   * 
* * @param id axis identification */ public Ruler(String ident) { ident_ = ident; selected_ = false; selectable_ = true; visible_ = true; } public LayerChild copy() { Ruler newRuler; try { newRuler = (Ruler)clone(); } catch (CloneNotSupportedException e) { newRuler = new Ruler(); } return (LayerChild)newRuler; } public void setSelected(boolean sel) { selected_ = sel; } public boolean isSelected() { return selected_; } public void setSelectable(boolean select) { selectable_ = select; } public boolean isSelectable() { return selectable_; } /** * Set the large tic height in physical units. * * @param lthgt large tic height. */ public void setLargeTicHeightP(double lthgt) { if(largeTicHeight_ != lthgt) { largeTicHeight_ = lthgt; modified("Ruler: setLargeTicHeightP()"); } } /** * Get the large tic height. * * @return large tic height in physcial units. */ public double getLargeTicHeightP() { return largeTicHeight_; } /** * Set the number of small tics between large tics. * * @param nstic number of small tics. */ public void setNumberSmallTics(int nstic) { if(numSmallTics_ != nstic) { numSmallTics_ = nstic; modified("Ruler: setNumberSmallTics()"); } } /** * Get the number of small tics between large tics. * * @return number of small tics. */ public int getNumberSmallTics() { return numSmallTics_; } /** * Set the small tic height in physical units. * * @param sthgt small tic height. */ public void setSmallTicHeightP(double sthgt) { if(smallTicHeight_ != sthgt) { smallTicHeight_ = sthgt; modified("Ruler: setSmallTicHeightP()"); } } /** * Get the small tic height. * * @return small tic height in physical units. */ public double getSmallTicHeightP() { return smallTicHeight_; } /** * Set the tic position. Tic position can be POSITIVE_SIDE, NEGATIVE_SIDE, * or BOTH_SIDES. * * @param tpos tic position */ public void setTicPosition(int tpos) { if(ticPosition_ != tpos) { ticPosition_ = tpos; modified("Ruler: setTicPosition()"); } } /** * Get the tic position. * * @return tic position */ public int getTicPosition() { return ticPosition_; } /** * Set the label position. Label position can be POSITIVE_SIDE, NEGATIVE_SIDE, * and NO_LABEL. * * @param lapb label position. */ public void setLabelPosition(int labp) { if(labelPosition_ != labp) { labelPosition_ = labp; modified("Ruler: setLabelPosition()"); } } /** * Get the label position. * * @return label position */ public int getLabelPosition() { return labelPosition_; } /** * Set the label font. * * @param fnt label font */ public void setLabelFont(Font fnt) { if(labelFont_ == null || !labelFont_.equals(fnt)) { labelFont_ = fnt; modified("Ruler: setLabelFont()"); } } /** * Get the label font. * * @return label font */ public Font getLabelFont() { return labelFont_; } /** * Set the label height in physical units. * * @param lhgt label height. */ public void setLabelHeightP(double lhgt) { if(labelHeight_ != lhgt) { labelHeight_ = lhgt; modified("Ruler: setLabelHeightP()"); } } /** * Get the label height. * * @return label height */ public double getLabelHeightP() { return labelHeight_; } /** * Set the axis identifier. * * @param id identifier **/ public void setId(String id) { ident_ = id; } /** * Set the axis identifier. * * @param id identifier **/ public String getId() { return ident_; } public void setLayer(Layer l) { layer_ = l; } public Layer getLayer() { return layer_; } public AbstractPane getPane() { return layer_.getPane(); } public void modified(String mess) { // if(Debug.EVENT) System.out.println("Ruler: modified()"); if(layer_ != null) layer_.modified(mess); } /** * Change the user unit range of Ruler */ public void setRangeU(Range2D range) { if(uRange_ == null || !uRange_.equals(range)) { uRange_ = range; modified("Ruler: setRangeU()"); } } public Range2D getRangeU() { return uRange_; } /** * Set the bounding box for the axis in physical units. * * @return bounding box */ public void setBoundsP(Rectangle2D.Double bounds) { if(pBounds_ == null || !pBounds_.equals(bounds)) { if(Debug.EVENT) System.out.println("pBounds_ = " + pBounds_ + ", bounds = " + bounds); pBounds_ = bounds; modified("Ruler: setBoundsP()"); } } /** * Get the bounding box for the axis in physical units. * * @return bounding box */ public Rectangle2D.Double getBoundsP() { return pBounds_; } /** * Set ruler orientation. Allowed orientations are HORIZONATAL and * VERTICAL. * * @param or orientation */ public void setOrientation(int orient) { if(orient_ != orient) { orient_ = orient; modified("Ruler: setOrientation()"); } } /** * Get axis orientation * * @return axis orientation */ public int getOrientation() { return orient_; } /** * Set the axis title. * * @param title axis title */ public void setTitle(SGLabel title) { if(title_ == null || !title_.equals(title)) { title_ = title; modified("Ruler: setTitle()"); } } /** * Get the axis title. * * @return axis title */ public SGLabel getTitle() { return title_; } /** * Get the bounding box for the axis in device units. * * @return bounding box */ public Rectangle getBounds() { int x, y, height, width; x = layer_.getXPtoD(pBounds_.x); y = layer_.getYPtoD(pBounds_.y); width = layer_.getXPtoD(pBounds_.x + pBounds_.width) - x; height = layer_.getYPtoD(pBounds_.y - pBounds_.height) - y; if(orient_ == HORIZONTAL) { y = y - height; } return new Rectangle(x, y, width, height); } public void setBounds(Rectangle r) { setBounds(r.x, r.y, r.width, r.height); } public void setBounds(int x, int y, int width, int height) { } public void draw(VectorGraphics g) { int xloc, yloc, xend, yend; int istop, i; double xt, yt, dir, x, y, xp, yp; double xtitle, ytitle; Format format; String labelText = null; AxisTransform sTrans; if(!visible_) return; if(title_ != null) title_.setLayer(layer_); // if(lineColor_ == null) { g.setColor(layer_.getPane().getComponent().getForeground()); } else { g.setColor(lineColor_); } // if(labelFormat_.length() <= 0) { format = new Format(Format.computeFormat(uRange_.start, uRange_.end, sigDigits_)); } else { format = new Format(labelFormat_); } if(orient_ == HORIZONTAL) { sTrans = new LinearTransform(pBounds_.x, pBounds_.x + pBounds_.width, uRange_.start, uRange_.end); yloc = layer_.getYPtoD(pBounds_.y); yp = pBounds_.y; xloc = layer_.getXPtoD(sTrans.getTransP(uRange_.start)); xend = layer_.getXPtoD(sTrans.getTransP(uRange_.end)); g.drawLine(xloc, yloc, xend, yloc); // dir = uRange_.delta > 0? 1.0: -1.0; xt = (int)((uRange_.start/uRange_.delta + (dir*uRange_.start > 0? 1.0: -1.0)*0.00001))*uRange_.delta; if(dir*xt < dir*uRange_.start) xt += uRange_.delta; istop = (int)((uRange_.end - xt)/uRange_.delta + 0.00001); x = xt; xp = sTrans.getTransP(x); drawSmallXTics(g, x, uRange_.start, -uRange_.delta, yp); drawXTic(g, xp, yp, largeTicHeight_); for(i=0; i < istop; i++) { drawSmallXTics(g, x, uRange_.end, uRange_.delta, yp); x += uRange_.delta; xp = sTrans.getTransP(x); drawXTic(g, xp, yp, largeTicHeight_); } drawSmallXTics(g, x, uRange_.end, uRange_.delta, yp); // if(labelInterval_ <= 0 || labelPosition_ == NO_LABEL) return; // SGLabel label; int vertalign; if(labelPosition_ == POSITIVE_SIDE) { vertalign = SGLabel.BOTTOM; if(ticPosition_ == BOTH_SIDES || ticPosition_ == POSITIVE_SIDE) { yt = yp + TIC_RATIO*largeTicHeight_; } else { yt = yp + TIC_GAP; } ytitle = yt + LABEL_RATIO*labelHeight_; } else { vertalign = SGLabel.TOP; if(ticPosition_ == BOTH_SIDES || ticPosition_ == NEGATIVE_SIDE) { yt = yp - TIC_RATIO*largeTicHeight_; } else { yt = yp - TIC_GAP; } ytitle = yt - LABEL_RATIO*labelHeight_; } if(dir*uRange_.start <= 0 && dir*uRange_.end >= 0) { x = ((int)(uRange_.start/(uRange_.delta*labelInterval_) - 0.00001))*uRange_.delta*labelInterval_; } else { x = xt; } istop = (int)((uRange_.end - x)/(uRange_.delta*labelInterval_) + 0.00001); for(i=0; i <= istop; i++) { xt = sTrans.getTransP(x); labelText = format.form(x); label = new SGLabel("coordinate", labelText, new Point2D.Double(xt, yt)); label.setFont(labelFont_); label.setHeightP(labelHeight_); label.setAlign(vertalign, SGLabel.CENTER); label.setLayer(layer_); label.setColor(labelColor_); try { label.draw(g); } catch (LayerNotFoundException e) {} x = x + uRange_.delta*labelInterval_; } if(title_ != null) { xtitle = (uRange_.end + uRange_.start)*0.5; yt = ytitle; xt = sTrans.getTransP(xtitle); title_.setLocationP(new Point2D.Double(xt, yt)); title_.setAlign(vertalign, SGLabel.CENTER); title_.setOrientation(SGLabel.HORIZONTAL); try { title_.draw(g); } catch (LayerNotFoundException e) {} } } else { // orientation is vertical sTrans = new LinearTransform(pBounds_.y, pBounds_.y + pBounds_.height, uRange_.start, uRange_.end); xloc = layer_.getXPtoD(pBounds_.x); xp = pBounds_.x; yloc = layer_.getYPtoD(sTrans.getTransP(uRange_.start)); yend = layer_.getYPtoD(sTrans.getTransP(uRange_.end)); g.drawLine(xloc, yloc, xloc, yend); // dir = uRange_.delta > 0? 1.0: -1.0; yt = (int)((uRange_.start/uRange_.delta) + (dir*uRange_.start > 0? 1.0: -1.0)*0.00001)*uRange_.delta; if(dir*yt < dir*uRange_.start) yt += uRange_.delta; istop = (int)((uRange_.end - yt)/uRange_.delta + 0.00001); y = yt; yp = sTrans.getTransP(y); drawSmallYTics(g, xp, y, uRange_.start, -uRange_.delta); drawYTic(g, xp, yp, largeTicHeight_); for(i=0; i < istop; i++) { drawSmallYTics(g, xp, y, uRange_.end, uRange_.delta); y += uRange_.delta; yp = sTrans.getTransP(y); drawYTic(g, xp, yp, largeTicHeight_); } drawSmallYTics(g, xp, y, uRange_.end, uRange_.delta); // if(labelInterval_ <= 0 || labelPosition_ == NO_LABEL) return; // SGLabel label; int vertalign; if(labelPosition_ == NEGATIVE_SIDE) { vertalign = SGLabel.BOTTOM; if(ticPosition_ == BOTH_SIDES || ticPosition_ == NEGATIVE_SIDE) { xt = xp - TIC_RATIO*largeTicHeight_; } else { xt = xp - TIC_GAP; } xtitle = xt - LABEL_RATIO*labelHeight_; } else { vertalign = SGLabel.TOP; if(ticPosition_ == BOTH_SIDES || ticPosition_ == POSITIVE_SIDE) { xt = xp + TIC_RATIO*largeTicHeight_; } else { xt = xp + TIC_GAP; } xtitle = xt + LABEL_RATIO*labelHeight_; } if(dir*uRange_.start <= 0 && dir*uRange_.end >= 0) { y = ((int)(uRange_.start/(uRange_.delta*labelInterval_) - 0.00001))*uRange_.delta*labelInterval_; } else { y = yt; } istop = (int)((uRange_.end - y)/(uRange_.delta*labelInterval_) + 0.00001); for(i=0; i <= istop; i++) { yt = sTrans.getTransP(y); labelText = format.form(y); label = new SGLabel("coordinate", labelText, new Point2D.Double(xt, yt)); label.setAlign(vertalign, SGLabel.CENTER); label.setOrientation(SGLabel.VERTICAL); label.setFont(labelFont_); label.setHeightP(labelHeight_); label.setLayer(layer_); try { label.draw(g); } catch (LayerNotFoundException e) {} y = y + uRange_.delta*labelInterval_; } if(title_ != null) { ytitle = (uRange_.end + uRange_.start)*0.5; yt = sTrans.getTransP(ytitle); xt = xtitle; title_.setLocationP(new Point2D.Double(xt, yt)); title_.setAlign(vertalign, SGLabel.CENTER); title_.setOrientation(SGLabel.VERTICAL); try { title_.draw(g); } catch (LayerNotFoundException e) {} } } } public boolean isVisible() { return visible_; } public void setVisible(boolean visible) { if(visible_ != visible) { visible_ = visible; modified("Ruler: setVisible()"); } } /** * @since 3.0 */ public int getLabelInterval() { return labelInterval_; } /** * @since 3.0 */ public void setLabelInterval(int labelInterval) { labelInterval_ = labelInterval; } /** * @since 3.0 */ public int getSignificantDigits() { return sigDigits_; } /** * @since 3.0 */ public void setSignificantDigits(int sigDigits) { sigDigits_ = sigDigits; } /** * @since 3.0 */ public String getLabelFormat() { return labelFormat_; } /** * @since 3.0 */ public void setLabelFormat(String labelFormat) { labelFormat_ = labelFormat; } /** * @since 3.0 */ public Color getLabelColor() { return labelColor_; } /** * @since 3.0 */ public void setLabelColor(Color labelColor) { labelColor_ = labelColor; } /** * @since 3.0 */ public Color getLineColor() { return lineColor_; } /** * @since 3.0 */ public void setLineColor(Color lineColor) { lineColor_ = lineColor; } }

Ads help maintain this website.