沪江小D在线词典 点击查词
有问题Q我

在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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2014-04-14 10:29  Python绿色通道  阅读(1791)  评论(0编辑  收藏  举报