最近要做一个绘图项目,需要在ACE折线图上再绘出一条红标记当前坐标,经过这几天研究,可以给大家分享一下了。先上效果图吧!

在AChartEngine上绘图,手指标记当前位置-LMLPHP

代码里的注释还是比较清楚,就不作说明了。

package com.example.drawlineonace;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random; import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer; import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
/**
*
* @time 2014-4-11 下午4:19:54
* @author 在ACE上绘图。
*/ public class TestTheActivity extends Activity {
private LinearLayout containerbody;
private GraphicalView mLineChartView; //竖线
private PopupWindow mPopupWindow; //竖线
private View mPopupView;
private int POPWIN_WIDTH;
private int POPWIN_HEIGHT;
private int screenEventLineY = 100; //红点
private PopupWindow mPopupWindowSign; //红点
private View mPopupViewSign;
private int POPWIN_SIGN_WIDTH;
private int POPWIN_SIGN_HEIGHT;
private int screenEventTagX = 0; //当前红点的X轴坐标
private int screenEventTagY = 0; //当前红点的Y轴坐标 private XYSeries series;
private int chart_margins_left; //绘图的边距
private int chart_margins_top;
private int chart_margins_right;
private int chart_margins_bottom;
private final int CHART_X_LABELS = 9;
private final int CHART_Y_LABELS = 6;
private final int CHART_X_AXISMAX = CHART_X_LABELS+1;
private final int CHART_Y_AXISMAX = CHART_Y_LABELS * 10;
private int lineEndX = 10;
private int mEventX; private List<Map<String, String>> mDataMapList = new ArrayList<Map<String, String>>(); ///点的集合
private Map<String, String> mDataMap = new HashMap<String, String>(); @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); init(); fillDataList(); initChartView(); } @SuppressLint("ResourceAsColor")
private void init() {
mPopupView = View.inflate(TestTheActivity.this, R.layout.pop_msg, null);
mPopupViewSign = View.inflate(TestTheActivity.this, R.layout.sign_layout, null);
} //dp转像素
public int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
} //像素转dip
public static int PixelsToDip(Context context,int Pixels) {
final float SCALE = context.getResources().getDisplayMetrics().density;
float dips =Pixels / SCALE ;
return (int)dips;
} /**
* @todo 填充数据
*/
private void fillDataList() {
Random r = new Random();
for (int i = 0; i < 10; i++) {
Map<String, String> tempMap = new HashMap<String, String>();
tempMap.put("BUSSUCCESS", "0");
tempMap.put("BUSTOTAL", "" + r.nextInt(60));
tempMap.put("BUSUNSUCCESS", "0");
tempMap.put("BUSFAILED", "0");
tempMap.put("type", "1");
mDataMapList.add(tempMap);
}
} /**
*
* @time 2014-4-3 下午3:28:40
* @todo 初始化图表
*/
private void initChartView() {
// 1, 构造显示用渲染图
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
// renderer.setPointSize(5);
// 2,进行显示
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
// 2.1, 构建数据
series = new XYSeries("业绩曲线");
for (int x = 0; x < lineEndX; x++) {
// 填x,y值
mDataMap = mDataMapList.get(x);
series.add(x, Integer.parseInt(mDataMap.get("BUSTOTAL")));
}
// 需要绘制的点放进dataset中
dataset.addSeries(series);
// 3, 对点的绘制进行设置
XYSeriesRenderer xyRenderer = new XYSeriesRenderer();
// 3.1设置K 线颜色
xyRenderer.setColor(Color.RED);
// 3.2设置点的样式
xyRenderer.setPointStyle(PointStyle.CIRCLE);
xyRenderer.setFillPoints(true);
// 设置线的宽度
xyRenderer.setLineWidth(3);
// 3.3, 将要绘制的点添加到坐标绘制中
renderer.addSeriesRenderer(xyRenderer);
// 4, 设置图表属性
// 显示网格
renderer.setShowGrid(true);
// 设置4周边距
chart_margins_top = (int) getResources().getDimension(R.dimen.chart_margin_top);
chart_margins_left = (int) getResources().getDimension(R.dimen.chart_margin_left);
chart_margins_bottom = (int) getResources().getDimension(R.dimen.chart_margin_bottom);
chart_margins_right = (int) getResources().getDimension(R.dimen.chart_margin_right); renderer.setMargins(new int[] { chart_margins_left,chart_margins_top, chart_margins_right,chart_margins_bottom});
// 边框外侧颜色
// renderer.setMarginsColor(Color.argb(0, 0xff, 0, 0)); // 穿透背景色
renderer.setMarginsColor(Color.WHITE);
// 设置背景颜色
renderer.setBackgroundColor(Color.TRANSPARENT);
// 设置背景颜色生效
renderer.setApplyBackgroundColor(true);
// 是否支持图表移动
renderer.setPanEnabled(true, false);
// 坐标滑动上、下限
renderer.setPanLimits(new double[] { 0, 0, 0, 0 });
// 是否支持图表缩放
renderer.setZoomEnabled(false, false);
// X轴等分,最小、最大坐标值
renderer.setXLabels(CHART_X_LABELS);
renderer.setXAxisMin(0);
renderer.setXAxisMax(CHART_X_AXISMAX);
// Y轴等分,最小、最大坐标值
renderer.setYLabels(CHART_Y_LABELS);
renderer.setYAxisMin(0);
renderer.setYAxisMax(CHART_Y_AXISMAX); // 坐标轴颜色
renderer.setAxesColor(Color.rgb(242, 103, 16));
// 坐标轴单位文字颜色、字号
renderer.setLabelsColor(Color.rgb(25, 110, 172));
renderer.setLabelsTextSize(16); // 坐标轴文字对齐
renderer.setYLabelsAlign(Paint.Align.RIGHT);
// 设置原点大小
renderer.setPointSize(5);
// 设置图表标题文字
// renderer.setChartTitle(getString(R.string.chart_title));
// 是否显示图例
renderer.setShowLegend(false); // 生成图表视图
mLineChartView = ChartFactory.getLineChartView(TestTheActivity.this,dataset, renderer);
mLineChartView.setOnTouchListener(chartViewOnTouchListener);
mLineChartView.setId(0); // 添加至父容器
containerbody = (LinearLayout) findViewById(R.id.container_chart);
containerbody.addView(mLineChartView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
} private OnTouchListener chartViewOnTouchListener = new OnTouchListener() {
@SuppressWarnings("deprecation")
public boolean onTouch(View v, MotionEvent event) { POPWIN_WIDTH = 2; //细线的宽度
POPWIN_HEIGHT = mLineChartView.getHeight()-chart_margins_bottom-chart_margins_top-33;
screenEventLineY = chart_margins_top+getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop(); POPWIN_SIGN_WIDTH = 20; //红点的大小
POPWIN_SIGN_HEIGHT = 20; switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPopupWindow = new PopupWindow(mPopupView,POPWIN_WIDTH, POPWIN_HEIGHT);
mPopupWindowSign = new PopupWindow(mPopupViewSign,POPWIN_SIGN_WIDTH, POPWIN_SIGN_HEIGHT);
break;
case MotionEvent.ACTION_MOVE:
mEventX = (int) event.getX(); //获取当前按下的坐标
// 求图表像素坐标 换算成屏幕像素坐标
screenEventTagX = getCurrentXLocation(mEventX); //获取当前红点x轴的坐标,然后红点对应到曲红上的X坐标,有四舍五入的操作 if (mPopupWindow.isShowing()) {
mPopupWindow.update(screenEventTagX,screenEventLineY, POPWIN_WIDTH,POPWIN_HEIGHT);
} else {
mPopupWindow.showAtLocation(mLineChartView,Gravity.NO_GRAVITY, screenEventTagX,screenEventLineY);
} screenEventTagY = getCurrentLocationY(mEventX); //获取当前红点Y轴的坐标,然后把红点对应到曲线上Y坐标, if (mPopupWindowSign.isShowing()) {
//这里注意要减去红点的大小/2
mPopupWindowSign.update(screenEventTagX - mPopupWindowSign.getWidth()/2,screenEventTagY- mPopupWindowSign.getWidth()/2, POPWIN_SIGN_WIDTH,POPWIN_SIGN_HEIGHT);
} else {
mPopupWindowSign.showAtLocation(mLineChartView,Gravity.NO_GRAVITY, screenEventTagX- mPopupWindowSign.getWidth()/2,screenEventTagY - mPopupWindowSign.getWidth()/2);
}
break;
case MotionEvent.ACTION_UP:
dismissPopupWindow();
break;
}
return false;
}
}; /**
* 获取当前X轴上红点的坐标
* @time 2014-4-10 下午3:35:08
* @todo TODO
* @param touchX
* @return
*/
private int getCurrentXLocation(int touchX){
//利用手指获取当前横坐标(注意要送去左边边距) 算出当前对应在X上的坐标
int currentX = Math.round((touchX-chart_margins_left) * CHART_X_AXISMAX/mLineChartView.getWidth()); //四舍五入
// 先减去两边边距,可以得到绘图区区域大小 ,再利用比例算出对应的坐标,
return currentX * (mLineChartView.getWidth()-chart_margins_left-chart_margins_right)/CHART_X_AXISMAX + chart_margins_left; //
} /**
*
* 根据x轴对应的坐标获取,y轴坐标,,然后按比例获取高度
* @todo 获取当前在chart上对应的y轴坐标
*/
private int getCurrentLocationY(int touchX){ int currentX = Math.round((touchX-chart_margins_left) * CHART_X_AXISMAX/mLineChartView.getWidth()); //四舍五入 int y = Integer.valueOf(mDataMapList.get(currentX).get("BUSTOTAL"));
int currentY = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop()+mLineChartView.getHeight() - y * (mLineChartView.getHeight()-chart_margins_top-chart_margins_bottom-3) / CHART_Y_AXISMAX-chart_margins_bottom*2; return currentY; } /**
*
* @author [email protected]
* @time 2014-4-3 上午9:03:30
* @todo 隐藏pop
*/
private void dismissPopupWindow() {
if (mPopupWindow != null) {
if (mPopupWindow.isShowing()) {
mPopupWindow.dismiss();
}
mPopupWindow = null;
} if (mPopupWindowSign != null) {
if (mPopupWindowSign.isShowing()) {
mPopupWindowSign.dismiss();
}
mPopupWindowSign = null;
}
}
}

源码 下载地址:http://download.csdn.net/detail/u014702332/7189769

05-11 10:59