最近要做一个绘图项目,需要在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

在AChartEngine上绘图,手指标记当前位置的更多相关文章

  1. 用C++Builder在Windows开始按钮上绘图制作方法

    熟悉Windows操作系统的软件设计人员知道,在Win95/98/NT/2000中有一任务栏(Task Bar)程序,路径为:C:\WINDOWS\SYSTEM\SYSTRAY.EXE(假设你的Win ...

  2. iOS:CALayer核心动画层上绘图

    在CALayer上绘图: •要在CALayer上绘图,有两种方法: 1.创建一个CALayer的子类,然后覆盖drawInContext:方法,可以使用Quartz2D API在其中进行绘图 2.设置 ...

  3. 获取UILabel上最后一个字符串的位置。获取文字长度和高度,自动换行

    //行的高度. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPat ...

  4. 无法处理文件 MainForm.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记。要想处理这些文件,请删除 Web 标记

    无法处理文件 MainForm.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记.要想处理这些文件,请删除 Web 标记 问题: 由于文件锁定,VS不能正常读取. 解 ...

  5. D3力布图绘制--在曲线路径上添加文本标记

    今天遇到一个在曲线路径上标识文本标记的问题,找到一个比较好的解决思路,在这里分享下: 使用d3建立的Force Layout,加上自定义的箭头形状,将多条连接线线改成弧线(https://www.cn ...

  6. 【解决方案】文件上具有 Web 标记,请删除 Web 标记

    错误: 无法处理文件 Form1.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记.要想处理这些文件,请删除 Web 标记.  解决方法: 文件-右键-属性 点击”解 ...

  7. plotly线上绘图和离线绘图的区别

    1.线上绘图 import plotly import plotly.plotly as py import plotly.graph_objs as go plotly.tools.set_cred ...

  8. GIS(一)——在js版搜索地图上加入Marker标记

    因为我们做的是有关于旅游方面的项目,所以涉及到了地图功能.我接到的当中一个任务就是,在地图上显示指定的几个景点,并在地图上加上标记. 我们项目用的是搜狗地图.使用的是js版本号.大家有兴趣的话,能够參 ...

  9. android 加载自定义图片并在图片上绘图

    来源:毕设 关键词:Bitmap Canvas //毕设中需要自定义室内地图,并且在地图上绘制轨迹 //此处是一个测试Demo,实现图片的加载和记录手指在屏幕上的运动轨迹 图片的载入 使用系统提供的内 ...

随机推荐

  1. 2011 Asia Fuzhou Regional Contest

    Xiangqi http://acm.hdu.edu.cn/showproblem.php?pid=4121 模拟,用高内聚低耦合的思想来写模拟题还是很好的,提高了函数的可重用性,程序的可读性,正确性 ...

  2. VS Bug 当获取其他项目的代码时, F5 无法进入调试模式. 也不报错....

    在64位的机子下, 被获用的项目使用X86时会出现. 就会出现   F5 无法进入调试模式. 也不报错.... 打断点也没有用. 在不加入X86项目的代码时, 又可以运行..   解决方案:   检查 ...

  3. poj 1704

    Georgia and Bob Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7233   Accepted: 2173 D ...

  4. 转载:PHP,MySQL的安装与配置

    本文转自:http://www.cnblogs.com/janas/archive/2012/08/27/2659240.html 一.安装配置PHP 1.下载Php的版本zip包之后,解压缩到指定目 ...

  5. ThinkPHP 单字母函数整理

    TP所有单独的函数,除了两个用来生成项目的buildAppDir之类的,其余都在框架目录/Common/functions.php这个文件里. A函数(基本是Action的简写) A函数是用来实例化我 ...

  6. 深入浅出ES6(十三):类 Class

    作者 Jason Orendorff  github主页  https://github.com/jorendorff 你可能觉得之前讲解的内容略显复杂,今天我们就讲解一些相对简单的内容,不再是生成器 ...

  7. POJ 2653 Pick-up sticks(线段相交)

    题目链接 题意 : 把每根棍往地上扔,找出最后在上面的棍,也就是说找出所有的没有别的棍子压在它的上面的棍子. 思路 : 对于每根棍子,压在他上面的棍子一定是在它之后扔的棍子,所以在找的时候只要找它之后 ...

  8. [RM HA 1] Cloudera CDH5 RM HA功能验证

    简介: 最新的Cloudera CDH5.0.0 beta版本已经支持RM的HA, 笔者为此简单验证了RM HA的功能. 后续将继续分析其HA的原理,以及其与社区RM HA的区别. 集群部属与RM f ...

  9. lintcode:线段树的查询

    线段树的查询 对于一个有n个数的整数数组,在对应的线段树中, 根节点所代表的区间为0-n-1, 每个节点有一个额外的属性max,值为该节点所代表的数组区间start到end内的最大值. 为Segmen ...

  10. iOS开发--iOS及Mac开源项目和学习资料

    文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...