Package de.progra.charting

Source Code of de.progra.charting.CoordSystem

/*
    JOpenChart Java Charting Library and Toolkit
    Copyright (C) 2001  Sebastian M�ller
    http://jopenchart.sourceforge.net

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    CoordSystem.java
    Created on 26. Juni 2001, 22:49
*/

package de.progra.charting;

import de.progra.charting.render.AbstractRenderer;
import de.progra.charting.render.ChartRenderingHints;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Line2D;
import java.awt.geom.AffineTransform;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.text.DecimalFormat;
import de.progra.charting.model.ChartDataModel;
import de.progra.charting.model.ChartDataModelConstraints;


/** This class defines a coordinate system. The CoordSystem class computes
* an AffineTransform for each y-axis, which translates the user space
* coordinates (ie. the data value coordinates) into pixel space coordinates.
* These AffineTransform classes make the PixelToPointTranslator obsolete,
* since it provides more flexibility. <code>getDefaultTransform</code> always
* computes the default transformation, whereas you can set another
* transformation via <code>setTransform</code>. This will be used to implement
* zooming and panning in the Swing classes.<p>
* All classes incl. this one, which render data will use the transformations
* to translate the coordinates. The transformations are not set up on
* instantiation of a CoordSystem, instead they're computed when setBounds
* is called, because they need this information of course. Afterwards you
* can set your own transformation or even better you can manipulate the
* existing ones by pre- or postconcatenating another AffineTransform.
*/
public class CoordSystem extends AbstractRenderer {
   
  /** The x-axis caption string. */
    protected String xaxis_unit = "x";
  /** The y-axis caption string. */
    protected String yaxis_unit = "y";
   
  /** The Font used in the CoordSystem. */
    protected Font font = new Font("sans", Font.PLAIN, 9);
   
    /** FontRenderContext used througout the CoordSystem*/
    protected final FontRenderContext frc = new FontRenderContext(null, false, false);
    /** DecimalFormat used throught on the Yaxis of the CoordSystem*/
    protected DecimalFormat dfY;
    /** DecimalFormat used throught on the Xaxis of the CoordSystem*/
    protected DecimalFormat dfX;
    /** if true, the arrows will be drawn at the end of the axi*/
    protected boolean shouldDrawArrows = true;
    /** if true, the increment will be painted at each tick mark*/
    protected boolean shouldPaintAltTick = true;
    /** if true only the tick will be painted on the yaxis.  Alternately, if false, a
     * light grey line will paint across the background of the chart.*/
    protected boolean shouldPaintOnlyTick = true;
   
    /** If true, the labels will be painted. If false, only the ticks will display. */
    protected boolean shouldPaintLabels = true;
   
    /** The left margin */
  protected int leftmargin = 50;
  /** The top margin. */
    protected int topmargin = 20;
 
  /** The right margin. */
    protected int rightmargin = 30;
  /** The bottom margin. */
    protected int bottommargin = 30;
  /** The minimal margin constant. */
    public final int MINIMALMARGIN = 20;
  /** The arrow length constant. */
    public final int ARROWLENGTH = 15;
   
  /** The ChartDataModel constraints of the first y-axis and the x-axis. */
    protected ChartDataModelConstraints constraints;
  /** The ChartDataModel constraints of the second y-axis and the x-axis. */
    protected ChartDataModelConstraints constraints2;
   
  /** The DataModel class. */
    protected ChartDataModel model;
   
  /** The utilities class, which contains all the rendering methods etc. */
    protected CoordSystemUtilities c;
   
  /** The xaxis.*/
    protected Axis xaxis;
    /** The first y-axis. */
  protected Axis yaxis;
  /** The second y-axis. */
    protected Axis yaxis2;
   
  /** The multiplication matrix for the first y-axis and the x-axis. */
    protected AffineTransform y1transform;
  /** The multiplication matrix for the second y-axis and the x-axis. */
    protected AffineTransform y2transform;
   
    /** the axis binding constant for the first y-axis
     */
    public static final int FIRST_YAXIS = 0;
    /** the axis binding constant for the second y-axis
     */
    public static final int SECOND_YAXIS = 1;
   
    /** Creates a new CoordSystem using the given model constraints.
     * Also creates default linear x and y-axis. Note that the length
     * of the axis are set on the first call to
     * setBounds().
     * @param c the ChartDataModel needed to compute the DataConstraints.
     */
    public CoordSystem(ChartDataModel cdm) {
        this.constraints = cdm.getChartDataModelConstraints(FIRST_YAXIS);
        this.constraints2 = cdm.getChartDataModelConstraints(SECOND_YAXIS);
       
        this.model = cdm;
       
        xaxis = new Axis(Axis.HORIZONTAL, constraints);
        yaxis = new Axis(Axis.VERTICAL, constraints);
       
        c = new CoordSystemUtilities(this, constraints, constraints2, model);
   
    dfY = new DecimalFormat();
        dfX = new DecimalFormat();
    }
   
    /** Creates a new CoordSystem using the given model constraints.
     * Also creates default linear x and y-axis. Note that the length
     * of the axis are set on the first call to
     * setBounds().
     * @param c the ChartDataModel needed to compute the DataConstraints.
     * @param xtext the x-axis unit
     * @param ytext the y-axis unit
     */
    public CoordSystem(ChartDataModel c, String xunit, String yunit) {
        this(c);

        setXAxisUnit(xunit);
        setYAxisUnit(yunit);
    }
 
  /**
     * Create a new CoordSystem with alternate painting parameters.
     * @param c the ChartDataModel needed to compute the DataConstraints.
     * @param drawArrows if true the arrows will be drawn at the end of the axis
     * @param paintAltYTick if true the caption will paint on alternate ticks of the
     * yaxis instead of on every one.
     * @param paintOnlyYTick if true the horizontal lightgray line will <i>not</i>
     * appear behind the chart at each yaxis tick mark.
     */
    public CoordSystem(ChartDataModel c, DecimalFormat yAxisFormat,
            boolean drawArrows, boolean paintAltYTick, boolean paintOnlyYTick) {
        this(c);
        dfY = yAxisFormat;
        shouldDrawArrows = drawArrows;
        shouldPaintAltTick = paintAltYTick;
        shouldPaintOnlyTick = paintOnlyYTick;
    }

    /** Sets the coordinate transformation for any y-coordinate.
     * @param at the AffineTransform that transforms the coordinates into pixel
     * space
     * @axis defines for which y-axis the transform is computed
     */
    public void setTransform(AffineTransform at, int axis) {
        switch(axis) {
            case(FIRST_YAXIS): y1transform = at; break;
            case(SECOND_YAXIS): y2transform = at; break;
        }
    }
   
    /** Returns the currently defined AffineTransform for any y-axis.
     * @param axis the y-axis to be used.
     */
    public AffineTransform getTransform(int axis) {
        switch(axis) {
            case(FIRST_YAXIS): return y1transform;
            case(SECOND_YAXIS): return y2transform;
        }
       
        return null;
    }
   
    /** This method computes the default transform which transforms the
     * user space coordinates of this coordinate system to the pixel
     * space coordinates used in the Graphics object.
     * All rendering in the CoordinateSystem and the ChartRenderers
     * will rely on this transform.
     * @param axis defines which y-axis to use.
     */
    public AffineTransform getDefaultTransform(int axis) {
        double x_pt2px = 0;
        double y_pt2px = 0;
        double xcoord0 = 0;
        double ycoord0 = 0;
       
        x_pt2px = 1 / getXAxis().getPointToPixelRatio();
        //System.out.println("** x_pt2px = "+getXAxis().getPointToPixelRatio());
        xcoord0 = getBounds().getX() + getLeftMargin() + getXAxis().getPixelForValue(0.0);
       
        switch(axis) {
            case FIRST_YAXIS:
                y_pt2px = 1 / getFirstYAxis().getPointToPixelRatio();
                ycoord0 = getBounds().getY() + getBounds().getHeight() - getBottomMargin() -
                getFirstYAxis().getPixelForValue(0.0);
                break;
            case SECOND_YAXIS:
                y_pt2px = 1 / getSecondYAxis().getPointToPixelRatio();
                ycoord0 = getBounds().getY() + getBounds().getHeight() - getBottomMargin() -
                getSecondYAxis().getPixelForValue(0.0);
                break;
        }
        return new AffineTransform(x_pt2px, 0f, 0f,
        -y_pt2px, xcoord0, ycoord0);
    }
   
    /** Sets the x-axis.
     * @param a the x-axis
     */
    public void setXAxis(Axis a) {
        xaxis = a;
    }
   
    /** Returns the x axis.
     * @return the x-axis
     */
    public Axis getXAxis() {
        return xaxis;
    }

    /** Sets the x-axis unit string.
     * @param xtext the unit string
     */
    public void setXAxisUnit(String xunit) {
        this.xaxis_unit = xunit;
    }
   
    /** Gets the x-axis unit string.
     * @return the label String
     */
    public String getXAxisUnit() {       
        return xaxis_unit;
    }
   
    /** Sets the y-axis unit string.
     * @param ytext the unit string
     */
    public void setYAxisUnit(String yunit) {
        this.yaxis_unit = yunit;
    }
   
    /** Gets the y-axis label.
     * @return the label String
     */
    public String getYAxisUnit() {       
        return yaxis_unit;
    }
   
    /** Sets the font for the axis labels.
     * @param f the Font to be used
     */
    public void setFont(Font f) {
        font = f;
    }
   
    /** Returns the font used for the axis labels.
     * @return the Font object
     */
    public Font getFont() {       
        return font;
    }

    /** Sets the left y-axis and computes the matrix transformation.
     * @param a the left y-axis
     */
    public void setFirstYAxis(Axis a) {
        yaxis = a;
    }
   
    /** Returns the first y-axis.
     * @return the left y-axis
     */
    public Axis getFirstYAxis() {
        return yaxis;
    }
   
    /** Sets the second y-axis and computes the matrix transformation.
     * @param a the right y-axis
     */
    public void setSecondYAxis(Axis a) {
        yaxis2 = a;
    }
   
    /** Returns the second y-axis.
     * @return the right y-axis
     */
    public Axis getSecondYAxis() {
        return yaxis2;
    }
   
    /** Returns the inner margin, ie the bounds minus the margins.
     * @return a Rectangle object defining the inner bounds.
     */
    public Rectangle getInnerBounds() {
        Rectangle b = getBounds();
        Rectangle i = new Rectangle((int)b.getX() + getLeftMargin() - 1,
        (int)b.getY() + getTopMargin() - 1,
        (int)b.getWidth() - (getLeftMargin() + getRightMargin()) + 2,
        (int)b.getHeight() - (getTopMargin() + getBottomMargin()) + 2);
        return i;
    }
   
    /** Computes all margins, initializes the length of the Axis and
     * calls <code>super.setBounds</code>. Additionally, it sets the
     * default AffineTransforms for every y-axis.
     * @param bounds <CODE>Rectangle</CODE> object defining the bounds
     */
    public void setBounds(Rectangle bounds) {
        super.setBounds(bounds);
 
  setRightMargin(c.computeRightMargin());
  setLeftMargin(c.computeLeftMargin());
 
  setTopMargin(c.computeTopMargin());
  setBottomMargin(c.computeBottomMargin());
       
        xaxis.setLength((int)(bounds.getWidth()) - getLeftMargin() - getRightMargin());
        //System.out.println("** xaxis.length = "+xaxis.getLength());
        yaxis.setLength((int)(bounds.getHeight()) - getTopMargin() - getBottomMargin());
        //System.out.println("** yaxis.length = "+yaxis.getLength());
        setTransform(getDefaultTransform(FIRST_YAXIS), FIRST_YAXIS);
        if(yaxis2 != null) {
            yaxis2.setLength((int)(bounds.getHeight()) - getTopMargin() - getBottomMargin());
            setTransform(getDefaultTransform(SECOND_YAXIS), SECOND_YAXIS);
        }
    }
   
    /** Returns the preferred size needed for the renderer.
     * @return a Dimension with the minimum Integer values.
     */
    public Dimension getPreferredSize() {
        return new Dimension(Integer.MIN_VALUE, Integer.MIN_VALUE);
    }
   
    /** Overrides the method to just call <code>paintDefault</code>.
     * @param g the <CODE>Graphics2D</CODE> object to paint in
     */
    public void render(Graphics2D g) {
        paintDefault(g);
    }
   
    /** This method is called by the paint method to do the actual painting.
     * The painting is supposed to start at point (0,0) and the size is
     * always the same as the preferred size. The paint method performs
     * the possible scaling.
     * @param g the <CODE>Graphics2D</CODE> object to paint in
     */
    public void paintDefault(Graphics2D g) {
        g.setColor(Color.black);
       
        Line2D x = c.getXAxisLine2D();
        Line2D y = c.getYAxisLine2D();
       
        g.draw(x);
        g.draw(y);
       
        // draw X-Axis Arrow
    if(shouldDrawArrows) {
      g.drawLine((int)x.getX2(), (int)x.getY2(), (int)x.getX2() + ARROWLENGTH, (int)x.getY2());
      g.fillPolygon(new int[] {(int)(x.getX2() + ARROWLENGTH / 3.0),
            (int)(x.getX2() + ARROWLENGTH / 3.0),
            (int)(x.getX2() + ARROWLENGTH)},
            new int[] {(int)x.getY2() - 3, (int)x.getY2() + 3, (int)x.getY2()},
            3);
    }
       
        // draw X-Axis label right below the Arrow ?!
        g.setColor(Color.black);
        TextLayout layoutX = new TextLayout(getXAxisUnit(), getFont(),
                                           new FontRenderContext(null, true, false));
    layoutX.draw(g, (float)x.getX2() + (float)ARROWLENGTH / 3(float)x.getY2() + (float)layoutX.getBounds().getHeight() + 5);
       
        // draw Y-Axis Arrow
    if(shouldDrawArrows) {
      g.drawLine((int)y.getX1(), (int)y.getY1(), (int)y.getX1(), (int)y.getY1() - ARROWLENGTH);
      g.fillPolygon(new int[] {(int)(y.getX1() - 3),
            (int)(y.getX1() + 3),
            (int)(y.getX1())},
            new int[] {(int)(y.getY1() - ARROWLENGTH / 3.0),
            (int)(y.getY1() - ARROWLENGTH / 3.0),
            (int)y.getY1() - ARROWLENGTH},
            3);
    }

        // draw Y-Axis label right below the Arrow ?!
        g.setColor(Color.black);
        TextLayout layoutY = new TextLayout(getYAxisUnit(), getFont(),
                                           new FontRenderContext(null, true, false));
        layoutY.draw(g, (float)y.getX1()-6-(float)layoutY.getBounds().getWidth(),
                        (float)y.getY1() - layoutX.getDescent() - 3);
       
        if(getSecondYAxis() != null) {
            Line2D y2 = c.getSecondYAxisLine2D();
            g.draw(y2);
        }
       
        if(model.isColumnNumeric())
            c.drawNumericalXAxisTicks(g);
        else
            c.drawXAxisTicks(g);
       
        c.drawYAxisTicks(g);
    }
   
    /** Returns a new PointToPixelTranslator for the given axis.
     * Please notice that this method is deprecated since release 0.92.
     * The PointToPixelTranslator interface has been replaced with
     * AffineTransforms.
     * @param y the y-axis identifier used to choose the right Point / Pixel ratio
     * @return a PointToPixelTranslator object or null if the resulting
     * Point is not within the Bounds of the Coordinate System
     * @deprecated
     */
    public PointToPixelTranslator getPointToPixelTranslator(int yaxis) {
        final Axis x = this.getXAxis();
        final Axis y;
        if(yaxis == CoordSystem.FIRST_YAXIS)
            y = this.getFirstYAxis();
        else
            y = this.getSecondYAxis();
       
        return new PointToPixelTranslator() {
            public Point2D getPixelCoord(Point2D pt) {
                double x0 = 0.0;
                double y0 = 0.0;
               
                x0 = getBounds().getX()+getLeftMargin()+
                x.getPixelForValue(pt.getX());
               
                y0 = getBounds().getY()+getBounds().getHeight() - getBottomMargin() -
                y.getPixelForValue(pt.getY());
                Point2D p = new Point2D.Double(x0, y0);
               
                if(getInnerBounds().contains(p))
                    return p;
                else
                    return null;
            }
        };
    }
   
    /** Returns the left margin. */
    protected int getLeftMargin() {
        return leftmargin;
    }
   
    /** Returns the right margin. */
    protected int getRightMargin() {
        return rightmargin;
    }
   
    /** Returns the top margin. */
    protected int getTopMargin() {
        return topmargin;
    }
   
    /** Returns the bottom margin. */
    protected int getBottomMargin() {
        return bottommargin;
    }
   
    /** Sets the left margin.
     * @param margin the new margin value
     */
    protected void setLeftMargin(int margin) {
        leftmargin = margin;
    }
   
    /** Sets the right margin.
     * @param margin the new margin value
     */
    protected void setRightMargin(int margin) {
        rightmargin = margin;
    }
   
    /** Sets the top margin.
     * @param margin the new margin value
     */
    protected void setTopMargin(int margin) {
        topmargin = margin;
    }
   
    /** Sets the bottom margin.
     * @param margin the new margin value
     */
    public void setBottomMargin(int margin) {
        bottommargin = margin;
    }
 
  /** Returns the FontRenderContext used througout the CoordSystem*/
  public FontRenderContext getFontRenderContext() {
    return frc;
  }
 
    /** Returns the DecimalFormat used throught on the Yaxis of the CoordSystem*/
    public DecimalFormat getYDecimalFormat() {
    return dfY;
  }
 
    /** Returns the DecimalFormat used throught on the Xaxis of the CoordSystem*/
  public DecimalFormat getXDecimalFormat() {
    return dfX;
  }
   
    /** if true, the arrows will be drawn at the end of the axis*/
  public boolean isDrawArrows() {
    return shouldDrawArrows;
  }
   
    /** if true, the increment will be painted at each tick mark*/
  public boolean isPaintAltTick() {
    return shouldPaintAltTick;
  }
   
    /** if true only the tick will be painted on the yaxis.  Alternately a
     * light grey line will paint across the background of the chart.*/
    public boolean isPaintOnlyTick() {
    return shouldPaintOnlyTick;
  }
  
    public boolean isPaintLabels() {
        return shouldPaintLabels;
    }
   
    public void setPaintLabels(boolean label) {
        shouldPaintLabels = label;
    }
   
    /** Returns the used ChartDataModelConstraints. */
    public ChartDataModelConstraints getChartDataModelConstraints(int axis) {
        if(axis == FIRST_YAXIS)
            return constraints;
        else if(axis == SECOND_YAXIS)
            return constraints2;
        else
            return null;
    }
}
TOP

Related Classes of de.progra.charting.CoordSystem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.