在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
在AChartEngine上绘图,手指标记当前位置的更多相关文章
- 用C++Builder在Windows开始按钮上绘图制作方法
熟悉Windows操作系统的软件设计人员知道,在Win95/98/NT/2000中有一任务栏(Task Bar)程序,路径为:C:\WINDOWS\SYSTEM\SYSTRAY.EXE(假设你的Win ...
- iOS:CALayer核心动画层上绘图
在CALayer上绘图: •要在CALayer上绘图,有两种方法: 1.创建一个CALayer的子类,然后覆盖drawInContext:方法,可以使用Quartz2D API在其中进行绘图 2.设置 ...
- 获取UILabel上最后一个字符串的位置。获取文字长度和高度,自动换行
//行的高度. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPat ...
- 无法处理文件 MainForm.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记。要想处理这些文件,请删除 Web 标记
无法处理文件 MainForm.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记.要想处理这些文件,请删除 Web 标记 问题: 由于文件锁定,VS不能正常读取. 解 ...
- D3力布图绘制--在曲线路径上添加文本标记
今天遇到一个在曲线路径上标识文本标记的问题,找到一个比较好的解决思路,在这里分享下: 使用d3建立的Force Layout,加上自定义的箭头形状,将多条连接线线改成弧线(https://www.cn ...
- 【解决方案】文件上具有 Web 标记,请删除 Web 标记
错误: 无法处理文件 Form1.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记.要想处理这些文件,请删除 Web 标记. 解决方法: 文件-右键-属性 点击”解 ...
- plotly线上绘图和离线绘图的区别
1.线上绘图 import plotly import plotly.plotly as py import plotly.graph_objs as go plotly.tools.set_cred ...
- GIS(一)——在js版搜索地图上加入Marker标记
因为我们做的是有关于旅游方面的项目,所以涉及到了地图功能.我接到的当中一个任务就是,在地图上显示指定的几个景点,并在地图上加上标记. 我们项目用的是搜狗地图.使用的是js版本号.大家有兴趣的话,能够參 ...
- android 加载自定义图片并在图片上绘图
来源:毕设 关键词:Bitmap Canvas //毕设中需要自定义室内地图,并且在地图上绘制轨迹 //此处是一个测试Demo,实现图片的加载和记录手指在屏幕上的运动轨迹 图片的载入 使用系统提供的内 ...
随机推荐
- [工作记录] Android OpenSL ES: references & AAC related
AAC V.S. MP3 http://en.wikipedia.org/wiki/Advanced_Audio_Coding#AAC.27s_improvements_over_MP3 AAC pa ...
- html之cellspacing && cellpadding讲解
单元格间距(表格间距)(cellspacing) -- 代表表格边框与单元格补白的距离,也是单元格补白之间的距离 单元格边距(表格填充)(cellpadding) -- 代表单元格外面的一个距离,用于 ...
- 常用的CSSreset整理
说道CSSreset,大家又爱又恨,cssreset好处是,覆盖了浏览器的默认样式,使前端攻城狮能更加精确的添加样式,各个浏览器中的界面效果都相同.可是大量的.固定的CSSreset也给网页加载带来一 ...
- 使用CSS3实现超炫的Loading(加载)动画效果
SpinKit 是一套网页动画效果,包含8种基于 CSS3 实现的很炫的加载动画.借助 CSS3 Animation 的强大功能来创建平滑,易于定制的动画.SpinKit 的目标不是提供一个每个浏览器 ...
- Chapter 3
1.序列类型可以使用成员操作符in,大小计算函数(len()),分片([]),都可以迭代.Python内置的序列类型:str,list,tuple,bytearray,bytes.标准库中的序列类型: ...
- zend studio插件
1.安装使用Aptana插件(html,css,js代码提示功能) 安装步骤: 1).zend studio->Help->Install New Software->work wi ...
- I/O复用:异步聊天
一.I/O复用 在<TCP套接字编程>的同步聊天程序中,我们看到TCP客户同时处理两个输入:标准输入和TCP套接字.考虑在客户阻塞于标准输入fgets调用时,服务器进程被杀死,服务器TCP ...
- Javascript format方法
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- **apache环境下 禁止显示 index of/ 目录下(如何禁止访问网站根目录)
比如: http://123.57.49.XX6// 当这样访问的时候,可能会列出网站的根目录 如何禁止列出网站目录,方法如下: 让别人知道你的网站目录结构直接查看你目录下的所有文件是很危险的一个事情 ...
- poj 3537 Crosses and Crosses 博弈论
思路:每次画X之后都会形成2个子游戏,即i-3和n-i-2. 代码如下: #include<iostream> #include<cstdio> #include<cma ...