package com.androsz.achartengine;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.androsz.achartengine.chart.AbstractChart;
import com.androsz.achartengine.renderer.XYMultipleSeriesRenderer;
import com.androsz.achartengine.tools.FitZoom;
import com.androsz.achartengine.tools.Pan;
import com.androsz.achartengine.tools.Zoom;
/**
* The view that encapsulates the graphical chart.
*/
public abstract class ChartView extends View {
/** The chart to be drawn. */
protected AbstractChart mChart;
/** The chart renderer. */
private XYMultipleSeriesRenderer mRenderer;
/** The view bounds. */
private final Rect mRect = new Rect();
/** The user interface thread handler. */
private Handler mHandler;
/** The old x coordinate. */
private float oldX;
/** The old y coordinate. */
private float oldY;
/** The zoom buttons rectangle. */
private final RectF zoomR = new RectF();
/** The zoom in icon. */
// private Bitmap zoomInImage;
/** The zoom out icon. */
// private Bitmap zoomOutImage;
/** The fit zoom icon. */
// private Bitmap fitZoomImage;
/** The zoom area size. */
private static final int ZOOM_SIZE = 45;
/** The zoom buttons background color. */
private static final int ZOOM_BUTTONS_COLOR = Color
.argb(175, 150, 150, 150);
/** The pan tool. */
private Pan pan;
/** The zoom in tool. */
private Zoom zoomIn;
/** The zoom out tool. */
private Zoom zoomOut;
/** The fit zoom tool. */
private FitZoom fitZoom;
/** The paint to be used when drawing the chart. */
private final Paint mPaint = new Paint();
/**
* Creates a new graphical view.
*
* @param context
* the context
* @param chart
* the chart to be drawn
*/
public ChartView(Context context) {
super(context);
setup(context);
}
public ChartView(final Context context, final AttributeSet as) {
super(context, as);
setup(context);
}
protected abstract AbstractChart buildChart();
public void handleTouch(MotionEvent event) {
final int action = event.getAction();
if (mRenderer != null && action == MotionEvent.ACTION_MOVE) {
if (oldX >= 0 || oldY >= 0) {
final float newX = event.getX();
final float newY = event.getY();
if (mRenderer.isPanXEnabled() || mRenderer.isPanYEnabled()) {
pan.apply(oldX, oldY, newX, newY);
}
oldX = newX;
oldY = newY;
repaint();
}
} else if (action == MotionEvent.ACTION_DOWN) {
oldX = event.getX();
oldY = event.getY();
if (mRenderer != null
&& (mRenderer.isZoomXEnabled() || mRenderer
.isZoomYEnabled()) && zoomR.contains(oldX, oldY)) {
if (oldX < zoomR.left + zoomR.width() / 3) {
zoomIn.apply();
} else if (oldX < zoomR.left + zoomR.width() * 2 / 3) {
zoomOut.apply();
} else {
fitZoom.apply();
}
}
} else if (action == MotionEvent.ACTION_UP) {
oldX = 0;
oldY = 0;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.getClipBounds(mRect);
final int top = mRect.top;
final int left = mRect.left;
final int width = mRect.width();
final int height = mRect.height();
mChart.draw(canvas, left, top, width, height, mPaint);
if (mRenderer != null
&& (mRenderer.isZoomXEnabled() || mRenderer.isZoomYEnabled())) {
mPaint.setColor(ZOOM_BUTTONS_COLOR);
zoomR.set(left + width - ZOOM_SIZE * 3, top + height - ZOOM_SIZE
* 0.775f, left + width, top + height);
canvas.drawRoundRect(zoomR, ZOOM_SIZE / 3, ZOOM_SIZE / 3, mPaint);
/*
* final float buttonY = top + height - ZOOM_SIZE * 0.625f;
* canvas.drawBitmap(zoomInImage, left + width - ZOOM_SIZE * 2.75f,
* buttonY, null); canvas.drawBitmap(zoomOutImage, left + width -
* ZOOM_SIZE * 1.75f, buttonY, null);
* canvas.drawBitmap(fitZoomImage, left + width - ZOOM_SIZE * 0.75f,
* buttonY, null);
*/
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mRenderer != null
&& (mRenderer.isPanXEnabled() || mRenderer.isZoomYEnabled()
|| mRenderer.isZoomXEnabled() || mRenderer
.isZoomYEnabled())) {
handleTouch(event);
return true;
}
return super.onTouchEvent(event);
}
/**
* Schedule a view content repaint.
*/
public void repaint() {
mHandler.post(new Runnable() {
@Override
public void run() {
invalidate();
}
});
}
/**
* Schedule a view content repaint, in the specified rectangle area.
*
* @param left
* the left position of the area to be repainted
* @param top
* the top position of the area to be repainted
* @param right
* the right position of the area to be repainted
* @param bottom
* the bottom position of the area to be repainted
*/
public void repaint(final int left, final int top, final int right,
final int bottom) {
mHandler.post(new Runnable() {
@Override
public void run() {
invalidate(left, top, right, bottom);
}
});
}
private void setup(final Context context) {
mChart = buildChart();
mHandler = new Handler();
/*
* if (mChart instanceof XYChart) { final Resources res =
* context.getResources(); zoomInImage =
* BitmapFactory.decodeResource(res, R.drawable.zoom_in); zoomOutImage =
* BitmapFactory.decodeResource(res, R.drawable.zoom_out); fitZoomImage
* = BitmapFactory.decodeResource(res, R.drawable.zoom_1); mRenderer =
* ((XYChart) mChart).getRenderer(); if (mRenderer.getMarginsColor() ==
* DefaultRenderer.NO_COLOR) {
* mRenderer.setMarginsColor(mPaint.getColor()); } if
* (mRenderer.isPanXEnabled() || mRenderer.isPanYEnabled()) { pan = new
* Pan((XYChart) mChart); } if (mRenderer.isZoomXEnabled() ||
* mRenderer.isZoomYEnabled()) { zoomIn = new Zoom((XYChart) mChart,
* true, mRenderer.getZoomRate()); zoomOut = new Zoom((XYChart) mChart,
* false, mRenderer.getZoomRate()); fitZoom = new FitZoom((XYChart)
* mChart); } }
*/
}
}