Android Open Source - AnkiStats X Axis






From Project

Back to project page AnkiStats.

License

The source code is released under:

GNU General Public License

If you think the Android project AnkiStats listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * /*from  w  w w. j av  a  2 s.c  o m*/
 */
package com.wildplot.android.rendering;


import java.text.DecimalFormat;

import com.wildplot.android.rendering.graphics.wrapper.FontMetrics;
import com.wildplot.android.rendering.graphics.wrapper.Graphics;
import com.wildplot.android.rendering.graphics.wrapper.Rectangle;
import com.wildplot.android.rendering.interfaces.Drawable;

/**
 * This Class represents a Drawable x-axis 
 * 
 */
public class XAxis implements Drawable {

    private boolean isIntegerNumbering = false;
  public boolean hasVariableLimits = true;
  
  /**
   * this determines if this axis uses automatic tics calculation based on pixel distance between tics
   */
  private boolean isAutoTic = false;
  
  /**
   * believe it or not, this axis can be placed higher or lower than y=0
   */
  private double yOffset = 0;
  
  /**
   * the offset of the y-axis so that we know where the intersection is
   */
  private double xOffset = 0;
  
  /**
   * Name of axis
   */
  private String name = "X";
  
  /**
   * Format that is used to print numbers under markers
   */
  private DecimalFormat df =   new DecimalFormat( "##0.0#" );
  
  /**
   * format for very big or small values
   */
  private DecimalFormat dfScience =   new DecimalFormat( "0.0##E0" );
    private DecimalFormat dfInteger =   new DecimalFormat( "#.#" );
  /**
   * is set to true if scientifiv format (e.g. 1E-3) should be used
   */
  private boolean isScientific = false;
  
  /**
   * the PlotSheet object the x-axis is drawn onto
   */
  private PlotSheet plotSheet;
  
  /**
   * the start of x-axis marker, used for relative alignment of further marks
   */
  private double ticStart = 0;
  
  /**
   * the space between two marks
   */
  private double tic = 1;
  
  /**
   * the space between two minor marks
   */
  private double minorTic= 0.5;
  
  /**
   * the estimated size between two major tics in auto tic mode
   */
  private float pixelDistance = 25;
  
  /**
   * the estimated size between two minor tics in auto tic mode
   */
  private float minorPixelDistance = 25;
  
  /**
   * start of drawn x-axis
   */
  private double start = 0;
  
  /**
   * end of drawn x-axis
   */
  private double end = 100;
  
  /**
   * true if the marker should be drawn into the direction above the axis
   */
  private boolean markOnUpside = true;
  
  /**
   * true if the marker should be drawn into the direction under the axis
   */
  private boolean markOnDownside = true;
  
  /**
   * length of a marker in pixel, length is only for one side
   */
  private float markerLength = 5;
  
  /**
   * true if this  axis is drawn onto the frame
   */
  private boolean isOnFrame = false;
  //FIXME if Axis is on frame and zoom is used, stay on frame!

    private String[] mTickNameList = null;
    private double[] mTickPositions = null;
  
  
  /**
   * Constructor for an X-axis object
   * @param plotSheet the sheet the axis will be drawn onto
   * @param ticStart the start of the axis markers used for relative alignment of other markers
   * @param tic the space between two markers
   */
  public XAxis(PlotSheet plotSheet, double ticStart, double tic, double minorTic) {
    this.plotSheet = plotSheet;
    this.ticStart = ticStart;
    this.tic = tic;
    this.minorTic = minorTic;
  }
  
  /**
   * Constructor for an X-axis object this instance uses autocalculation of tics with a given pixeldistance
   * @param plotSheet the sheet the axis will be drawn onto
   * @param ticStart the start of the axis markers used for relative alignment of other markers
   */
  public XAxis(PlotSheet plotSheet, double ticStart, float pixelDistance, float minorPixelDistance ) {
    this.plotSheet = plotSheet;
    this.ticStart = ticStart;
    this.pixelDistance = pixelDistance;
    this.minorPixelDistance = minorPixelDistance;
    this.isAutoTic = true;
  }
  
  /*
   * (non-Javadoc)
   * @see rendering.Drawable#paint(java.awt.Graphics)
   */
  public void paint(Graphics g) {
    Rectangle field = g.getClipBounds();
    
    if(this.hasVariableLimits){
      start = plotSheet.getxRange()[0];
      end = plotSheet.getxRange()[1];
    }
    
    if(this.isOnFrame)
      yOffset = plotSheet.getyRange()[0];
      
    if(this.isAutoTic){
      this.tic = plotSheet.ticsCalcX(pixelDistance, field);      
      double quotient = (pixelDistance*1.0)/(minorPixelDistance*1.0);
      this.minorTic = (this.tic / Math.round(quotient));
      //System.err.println("XAXIS DEBUG");
    }
    else {
      this.pixelDistance = Math.abs(plotSheet.xToGraphic(0, field) - plotSheet.xToGraphic(tic, field));
      this.minorPixelDistance = Math.abs(plotSheet.xToGraphic(0, field) - plotSheet.xToGraphic(minorTic, field));
    }
    if(this.tic < 1e-2 || this.tic > 1e2)
      this.isScientific = true;
    
    //horizontale Linie
        float[] coordStart   = plotSheet.toGraphicPoint(start, yOffset, field);
        float[] coordEnd     = plotSheet.toGraphicPoint(end, yOffset, field);
    
    if(!this.isOnFrame)
      g.drawLine(coordStart[0], coordStart[1], coordEnd[0], coordEnd[1]);
    
    drawMarkers(g);
        if(mTickPositions == null)
        drawMinorMarkers(g);
  }



  /**
   * draw markers on the axis
   * @param g graphic object used for drawing
   */
  private void drawMarkers(Graphics g) {
    Rectangle field = g.getClipBounds();


        if(mTickPositions == null)
            drawImplicitMarker(g);
        else
            drawExplicitMarkers(g);


    //arrow
        float[] arowheadPos = {(plotSheet.getxRange()[1] >= this.end)? plotSheet.xToGraphic( this.end, field): plotSheet.xToGraphic(plotSheet.getxRange()[1], field), plotSheet.yToGraphic(yOffset, field) };

    FontMetrics fm = g.getFontMetrics( g.getFont() );
        float fontHeigth = fm.getHeight(true);
        float width = fm.stringWidth(this.name);
    if(!this.isOnFrame) {
      g.drawLine(arowheadPos[0]-1, arowheadPos[1]-1, arowheadPos[0]-6, arowheadPos[1]-3);
      g.drawLine(arowheadPos[0]-1, arowheadPos[1]+1, arowheadPos[0]-6, arowheadPos[1]+3);
      g.drawString(this.name, arowheadPos[0]-14-width, arowheadPos[1] + 12);
    } else {
            float[] middlePosition = {plotSheet.xToGraphic(0, field), plotSheet.yToGraphic( yOffset, field) };
      g.drawString(this.name, field.width/2-width/2, Math.round(middlePosition[1]+fontHeigth* 2.5f));
    }
  }

    private void drawImplicitMarker(Graphics g){
        Rectangle field = g.getClipBounds();
        int tics = (int)((this.ticStart - this.start)/tic);
        double leftStart = this.ticStart - this.tic*tics;

        double currentX = leftStart;

        while(currentX <= this.end) {
            if((!this.isOnFrame && plotSheet.xToGraphic(currentX, field) <= plotSheet.xToGraphic(this.end, field) -45
                    && plotSheet.xToGraphic(currentX, field) <= field.x + field.width - 45) ||
                    (this.isOnFrame && currentX <= this.plotSheet.getxRange()[1] &&
                            currentX >= this.plotSheet.getxRange()[0])){

                if(currentX < this.plotSheet.getxRange()[0]){
                    //System.out.println("WTF");
                }
                if(this.markOnDownside) {
                    drawDownwardsMarker(g, field, currentX);
                }
                if(this.markOnUpside) {
                    drawUpwardsMarker(g, field, currentX);
                }
                drawNumbering(g, field, currentX, -1);
            }
            currentX += this.tic;
        }
    }

    private void drawExplicitMarkers(Graphics g){
        Rectangle field = g.getClipBounds();
        for(int i = 0; i < mTickPositions.length; i ++){
            double currentX = mTickPositions[i];
            if((!this.isOnFrame && plotSheet.xToGraphic(currentX, field) <= plotSheet.xToGraphic(this.end, field) -45
                    && plotSheet.xToGraphic(currentX, field) <= field.x + field.width - 45) ||
                    (this.isOnFrame && currentX <= this.plotSheet.getxRange()[1] &&
                            currentX >= this.plotSheet.getxRange()[0])){

                if(currentX < this.plotSheet.getxRange()[0]){
                    //System.out.println("WTF");
                }
                if(this.markOnDownside) {
                    drawDownwardsMarker(g, field, currentX);
                }
                if(this.markOnUpside) {
                    drawUpwardsMarker(g, field, currentX);
                }
                drawNumbering(g, field, currentX, i);
            }
        }
    }
  
  /**
   * draw number under a marker
   * @param g graphic object used for drawing
   * @param field bounds of plot
   * @param x position of number
   */
  private void drawNumbering(Graphics g, Rectangle field, double x, int index) {
    
    if(this.tic < 1 && Math.abs(ticStart-x) <  this.tic*this.tic)
      x = ticStart;
    
    FontMetrics fm = g.getFontMetrics( g.getFont() );
        float fontHeigth = fm.getHeight();
        float[] coordStart = plotSheet.toGraphicPoint(x, yOffset, field);
    if(Math.abs(x) - Math.abs(xOffset) <0.001 && !this.isOnFrame){
      coordStart[0]+=10;
      coordStart[1]-=10;
    }

    String text = (mTickNameList == null)?df.format(x) : mTickNameList[index];
        float width = fm.stringWidth(text);
    if(this.isScientific || width > this.pixelDistance){
      text = (mTickNameList == null)?dfScience.format(x) : mTickNameList[index];
      width = fm.stringWidth(text);
      g.drawString(text, coordStart[0]-width/2, Math.round(coordStart[1]+((this.isOnFrame)? Math.round(fontHeigth*1.5) : 20)));
    }else if(isIntegerNumbering){
            text = (mTickNameList == null)?dfInteger.format(x) : mTickNameList[index];
            width = fm.stringWidth(text);
            g.drawString(text, coordStart[0]-width/2, Math.round(coordStart[1]+((this.isOnFrame)? Math.round(fontHeigth*1.5) : 20)));
        } else {
      width = fm.stringWidth(text);
      g.drawString(text, coordStart[0]-width/2, Math.round(coordStart[1]+((this.isOnFrame)? Math.round(fontHeigth*1.5) : 20)));
    }
  }
  
  /**
   * draws an upwards marker
   * @param g graphic object used for drawing
   * @param field bounds of plot
   * @param x position of marker
   */
  private void drawUpwardsMarker(Graphics g, Rectangle field, double x){

        float[] coordStart = plotSheet.toGraphicPoint(x, yOffset, field);
        float[] coordEnd = {coordStart[0], coordStart[1] - this.markerLength};
    g.drawLine(coordStart[0], coordStart[1], coordEnd[0], coordEnd[1]);
    
  }
  
  /**
   * draws an downwards marker
   *@param g graphic object used for drawing
   * @param field bounds of plot
   * @param x position of marker
   */
  private void drawDownwardsMarker(Graphics g, Rectangle field, double x){
        float[] coordStart = plotSheet.toGraphicPoint(x, yOffset, field);
        float[] coordEnd = {coordStart[0], coordStart[1] + this.markerLength};
    g.drawLine(coordStart[0], coordStart[1], coordEnd[0], coordEnd[1]);
    
  }

  /**
   * get the offset of this axis
   * @return the offset of this axis
   */
  public double getyOffset() {
    return yOffset;
  }
  
  /**
   * set the offset of this axis
   * @param yOffset new offset
   */
  public void setyOffset(double yOffset) {
    this.yOffset = yOffset;
  }
  
  /**
   * set offset back to zero for normal axis behavior
   */
  public void unsetyOffset() {
    this.yOffset = 0;
  }
  
  /**
   * set the axis to draw on the border between outer frame and plot
   */
  public void setOnFrame() {
    this.isOnFrame = true;
    yOffset = plotSheet.getyRange()[0];
    markOnDownside = false;
  }
  
  /**
   * unset the axis to draw on the border between outer frame and plot
   */
  public void unsetOnFrame() {
    this.isOnFrame = false;
    yOffset = 0;
    markOnDownside = true;
  }
  
  /*
   * (non-Javadoc)
   * @see rendering.Drawable#isOnFrame()
   */
  public boolean isOnFrame() {
    return isOnFrame;
  }
  
  /**
   * set name description of axis
   * @param name of axis
   */
  public void setName(String name) {
    this.name = name;
  }
  /**
   * draw minor markers on the axis
   * @param g graphic object used for drawing
   */
  private void drawMinorMarkers(Graphics g) {
    Rectangle field = g.getClipBounds();
    
    int tics = (int)((this.ticStart - this.start)/tic);
    double leftStart = this.ticStart - this.tic*tics;

    double currentX = leftStart;
    
    while(currentX <= this.end) {
      if((!this.isOnFrame && plotSheet.xToGraphic(currentX, field) <= plotSheet.xToGraphic(this.end, field) -45 
          && plotSheet.xToGraphic(currentX, field) <= field.x + field.width - 45) || 
          (this.isOnFrame && currentX <= this.plotSheet.getxRange()[1] &&
          currentX >= this.plotSheet.getxRange()[0])){
        
        if(currentX < this.plotSheet.getxRange()[0]){
          //System.out.println("WTF");
        }
        if(this.markOnDownside) {
          drawDownwardsMinorMarker(g, field, currentX);
        }
        if(this.markOnUpside) {
          drawUpwardsMinorMarker(g, field, currentX);
        }

        //drawNumbering(g, field, currentX);
      }
      currentX += minorTic;
//      currentX += calcMinorTics(g)*this.tic;
    }

  }
  
//  /**
//   * caculates minor tics
//   * @param g graphic object used for drawing
//   * @return returns the new minor tics in percent
//   */
//  private double calcMinorTics(Graphics g)
//  {
//    double percentMinorTic=this.minorTic/this.tic;
//    return percentMinorTic;
//  }
  
  /**
   * draws an upwards minor marker
   * @param g graphic object used for drawing
   * @param field bounds of plot
   * @param x position of marker
   */
  private void drawUpwardsMinorMarker(Graphics g, Rectangle field, double x){

        float[] coordStart = plotSheet.toGraphicPoint(x, yOffset, field);
        float[] coordEnd = {coordStart[0], (int) (coordStart[1] - 0.5*this.markerLength)};
    g.drawLine(coordStart[0], coordStart[1], coordEnd[0], coordEnd[1]);
    
  }
  
  /**
   * draws an downwards minor marker
   *@param g graphic object used for drawing
   * @param field bounds of plot
   * @param x position of marker
   */
  private void drawDownwardsMinorMarker(Graphics g, Rectangle field, double x){
        float[] coordStart = plotSheet.toGraphicPoint(x, yOffset, field);
        float[] coordEnd = {coordStart[0], (int) (coordStart[1] + 0.5*this.markerLength)};
    g.drawLine(coordStart[0], coordStart[1], coordEnd[0], coordEnd[1]);
    
  }
    public void setIntegerNumbering(boolean isIntegerNumbering){
        this.isIntegerNumbering = isIntegerNumbering;
    }
  @Override
  public void abortAndReset() {
    // TODO Auto-generated method stub
    
    }
    @Override
    public boolean isClusterable() {
        return true;
    }

    @Override
    public boolean isCritical() {
        return true;
    }

    public void setExplicitTics(double[] tickPositions, String[] tickNameList){
        mTickPositions = tickPositions;
        mTickNameList = tickNameList;
    }
    public void unsetExplicitTics(){
        mTickNameList = null;
        mTickPositions = null;
    }

}




Java Source Code List

com.wildplot.android.ankistats.AnkiDb.java
com.wildplot.android.ankistats.AnkiStatsActivity.java
com.wildplot.android.ankistats.AnkiStatsApplication.java
com.wildplot.android.ankistats.AnswerButton.java
com.wildplot.android.ankistats.ApplicationTest.java
com.wildplot.android.ankistats.CardsTypes.java
com.wildplot.android.ankistats.CollectionData.java
com.wildplot.android.ankistats.Forecast.java
com.wildplot.android.ankistats.HourlyBreakdown.java
com.wildplot.android.ankistats.Intervals.java
com.wildplot.android.ankistats.ReviewCount.java
com.wildplot.android.ankistats.Utils.java
com.wildplot.android.ankistats.WeeklyBreakdown.java
com.wildplot.android.parsing.Atom.java
com.wildplot.android.parsing.ExpressionFormatException.java
com.wildplot.android.parsing.Expression.java
com.wildplot.android.parsing.Factor.java
com.wildplot.android.parsing.Pow.java
com.wildplot.android.parsing.Term.java
com.wildplot.android.parsing.TopLevelParser.java
com.wildplot.android.parsing.TreeElement.java
com.wildplot.android.parsing.AtomTypes.FunctionXAtom.java
com.wildplot.android.parsing.AtomTypes.FunctionXYAtom.java
com.wildplot.android.parsing.AtomTypes.MathFunctionAtom.java
com.wildplot.android.parsing.AtomTypes.NumberAtom.java
com.wildplot.android.parsing.AtomTypes.VariableAtom.java
com.wildplot.android.parsing.AtomTypes.XVariableAtom.java
com.wildplot.android.parsing.AtomTypes.YVariableAtom.java
com.wildplot.android.rendering.AdvancedPlotSheet.java
com.wildplot.android.rendering.BarGraph.java
com.wildplot.android.rendering.DrawableContainer.java
com.wildplot.android.rendering.FunctionDrawer.java
com.wildplot.android.rendering.FunctionDrawer_y.java
com.wildplot.android.rendering.Integral.java
com.wildplot.android.rendering.LegendDrawable.java
com.wildplot.android.rendering.LinesPoints.java
com.wildplot.android.rendering.Lines.java
com.wildplot.android.rendering.MultiScreenPart.java
com.wildplot.android.rendering.PieChart.java
com.wildplot.android.rendering.PlotSheet.java
com.wildplot.android.rendering.PointDrawer2D.java
com.wildplot.android.rendering.RelativeColorGradient.java
com.wildplot.android.rendering.ReliefDrawer.java
com.wildplot.android.rendering.XAxisBarGraph.java
com.wildplot.android.rendering.XAxisHistoGram.java
com.wildplot.android.rendering.XAxis.java
com.wildplot.android.rendering.XGrid.java
com.wildplot.android.rendering.YAxisBarGraph.java
com.wildplot.android.rendering.YAxisHistoGram.java
com.wildplot.android.rendering.YAxis.java
com.wildplot.android.rendering.YGrid.java
com.wildplot.android.rendering.graphics.wrapper.BasicStroke.java
com.wildplot.android.rendering.graphics.wrapper.BufferedImage.java
com.wildplot.android.rendering.graphics.wrapper.Color.java
com.wildplot.android.rendering.graphics.wrapper.FontMetrics.java
com.wildplot.android.rendering.graphics.wrapper.Graphics2D.java
com.wildplot.android.rendering.graphics.wrapper.Graphics.java
com.wildplot.android.rendering.graphics.wrapper.Rectangle.java
com.wildplot.android.rendering.graphics.wrapper.Stroke.java
com.wildplot.android.rendering.interfaces.Drawable.java
com.wildplot.android.rendering.interfaces.Function2D.java
com.wildplot.android.rendering.interfaces.Function3D.java
com.wildplot.android.rendering.interfaces.Legendable.java
com.wildplot.android.rendering.interfaces.StepFunction2D.java