AbstractChartRender.java :  » Chart » charts4a » com » cloud » charts4a » chart » render » Android Open Source

Android Open Source » Chart » charts4a 
charts4a » com » cloud » charts4a » chart » render » AbstractChartRender.java
package com.cloud.charts4a.chart.render;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import com.cloud.charts4a.chart.attrib.AbstractXAxisAttribs;
import com.cloud.charts4a.chart.attrib.YAxisAttribs;
import com.cloud.charts4a.chart.attrib.YRangeHighLightAttribs;
import com.cloud.charts4a.data.AbstractChartData;
import com.cloud.charts4a.data.ChartDataSeries;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;

/**
 * Abstract Chart Render<p/>
 *
 * @param <T1>  subclass of AbstractXAxisAttribs class
 * @param <T2>  subclass of AbstractChartData class
 * 
 * @version
 * <ol>
 *   <li>2010/07/09 CloudTuFirst Release</li>
 * </ol>
 * 
 * @author cloudtu 
 */
abstract class AbstractChartRender<T1 extends AbstractXAxisAttribs<?, ?>,T2 extends AbstractChartData<T2>> {
  /**
   * 
   */  
  protected static final DecimalFormat tipDecimalFormat = new DecimalFormat("#.##");      
  
  /**
   * Canvas
   */
  protected Canvas canvas;
  
  /**
   * Canvas width
   */
  protected float canvasWidth;
  
  /**
   * Canvas Height
   */
  protected float canvasHeight;
  
  /**
   * X
   */
  protected String[] xAxisLabels;
  
  /**
   * Y
   */
  protected int[] yAxisLabels;
  
  /**
   * 
   */
  protected String[] legends;
  
  /**
   * legends's color
   */
  protected int[] legendColors;
  
  /**
   * X
   */
  protected boolean isShowXUnitDesc;
  
  /**
   * Y
   */
  protected boolean isShowYUnitDesc;
  
  /**
   * 
   */
  protected boolean isShowLegend;
  
  /**
   * 
   */
  protected boolean isOnlyShowDot;
  
  /**
   * X-Axis attributes in chart
   */
  protected T1 xAxisAttribs;
  
  /**
   * Y-Axis attributes in chart
   */
  protected YAxisAttribs yAxisAttribs;
  
  /**
   * Y-Axis range highlight attributes
   */
  protected YRangeHighLightAttribs yRangeHighLightAttribs;
  
  /**
   * ChartDataSeries list
   */
  protected List<ChartDataSeries<T2>> chartDataSeriesList = new ArrayList<ChartDataSeries<T2>>();
  
  /**
   * XYpaint object
   */
  protected Paint xyAxisPaint;
  
  /**
   * XYpaint object
   */
  protected Paint xyAxisBackgroundGridPaint;    
  
  /**
   * XY paint object
   */
  protected Paint xyAxisLabelPaint;  
  
  /**
   * XYPaint object
   */
  protected Paint xyAxisUnitDescPaint;  
  
  /**
   * X-Axis interval pixels of two xAxisLabel unit 
   */
  protected float xAxisIntervalForTwoXAxisLabelUnit;  
  
  /**
   * Y-Axis interval pixels of two yAxisLabel unit
   */
  protected float yAxisIntervalForTwoYAxisLabelUnit;  
  
  /**
   * XPixel
   */
  protected float xAxisUnitDescHeight;  
  
  /**
   * XPixel
   */
  protected float xAxisUnitDescHeightWithTopAndBottomPad;  
  
  /**
   * YPixel
   */
  protected float yAxisUnitDescHeightWithTopAndBottomPad;
  
  /**
   * xyAxisLabel height pixels
   */
  protected float xyAxisLabelHeight;    
  
  /**
   * xAxisLabelPixel
   */
  protected float xAxisLabelHeightWithTopAndBottomPad;  
  
  /**
   * yAxisLabelPixel
   */
  protected float yAxisLabelWidthWithLeftAndRightPad;
  
  /**
   * one legend height pixels with top and bottom padding
   */
  protected float oneLegendUnitHeightWithTopAndBottomPad;  
  
  /**
   * total legends height pixels with top and bottom padding
   */
  protected float totalLegendsHeightWithTopAndBottomPad;  
  
  protected ChartRenderBo chartRenderBo;  

  /**
   * Draw chart
   */
  public void drawChart(){        
    drawXYAxisBackgroundGrid();
    drawContents();
    drawBlankRectAboveMaxYAxisValueAndBelowMinYAxisValue();
    drawXAxisLabels();
    drawYAxisLabels();
    drawXAxisUnitDesc();
    drawYAxisUnitDesc();  
    drawLegends();    
  }
  
  /**
   * initial xAxisLabels variable
   */
  abstract protected void initXAxisLabelsValue();  
  
  /**
   * initial yAxisLabels variable
   */    
  protected void initYAxisLabelsValue(){            
    //(yAxisAttribs.getMinYValue() != null && yAxisAttribs.getMaxYValue() != null)yAxisLabels
    //chartDataSeriesListyAxisLabels
    if(yAxisAttribs.getMinYValue() != null && yAxisAttribs.getMaxYValue() != null){
      yAxisLabels = new int[(yAxisAttribs.getMaxYValue() - yAxisAttribs.getMinYValue())/yAxisAttribs.getYValueInterval() + 1];    
      for(int i=0;i<yAxisLabels.length;i++){
        yAxisLabels[i] = yAxisAttribs.getMinYValue() + yAxisAttribs.getYValueInterval() * i;
      }      
    }
    else{
      //(chartDataSeriesList.size() == 0 && yRangeHighLightAttribs == null)yAxisLabels
      if(chartDataSeriesList.size() == 0 && yRangeHighLightAttribs == null){
        yAxisLabels = new int[2];
        yAxisLabels[1] = yAxisAttribs.getYValueInterval();
        return;
      }      
      
      int minYValue = Integer.MAX_VALUE;
      int maxYValue = Integer.MIN_VALUE;
        
      if(chartDataSeriesList.size() > 0){
        for (ChartDataSeries<T2> chartDataSeries : chartDataSeriesList) {
          if(chartDataSeries.getMinYValueInAllData() < minYValue){
            minYValue = (int)chartDataSeries.getMinYValueInAllData();
          }
          if(chartDataSeries.getMaxYValueInAllData() > maxYValue){
            maxYValue = (int)Math.ceil(chartDataSeries.getMaxYValueInAllData());
          }      
        }        
      }          
      
      if(yRangeHighLightAttribs != null && yRangeHighLightAttribs.getMinYValue() < minYValue){
        minYValue = yRangeHighLightAttribs.getMinYValue();
      }
      if(yRangeHighLightAttribs != null && yRangeHighLightAttribs.getMaxYValue() > maxYValue){
        maxYValue = yRangeHighLightAttribs.getMaxYValue();
      }    

      if(yAxisAttribs.getYValueInterval() >= 5){
        //minYValue5
        minYValue = (int)Math.floor((double)minYValue / 5) * 5;                  
      }    
      //minYValuemaxYValueyIntervalmaxYValue
      maxYValue = minYValue + (int)Math.abs(Math.ceil(((double)maxYValue - minYValue) / yAxisAttribs.getYValueInterval())) * yAxisAttribs.getYValueInterval();    
      
      yAxisLabels = new int[(maxYValue - minYValue)/yAxisAttribs.getYValueInterval() + 1];    
      for(int i=0;i<yAxisLabels.length;i++){
        yAxisLabels[i] = minYValue + yAxisAttribs.getYValueInterval() * i;
      }      
    }    
  }  
  
  /**
   * initial legends and legendColors variable
   */    
  protected void initLegendsValue(){
    if(isShowLegend == true && chartDataSeriesList.size() > 0){
      legends = new String[chartDataSeriesList.size()];
      legendColors = new int[chartDataSeriesList.size()];
      
      for(int i=0;i<chartDataSeriesList.size();i++){
        legends[i] = " " + chartDataSeriesList.get(i).getName();
        legendColors[i] = chartDataSeriesList.get(i).getColor();
      }      
    }    
  }  
  
  /**
   * Draw yAxisLabels
   */
  private void drawYAxisLabels(){
    float xPosition = yAxisUnitDescHeightWithTopAndBottomPad + yAxisLabelWidthWithLeftAndRightPad / 2;
    float yPosition = xAxisLabelHeightWithTopAndBottomPad + xyAxisLabelHeight / 2;
    int counter = 0;
    for(int i= yAxisLabels.length -1;i>=0;i--){
      canvas.drawText("" + yAxisLabels[i], xPosition, yPosition + counter * yAxisIntervalForTwoYAxisLabelUnit, xyAxisLabelPaint);
      counter++;
    }  
  }
  
  /**
   * Draw xAxisLabels
   */
  private void drawXAxisLabels(){
    float xPosition = yAxisUnitDescHeightWithTopAndBottomPad + yAxisLabelWidthWithLeftAndRightPad + (xAxisIntervalForTwoXAxisLabelUnit / 2);
    float yPosition = xAxisLabelHeightWithTopAndBottomPad + yAxisIntervalForTwoYAxisLabelUnit * (yAxisLabels.length - 1) + chartRenderBo.textPadding + xyAxisLabelHeight;  
    for(int i= 0;i<xAxisLabels.length;i++){
      canvas.drawText(xAxisLabels[i], xPosition + i * xAxisIntervalForTwoXAxisLabelUnit, yPosition, xyAxisLabelPaint);
    }
  }  
  
  /**
   * Draw xAxisUnitDesc
   */
  private void drawXAxisUnitDesc(){
    if(isShowXUnitDesc == true){
      float xPosition = canvasWidth / 2;
      float yPosition = xAxisLabelHeightWithTopAndBottomPad * 2 + yAxisIntervalForTwoYAxisLabelUnit * (yAxisLabels.length - 1) + chartRenderBo.textPadding + xAxisUnitDescHeight;
      canvas.drawText(xAxisAttribs.getXUnitDesc(), xPosition, yPosition, xyAxisUnitDescPaint);      
    }
  }    
  
  /**
   * Draw yAxisUnitDesc
   */
  private void drawYAxisUnitDesc(){
    if(isShowYUnitDesc == true){
      canvas.save();
      float xPosition = (canvasHeight - totalLegendsHeightWithTopAndBottomPad) / 2;
      float yPosition = - chartRenderBo.textPadding;
      canvas.rotate(90);
      canvas.drawText(yAxisAttribs.getYUnitDesc(), xPosition, yPosition, xyAxisUnitDescPaint);  
      canvas.restore();
    }
  }    
  
  /**
   * Draw legends
   */
  private void drawLegends(){
    if(isShowLegend == true && chartDataSeriesList.size() > 0){
      float checkedWidth = 0;    
      float xPosition = 0;
      float yPosition = xAxisLabelHeightWithTopAndBottomPad * 2 + yAxisIntervalForTwoYAxisLabelUnit * (yAxisLabels.length - 1) +
                xAxisUnitDescHeightWithTopAndBottomPad + oneLegendUnitHeightWithTopAndBottomPad - chartRenderBo.textPadding;  
      for(int i=0;i<legends.length;i++){
        float oneLegendUnitWidthWithLeftAndRightPad = chartRenderBo.calSpecifiedLegendWidthWithLeftAndRightPad(legends[i]);
        checkedWidth = checkedWidth + oneLegendUnitWidthWithLeftAndRightPad; 
        if(canvasWidth >= checkedWidth){
          xPosition = xPosition + oneLegendUnitWidthWithLeftAndRightPad / 2;      
        }
        else{
          xPosition = oneLegendUnitWidthWithLeftAndRightPad / 2;
          yPosition = yPosition + oneLegendUnitHeightWithTopAndBottomPad;
          checkedWidth = oneLegendUnitWidthWithLeftAndRightPad;        
        }
            
        Paint legendPaint = chartRenderBo.createLegendPaint(legendColors[i]);
        canvas.drawText(legends[i], xPosition, yPosition, legendPaint);
        xPosition = xPosition + oneLegendUnitWidthWithLeftAndRightPad / 2;      
      }      
    }
  }    
  
  /**
   * Draw XYAxis background grid
   */
  private void drawXYAxisBackgroundGrid(){
    float xPosition = yAxisUnitDescHeightWithTopAndBottomPad + yAxisLabelWidthWithLeftAndRightPad;
    float yPosition = xAxisLabelHeightWithTopAndBottomPad;

    //X
    canvas.drawLine(xPosition, yPosition + (yAxisLabels.length - 1) * yAxisIntervalForTwoYAxisLabelUnit,
            xPosition + (xAxisIntervalForTwoXAxisLabelUnit / 2) + xAxisIntervalForTwoXAxisLabelUnit * (xAxisLabels.length - 1),
            yPosition + (yAxisLabels.length - 1) * yAxisIntervalForTwoYAxisLabelUnit , xyAxisPaint);
    //Y
    canvas.drawLine(xPosition, yPosition , xPosition, yPosition + yAxisIntervalForTwoYAxisLabelUnit * (yAxisLabels.length - 1), xyAxisPaint);
              
    //X    
    for(int i=0;i<yAxisLabels.length-1;i++){
      canvas.drawLine(xPosition, yPosition + i * yAxisIntervalForTwoYAxisLabelUnit,
              xPosition + (xAxisIntervalForTwoXAxisLabelUnit / 2) + xAxisIntervalForTwoXAxisLabelUnit * (xAxisLabels.length - 1),
              yPosition + i * yAxisIntervalForTwoYAxisLabelUnit, xyAxisBackgroundGridPaint);
    }    
    //Y
    for(int j=0;j<xAxisLabels.length;j++){
      canvas.drawLine(xPosition + (xAxisIntervalForTwoXAxisLabelUnit / 2) + xAxisIntervalForTwoXAxisLabelUnit * j, yPosition ,
              xPosition + (xAxisIntervalForTwoXAxisLabelUnit / 2) + xAxisIntervalForTwoXAxisLabelUnit * j,
              yPosition + yAxisIntervalForTwoYAxisLabelUnit * (yAxisLabels.length - 1), xyAxisBackgroundGridPaint);
    }      
  }    
  
  /**
   * YY
   */  
  private void drawBlankRectAboveMaxYAxisValueAndBelowMinYAxisValue(){  
    Paint blackPaint = new Paint();
    blackPaint.setColor(Color.BLACK);    
    RectF aboveRect = new RectF(0,0,canvasWidth,xAxisLabelHeightWithTopAndBottomPad);    
    canvas.drawRect(aboveRect, blackPaint);  //Y
    
    RectF belowRect = new RectF(0,xAxisLabelHeightWithTopAndBottomPad + (yAxisLabels.length - 1) * yAxisIntervalForTwoYAxisLabelUnit,canvasWidth,canvasHeight);    
    canvas.drawRect(belowRect, blackPaint);  //Y    
    
    float xPosition = yAxisUnitDescHeightWithTopAndBottomPad + yAxisLabelWidthWithLeftAndRightPad;
    float yPosition = xAxisLabelHeightWithTopAndBottomPad;
    //X
    canvas.drawLine(xPosition, yPosition,
            xPosition + (xAxisIntervalForTwoXAxisLabelUnit / 2) + xAxisIntervalForTwoXAxisLabelUnit * (xAxisLabels.length - 1),
            yPosition, xyAxisBackgroundGridPaint);        
    //X
    canvas.drawLine(xPosition, yPosition + (yAxisLabels.length - 1) * yAxisIntervalForTwoYAxisLabelUnit,
            xPosition + (xAxisIntervalForTwoXAxisLabelUnit / 2) + xAxisIntervalForTwoXAxisLabelUnit * (xAxisLabels.length - 1),
            yPosition + (yAxisLabels.length - 1) * yAxisIntervalForTwoYAxisLabelUnit , xyAxisPaint);      
  }  
  
  /**
   * Draw all contents in XY-Axis
   */
  abstract protected void drawContents();
  
  /**
   * 
   * 
   * @param chartData  ChartData
   */
  public void drawTipOnChartWhenDotIsClicked(T2 chartData){
    //YY
    if(chartData.getYValue() < yAxisLabels[0] || chartData.getYValue() > yAxisLabels[yAxisLabels.length - 1]){  
      return;
    }    
    
    Rect tipRect = chartData.getTipRect();
    Path tipBackGroundPath = new Path();
    Paint tipBackGroundPaint = chartRenderBo.createTipBackgroundRectPaint();
    Paint tipTextPaint = chartRenderBo.createTipTextPaint();
    
    if(tipRect.top > chartData.getYPosition()){
      tipBackGroundPath.moveTo(chartData.getXPosition(), chartData.getYPosition() + 2 * chartRenderBo.dataSeriesDotRadias);
      tipBackGroundPath.lineTo(chartData.getXPosition() - 2 * chartRenderBo.dataSeriesDotRadias, ((float)tipRect.top + tipRect.bottom)/2);
      tipBackGroundPath.lineTo(chartData.getXPosition() + 2 * chartRenderBo.dataSeriesDotRadias, ((float)tipRect.top + tipRect.bottom)/2);
      tipBackGroundPath.close();
      tipBackGroundPath.addRoundRect(new RectF(tipRect.left,((float)tipRect.top + tipRect.bottom)/2,tipRect.right,tipRect.bottom),
                 chartRenderBo.tipRectCornerRadius, chartRenderBo.tipRectCornerRadius, Path.Direction.CW);      
      canvas.drawPath(tipBackGroundPath, tipBackGroundPaint);            
      canvas.drawText(chartData.getTipText(), ((float)tipRect.left + tipRect.right)/2, tipRect.bottom - chartRenderBo.tipTextPadding, tipTextPaint);        
    }
    else{
      tipBackGroundPath.addRoundRect(new RectF(tipRect.left,tipRect.top,tipRect.right,((float)tipRect.top + tipRect.bottom)/2),
                  chartRenderBo.tipRectCornerRadius, chartRenderBo.tipRectCornerRadius, Path.Direction.CW);  
      tipBackGroundPath.moveTo(chartData.getXPosition(), chartData.getYPosition() - 2 * chartRenderBo.dataSeriesDotRadias);
      tipBackGroundPath.lineTo(chartData.getXPosition() - 2 * chartRenderBo.dataSeriesDotRadias, ((float)tipRect.top + tipRect.bottom)/2);
      tipBackGroundPath.lineTo(chartData.getXPosition() + 2 * chartRenderBo.dataSeriesDotRadias, ((float)tipRect.top + tipRect.bottom)/2);
      tipBackGroundPath.close();
      canvas.drawPath(tipBackGroundPath, tipBackGroundPaint);  
      canvas.drawText(chartData.getTipText(), ((float)tipRect.left + tipRect.right)/2,
                           ((float)tipRect.top + tipRect.bottom)/2 - chartRenderBo.tipTextPadding, tipTextPaint);        
    }        
  }      
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.