Android Open Source - Android-Charts Line Chart






From Project

Back to project page Android-Charts.

License

The source code is released under:

Apache License??Version 2.0, January 2004??http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and condi...

If you think the Android project Android-Charts 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

/*
 * LineChart.java//  ww  w.  j ava  2 s. c  o  m
 * Android-Charts
 *
 * Created by limc on 2011/05/29.
 *
 * Copyright 2011 limc.cn All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.limc.androidcharts.view;

import java.util.ArrayList;
import java.util.List;

import cn.limc.androidcharts.entity.DateValueEntity;
import cn.limc.androidcharts.entity.LineEntity;
import cn.limc.androidcharts.event.IGestureDetector;
import cn.limc.androidcharts.event.IZoomable;
import cn.limc.androidcharts.event.OnZoomGestureListener;
import cn.limc.androidcharts.event.ZoomGestureDetector;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;

/**
 * 
 * <p>
 * LineChart is a kind of graph that draw some lines on a GridChart
 * </p>
 * <p>
 * LineChart???GridChart????????????????????????????????????
 * </p>
 * <p>
 * LineChart??GridChart??????????????????
 * </p>
 * 
 * @author limc
 * @version v1.0 2011/05/30 14:23:53
 * @see GridChart
 */
public class LineChart extends GridChart implements IZoomable {
  public static final int DEFAULT_LINE_ALIGN_TYPE = ALIGN_TYPE_JUSTIFY;
  /**
   * <p>
   * data to draw lines
   * </p>
   * <p>
   * ????????????
   * </p>
   * <p>
   * ????????????
   * </p>
   */
  private List<LineEntity<DateValueEntity>> linesData;

  /**
   * <p>
   * max points of a single line
   * </p>
   * <p>
   * ??????????????
   * </p>
   * <p>
   * ???????????
   * </p>
   */
  private int maxPointNum;

  /**
   * <p>
   * min value of Y axis
   * </p>
   * <p>
   * Y????????
   * </p>
   * <p>
   * Y???????
   * </p>
   */
  private double minValue;

  /**
   * <p>
   * max value of Y axis
   * </p>
   * <p>
   * Y???????
   * </p>
   * <p>
   * Y??????
   * </p>
   */
  private double maxValue;
  
  private int lineAlignType = DEFAULT_LINE_ALIGN_TYPE;

  public static final boolean DEFAULT_AUTO_CALC_VALUE_RANGE = true;
  private boolean autoCalcValueRange = DEFAULT_AUTO_CALC_VALUE_RANGE;
  
  protected OnZoomGestureListener onZoomGestureListener = new OnZoomGestureListener();
  protected IGestureDetector zoomGestureDetector = new ZoomGestureDetector<IZoomable>(this);

  /*
   * (non-Javadoc)
   * 
   * @param context
   * 
   * @see cn.limc.androidcharts.view.GridChart#GridChart(Context)
   */
  public LineChart(Context context) {
    super(context);
  }

  /*
   * (non-Javadoc)
   * 
   * @param context
   * 
   * @param attrs
   * 
   * @param defStyle
   * 
   * @see cn.limc.androidcharts.view.GridChart#GridChart(Context,
   * AttributeSet, int)
   */
  public LineChart(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  /*
   * (non-Javadoc)
   * 
   * @param context
   * 
   * @param attrs
   * 
   * 
   * 
   * @see cn.limc.androidcharts.view.GridChart#GridChart(Context,
   * AttributeSet)
   */
  public LineChart(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  protected void calcDataValueRange() {
    double maxValue = Double.MIN_VALUE;
    double minValue = Double.MAX_VALUE;
    // ???????MA?
    for (int i = 0; i < this.linesData.size(); i++) {
      LineEntity<DateValueEntity> line = (LineEntity<DateValueEntity>) linesData
          .get(i);
      if (line == null) {
        continue;
      }
      if (line.isDisplay() == false) {
        continue;
      }
      List<DateValueEntity> lineData = line.getLineData();
      if (lineData == null) {
        continue;
      }
      // ???????????????
      for (int j = 0; j < lineData.size(); j++) {
        DateValueEntity entity;
        if (axisYPosition == AXIS_Y_POSITION_LEFT) {
          entity = line.getLineData().get(j);
        } else {
          entity = line.getLineData().get(lineData.size() - 1 - j);
        }

        if (entity.getValue() < minValue) {
          minValue = entity.getValue();
        }
        if (entity.getValue() > maxValue) {
          maxValue = entity.getValue();
        }
      }
    }

    this.maxValue = maxValue;
    this.minValue = minValue;
  }

  protected void calcValueRangePaddingZero() {
    double maxValue = this.maxValue;
    double minValue = this.minValue;

    if ((long) maxValue > (long) minValue) {
      if ((maxValue - minValue) < 10. && minValue > 1.) {
        this.maxValue = (long) (maxValue + 1);
        this.minValue = (long) (minValue - 1);
      } else {
        this.maxValue = (long) (maxValue + (maxValue - minValue) * 0.1);
        this.minValue = (long) (minValue - (maxValue - minValue) * 0.1);

        if (this.minValue < 0) {
          this.minValue = 0;
        }
      }
    } else if ((long) maxValue == (long) minValue) {
      if (maxValue <= 10 && maxValue > 1) {
        this.maxValue = maxValue + 1;
        this.minValue = minValue - 1;
      } else if (maxValue <= 100 && maxValue > 10) {
        this.maxValue = maxValue + 10;
        this.minValue = minValue - 10;
      } else if (maxValue <= 1000 && maxValue > 100) {
        this.maxValue = maxValue + 100;
        this.minValue = minValue - 100;
      } else if (maxValue <= 10000 && maxValue > 1000) {
        this.maxValue = maxValue + 1000;
        this.minValue = minValue - 1000;
      } else if (maxValue <= 100000 && maxValue > 10000) {
        this.maxValue = maxValue + 10000;
        this.minValue = minValue - 10000;
      } else if (maxValue <= 1000000 && maxValue > 100000) {
        this.maxValue = maxValue + 100000;
        this.minValue = minValue - 100000;
      } else if (maxValue <= 10000000 && maxValue > 1000000) {
        this.maxValue = maxValue + 1000000;
        this.minValue = minValue - 1000000;
      } else if (maxValue <= 100000000 && maxValue > 10000000) {
        this.maxValue = maxValue + 10000000;
        this.minValue = minValue - 10000000;
      }
    } else {
      this.maxValue = 0;
      this.minValue = 0;
    }
  }

  protected void calcValueRangeFormatForAxis() {
    int rate = 1;

    if (this.maxValue < 3000) {
      rate = 1;
    } else if (this.maxValue >= 3000 && this.maxValue < 5000) {
      rate = 5;
    } else if (this.maxValue >= 5000 && this.maxValue < 30000) {
      rate = 10;
    } else if (this.maxValue >= 30000 && this.maxValue < 50000) {
      rate = 50;
    } else if (this.maxValue >= 50000 && this.maxValue < 300000) {
      rate = 100;
    } else if (this.maxValue >= 300000 && this.maxValue < 500000) {
      rate = 500;
    } else if (this.maxValue >= 500000 && this.maxValue < 3000000) {
      rate = 1000;
    } else if (this.maxValue >= 3000000 && this.maxValue < 5000000) {
      rate = 5000;
    } else if (this.maxValue >= 5000000 && this.maxValue < 30000000) {
      rate = 10000;
    } else if (this.maxValue >= 30000000 && this.maxValue < 50000000) {
      rate = 50000;
    } else {
      rate = 100000;
    }

    // ?????
    if (this.latitudeNum > 0 && rate > 1
        && (long) (this.minValue) % rate != 0) {
      // ???????
      this.minValue = (long) this.minValue
          - (long) (this.minValue) % rate;
    }
    // ?????
    if (this.latitudeNum > 0
        && (long) (this.maxValue - this.minValue)
            % (this.latitudeNum * rate) != 0) {
      // ???????
      this.maxValue = (long) this.maxValue
          + this.latitudeNum * rate
          - (long) (this.maxValue - this.minValue) % (this.latitudeNum * rate);
    }
  }

  protected void calcValueRange() {
    if (null == this.linesData) {
      this.maxValue = 0;
      this.minValue = 0;
      return;
    }
    if (this.linesData.size() > 0) {
      this.calcDataValueRange();
      this.calcValueRangePaddingZero();
    } else {
      this.maxValue = 0;
      this.minValue = 0;
    }
    this.calcValueRangeFormatForAxis();
  }

  /*
   * (non-Javadoc)
   * 
   * <p>Called when is going to draw this chart<p> <p>???????????????????????<p>
   * <p>???????<p>
   * 
   * @param canvas
   * 
   * @see android.view.View#onDraw(android.graphics.Canvas)
   */
  @Override
  protected void onDraw(Canvas canvas) {
    if (autoCalcValueRange) {
      calcValueRange();
    }

    initAxisY();
    initAxisX();

    super.onDraw(canvas);
    drawLines(canvas);

  }

  /**
   * <p>
   * draw lines
   * </p>
   * <p>
   * ????????
   * </p>
   * <p>
   * ??????
   * </p>
   * 
   * @param canvas
   */
  protected void drawLines(Canvas canvas) {
    if (null == this.linesData) {
      return;
    }
    // distance between two points
    float lineLength;
    // start points X
    float startX;

    // draw lines
    for (int i = 0; i < linesData.size(); i++) {
      LineEntity<DateValueEntity> line = (LineEntity<DateValueEntity>) linesData
          .get(i);
      if (line == null) {
        continue;
      }
      if (line.isDisplay() == false) {
        continue;
      }
      List<DateValueEntity> lineData = line.getLineData();
      if (lineData == null) {
        continue;
      }

      Paint mPaint = new Paint();
      mPaint.setColor(line.getLineColor());
      mPaint.setAntiAlias(true);
      // start point
      PointF ptFirst = null;
      if (axisYPosition == AXIS_Y_POSITION_LEFT) {
              if (lineAlignType == ALIGN_TYPE_CENTER) {
                  lineLength= (dataQuadrant.getQuadrantPaddingWidth() / maxPointNum);
                  startX = dataQuadrant.getQuadrantPaddingStartX() + lineLength / 2;
              }else {
                  lineLength= (dataQuadrant.getQuadrantPaddingWidth() / (maxPointNum - 1));
                  startX = dataQuadrant.getQuadrantPaddingStartX();
              }
        
        for (int j = 0; j < maxPointNum; j++) {
          float value = lineData.get(j).getValue();
          // calculate Y
          float valueY = (float) ((1f - (value - minValue)
              / (maxValue - minValue)) * dataQuadrant.getQuadrantPaddingHeight())
              + dataQuadrant.getQuadrantPaddingStartY();

          // if is not last point connect to previous point
          if (j > 0) {
            canvas.drawLine(ptFirst.x, ptFirst.y, startX, valueY,
                mPaint);
          }
          // reset
          ptFirst = new PointF(startX, valueY);
          startX = startX + lineLength;
        }
      } else {
              if (lineAlignType == ALIGN_TYPE_CENTER) {
                  lineLength= (dataQuadrant.getQuadrantPaddingWidth() / maxPointNum);
                  startX = dataQuadrant.getQuadrantPaddingEndX() - lineLength / 2;
              }else {
                  lineLength= (dataQuadrant.getQuadrantPaddingWidth() / (maxPointNum - 1));
                  startX = dataQuadrant.getQuadrantPaddingEndX();
              }
              
        for (int j = maxPointNum - 1; j >= 0; j--) {
          float value = lineData.get(j).getValue();
          // calculate Y
          float valueY = (float) ((1f - (value - minValue)
              / (maxValue - minValue)) * dataQuadrant.getQuadrantPaddingHeight())
              + dataQuadrant.getQuadrantPaddingStartY();

          // if is not last point connect to previous point
          if (j < maxPointNum - 1) {
            canvas.drawLine(ptFirst.x, ptFirst.y, startX, valueY,
                mPaint);
          }
          // reset
          ptFirst = new PointF(startX, valueY);
          startX = startX - lineLength;
        }
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @param value
   * 
   * @see cn.limc.androidcharts.view.GridChart#getAxisXGraduate(Object)
   */
  @Override
  public String getAxisXGraduate(Object value) {

    float graduate = Float.valueOf(super.getAxisXGraduate(value));
    int index = (int) Math.floor(graduate * maxPointNum);

    if (index >= maxPointNum) {
      index = maxPointNum - 1;
    } else if (index < 0) {
      index = 0;
    }

    if (null == this.linesData) {
      return "";
    }
    LineEntity<DateValueEntity> line = (LineEntity<DateValueEntity>) linesData
        .get(0);
    if (line == null) {
      return "";
    }
    if (line.isDisplay() == false) {
      return "";
    }
    List<DateValueEntity> lineData = line.getLineData();
    if (lineData == null) {
      return "";
    }
    return String.valueOf(lineData.get(index).getDate());
  }

  /*
   * (non-Javadoc)
   * 
   * @param value
   * 
   * @see cn.limc.androidcharts.view.GridChart#getAxisYGraduate(Object)
   */
  @Override
  public String getAxisYGraduate(Object value) {
    float graduate = Float.valueOf(super.getAxisYGraduate(value));
    return String.valueOf((int) Math.floor(graduate * (maxValue - minValue)
        + minValue));
  }
  
  public float longitudePostOffset(){
    if (lineAlignType == ALIGN_TYPE_CENTER) {
      float lineLength = dataQuadrant.getQuadrantPaddingWidth() / maxPointNum;
      return (this.dataQuadrant.getQuadrantPaddingWidth() - lineLength)/ (longitudeTitles.size() - 1);
      }else{
      return this.dataQuadrant.getQuadrantPaddingWidth()/ (longitudeTitles.size() - 1);
      }
  }
  
  public float longitudeOffset(){
    if (lineAlignType == ALIGN_TYPE_CENTER) {
      float lineLength = dataQuadrant.getQuadrantPaddingWidth() / maxPointNum;
      return dataQuadrant.getQuadrantPaddingStartX() + lineLength / 2;
    }else{
      return dataQuadrant.getQuadrantPaddingStartX();
    }
  }

  /**
   * <p>
   * initialize degrees on Y axis
   * </p>
   * <p>
   * Y???????????
   * </p>
   * <p>
   * ????Y???????
   * </p>
   */
  protected void initAxisY() {
    this.calcValueRange();
    List<String> titleY = new ArrayList<String>();
    float average = (int) ((maxValue - minValue) / this.getLatitudeNum());
    ;
    // calculate degrees on Y axis
    for (int i = 0; i < this.getLatitudeNum(); i++) {
      String value = String.valueOf((int) Math.floor(minValue + i
          * average));
      if (value.length() < super.getLatitudeMaxTitleLength()) {
        while (value.length() < super.getLatitudeMaxTitleLength()) {
          value = " " + value;
        }
      }
      titleY.add(value);
    }
    // calculate last degrees by use max value
    String value = String.valueOf((int) Math.floor(((int) maxValue)));
    if (value.length() < super.getLatitudeMaxTitleLength()) {
      while (value.length() < super.getLatitudeMaxTitleLength()) {
        value = " " + value;
      }
    }
    titleY.add(value);

    super.setLatitudeTitles(titleY);
  }

  /**
   * <p>
   * initialize degrees on Y axis
   * </p>
   * <p>
   * Y???????????
   * </p>
   * <p>
   * ????Y???????
   * </p>
   */
  protected void initAxisX() {
    List<String> titleX = new ArrayList<String>();
    if (null != linesData && linesData.size() > 0) {
      float average = maxPointNum / this.getLongitudeNum();
      for (int i = 0; i < this.getLongitudeNum(); i++) {
        int index = (int) Math.floor(i * average);
        if (index > maxPointNum - 1) {
          index = maxPointNum - 1;
        }
        titleX.add(String.valueOf(
            linesData.get(0).getLineData().get(index).getDate())
            .substring(4));
      }
      titleX.add(String.valueOf(
          linesData.get(0).getLineData().get(maxPointNum - 1)
              .getDate()).substring(4));
    }
    super.setLongitudeTitles(titleX);
  }

//  private float olddistance = 0f;
//  private float newdistance = 0f;

  /*
   * (non-Javadoc)
   * 
   * <p>Called when chart is touched<p> <p>????????????????????????????<p>
   * <p>???????<p>
   * 
   * @param event
   * 
   * @see android.view.View#onTouchEvent(MotionEvent)
   */
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    //valid
    if (!isValidTouchPoint(event.getX(),event.getY())) {
      return false;
    }
    if (null == linesData || linesData.size() == 0) {
      return false;
    }
    
    return zoomGestureDetector.onTouchEvent(event);
  }

  /**
   * <p>
   * calculate the distance between two touch points
   * </p>
   * <p>
   * ???????????????????????
   * </p>
   * <p>
   * ???????????????
   * </p>
   * 
   * @param event
   * @return float
   *         <p>
   *         distance
   *         </p>
   *         <p>
   *         ???
   *         </p>
   *         <p>
   *         ???
   *         </p>
   */
  protected float calcDistance(MotionEvent event) {
    if(event.getPointerCount() <= 1) {
      return 0f;
    }else{
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return FloatMath.sqrt(x * x + y * y);
    }
  }

  /**
   * <p>
   * Zoom in the graph
   * </p>
   * <p>
   * ?????????
   * </p>
   * <p>
   * ????
   * </p>
   */
  public void zoomIn() {
    if (null == linesData || linesData.size() <= 0) {
      return;
    }
    if (maxPointNum > 10) {
      maxPointNum = maxPointNum - ZOOM_STEP;
    }
    
    this.postInvalidate();
    
//    //Listener
//    if (onZoomGestureListener != null) {
//      onZoomGestureListener.onZoom(ZOOM_IN, 0, maxPointNum);
//    }
  }

  /**
   * <p>
   * Zoom out the grid
   * </p>
   * <p>
   * ??????????
   * </p>
   * <p>
   * ???
   * </p>
   */
  public void zoomOut() {
    if (null == linesData || linesData.size() <= 0) {
      return;
    }
    if (maxPointNum < linesData.get(0).getLineData().size() - 1 - ZOOM_STEP) {
      maxPointNum = maxPointNum + ZOOM_STEP;
    }
    
    this.postInvalidate();
    
//    //Listener
//    if (onZoomGestureListener != null) {
//      onZoomGestureListener.onZoom(ZOOM_OUT, 0, maxPointNum);
//    }
  }

  /**
   * @return the linesData
   */
  public List<LineEntity<DateValueEntity>> getLinesData() {
    return linesData;
  }

  /**
   * @param linesData
   *            the linesData to set
   */
  public void setLinesData(List<LineEntity<DateValueEntity>> linesData) {
    this.linesData = linesData;
  }

  /**
   * @return the maxPointNum
   */
  public int getMaxPointNum() {
    return maxPointNum;
  }

  /**
   * @param maxPointNum
   *            the maxPointNum to set
   */
  public void setMaxPointNum(int maxPointNum) {
    this.maxPointNum = maxPointNum;
  }

  /**
   * @return the minValue
   */
  public double getMinValue() {
    return minValue;
  }

  /**
   * @param minValue
   *            the minValue to set
   */
  public void setMinValue(double minValue) {
    this.minValue = minValue;
  }

  /**
   * @return the maxValue
   */
  public double getMaxValue() {
    return maxValue;
  }

  /**
   * @param maxValue
   *            the maxValue to set
   */
  public void setMaxValue(double maxValue) {
    this.maxValue = maxValue;
  }

  /**
   * @return the autoCalcValueRange
   */
  public boolean isAutoCalcValueRange() {
    return autoCalcValueRange;
  }

  /**
   * @param autoCalcValueRange
   *            the autoCalcValueRange to set
   */
  public void setAutoCalcValueRange(boolean autoCalcValueRange) {
    this.autoCalcValueRange = autoCalcValueRange;
  }

  /**
   * @return the lineAlignType
   */
  public int getLineAlignType() {
    return lineAlignType;
  }

  /**
   * @param lineAlignType the lineAlignType to set
   */
  public void setLineAlignType(int lineAlignType) {
    this.lineAlignType = lineAlignType;
  }

  /* (non-Javadoc)
   * 
   * @param listener 
   * @see cn.limc.androidcharts.event.IZoomable#setOnZoomGestureListener(cn.limc.androidcharts.event.OnZoomGestureListener) 
   */
  public void setOnZoomGestureListener(OnZoomGestureListener listener) {
    this.onZoomGestureListener = listener;
  }

  /* (non-Javadoc)
   * 
   * @return 
   * @see cn.limc.androidcharts.event.IZoomable#getOnZoomGestureListener() 
   */
  public OnZoomGestureListener getOnZoomGestureListener() {
    return onZoomGestureListener;
  }
}




Java Source Code List

cn.limc.androidcharts.AndroidChartsActivity.java
cn.limc.androidcharts.common.Axis.java
cn.limc.androidcharts.common.ChartRender.java
cn.limc.androidcharts.common.CrossLines.java
cn.limc.androidcharts.common.HorizontalAxis.java
cn.limc.androidcharts.common.IAxis.java
cn.limc.androidcharts.common.IChart.java
cn.limc.androidcharts.common.ICrossLines.java
cn.limc.androidcharts.common.IDataCursor.java
cn.limc.androidcharts.common.IFlexableGrid.java
cn.limc.androidcharts.common.IGrid.java
cn.limc.androidcharts.common.IQuadrant.java
cn.limc.androidcharts.common.IRender.java
cn.limc.androidcharts.common.Quadrant.java
cn.limc.androidcharts.common.SectionDataCursor.java
cn.limc.androidcharts.common.SimpleDataCursor.java
cn.limc.androidcharts.common.VerticalAxis.java
cn.limc.androidcharts.entity.ColoredStickEntity.java
cn.limc.androidcharts.entity.DateValueEntity.java
cn.limc.androidcharts.entity.IChartData.java
cn.limc.androidcharts.entity.IEntity.java
cn.limc.androidcharts.entity.IHasColor.java
cn.limc.androidcharts.entity.IHasDate.java
cn.limc.androidcharts.entity.IMeasurable.java
cn.limc.androidcharts.entity.IStickEntity.java
cn.limc.androidcharts.entity.LineEntity.java
cn.limc.androidcharts.entity.ListChartData.java
cn.limc.androidcharts.entity.MACDEntity.java
cn.limc.androidcharts.entity.OHLCEntity.java
cn.limc.androidcharts.entity.StickEntity.java
cn.limc.androidcharts.entity.TitleValueColorEntity.java
cn.limc.androidcharts.entity.TitleValueEntity.java
cn.limc.androidcharts.event.IDisplayCursorListener.java
cn.limc.androidcharts.event.IGestureDetector.java
cn.limc.androidcharts.event.ISlipable.java
cn.limc.androidcharts.event.ITouchable.java
cn.limc.androidcharts.event.IZoomable.java
cn.limc.androidcharts.event.OnSlipGestureListener.java
cn.limc.androidcharts.event.OnTouchGestureListener.java
cn.limc.androidcharts.event.OnZoomGestureListener.java
cn.limc.androidcharts.event.SlipGestureDetector.java
cn.limc.androidcharts.event.TouchGestureDetector.java
cn.limc.androidcharts.event.ZoomGestureDetector.java
cn.limc.androidcharts.mole.AbstractMole.java
cn.limc.androidcharts.mole.IMoleProvider.java
cn.limc.androidcharts.mole.IMole.java
cn.limc.androidcharts.mole.RectMole.java
cn.limc.androidcharts.mole.StickMole.java
cn.limc.androidcharts.view.AbstractBaseChart.java
cn.limc.androidcharts.view.BOLLMASlipCandleStickChart.java
cn.limc.androidcharts.view.CandleStickChart.java
cn.limc.androidcharts.view.ColoredSlipStickChart.java
cn.limc.androidcharts.view.DataGridChart.java
cn.limc.androidcharts.view.GridChart.java
cn.limc.androidcharts.view.LineChart.java
cn.limc.androidcharts.view.MACDChart.java
cn.limc.androidcharts.view.MACandleStickChart.java
cn.limc.androidcharts.view.MASlipCandleStickChart.java
cn.limc.androidcharts.view.MASlipStickChart.java
cn.limc.androidcharts.view.MAStickChart.java
cn.limc.androidcharts.view.MinusStickChart.java
cn.limc.androidcharts.view.PeriodDataGridChart.java
cn.limc.androidcharts.view.PieChart.java
cn.limc.androidcharts.view.RadarChart.java
cn.limc.androidcharts.view.RoseChart.java
cn.limc.androidcharts.view.RoundChart.java
cn.limc.androidcharts.view.SlipAreaChart.java
cn.limc.androidcharts.view.SlipBandAreaChart.java
cn.limc.androidcharts.view.SlipCandleStickChart.java
cn.limc.androidcharts.view.SlipLineChart.java
cn.limc.androidcharts.view.SlipMinusStickChart.java
cn.limc.androidcharts.view.SlipStickChart.java
cn.limc.androidcharts.view.SpiderWebChart.java
cn.limc.androidcharts.view.StickChart.java