在AChartEngine上繪圖,手指標記當前位置

最近要作一個繪圖項目,須要在ACE折線圖上再繪出一條紅標記當前座標,通過這幾天研究,能夠給你們分享一下了。先上效果圖吧!java

 

 

代碼裏的註釋仍是比較清楚,就不做說明了。android

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/7189769app

相關文章
相關標籤/搜索