在AChartEngine上绘图,手指标记当前位置
最近要做一个绘图项目,需要在ACE折线图上再绘出一条红标记当前坐标,经过这几天研究,可以给大家分享一下了。先上效果图吧!
代码里的注释还是比较清楚,就不作说明了。
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 lzlong@zwmob.com * @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
有些东西会,但不精通,而我现在要做的就是精通,复习回顾,整理自己的框架,举一反三。。。