AChartEngine应用之PieChart(动态饼图,允许产生动态数据并显示)
AChartEngine应用之PieChart(动态饼图)
接着上一次写的内容,构建动态饼图,并产生与用户交互,官方的API并没有提供可以借鉴的动态更新饼图的方法,考虑到数据都是活动的,不可能总是用静态数据,所以我下面的demo就是模拟动态数据用饼图显示,过程看起来笨拙一点,但是肯定可以使用的,具体是通过定时器+Handler实现定时任务,通过Handler更新主线程UI,在更新之前要把之前的数据清除掉,否则那些数据都会被加载,最后重新绘制饼图,
构建动态饼图的步骤主要分为以下四步,还需要在项目中引入AChartEngine依赖jar包,在Manifest中添加:<activityandroid:name="org.achartengine.GraphicalActivity" />
1.设置DefaultRenderer
DefaultRenderer mRenderer = new DefaultRenderer();// PieChart的主要描绘器 mRenderer = new DefaultRenderer();// 创建一个描绘器的实例,将被用来创建图表 mRenderer.setZoomButtonsVisible(true);// 显示放大缩小功能按钮 mRenderer.setStartAngle(180);// 设置为水平开始 mRenderer.setDisplayValues(true);// 显示数据 // mRenderer.setFitLegend(false);// 设置是否显示图例 // mRenderer.setLegendTextSize(10);// 设置图例字体大小 // mRenderer.setLegendHeight(10);// 设置图例高度 mRenderer.setShowLegend(false);// 默认是显示的需要关闭,因为动态更新数据的时候,图例更新慢 mRenderer.setChartTitle("饼图示例");// 设置饼图标题 mRenderer.setChartTitleTextSize(14);// 设置饼图标题大小 |
2.构建数据源CategorySeries
for (int i = 0; i < data.length; i++) VALUE += data[i]; for (int i = 0; i < data.length; i++) { mSeries.add("示例 " + (i + 1), data[i] / VALUE);// 设置种类名称和对应的数值,前面是(key,value)键值对 SimpleSeriesRenderer renderer = new SimpleSeriesRenderer(); if (i < COLORS.length) { renderer.setColor(COLORS[i]);// 设置描绘器的颜色 } else { renderer.setColor(getRandomColor());// 设置描绘器的颜色 } renderer.setChartValuesFormat(NumberFormat.getPercentInstance());// 设置百分比 mRenderer.setChartTitleTextSize(14);// 设置饼图标题大小 mRenderer.addSeriesRenderer(renderer);// 将最新的描绘器添加到DefaultRenderer中 } |
3.通过ChartFactory获取饼图
mChartView = ChartFactory.getPieChartView(getApplicationContext(), mSeries, mRenderer);// 构建mChartView mRenderer.setClickEnabled(true);// 允许点击事件 mChartView.setOnClickListener(new View.OnClickListener() {// 具体内容 } |
4.构建定时器任务
handler = new Handler() {// 这里的Handler实例将配合下面的Timer实例,完成定时更新图表的功能 @Override public void handleMessage(Message msg) { if (msg.what == 1) { updateChart();// 刷新图表具体方法 Handler将此并入主线程 } super.handleMessage(msg); } }; task = new TimerTask() { @Override public void run() {//通过消息更新 Log.i("task", " task ok "); Message message = new Message(); message.what = 1;//消息定义标志 handler.sendMessage(message); } }; timer.schedule(task, 500, 1000 * 10);//执行任务 |
效果图:
code:
package com.qiuzhping.achart; import java.text.NumberFormat; import java.util.Random; import java.util.Timer; import java.util.TimerTask; import org.achartengine.ChartFactory; import org.achartengine.GraphicalView; import org.achartengine.model.CategorySeries; import org.achartengine.renderer.DefaultRenderer; import org.achartengine.renderer.SimpleSeriesRenderer; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.LinearLayout; /** * @项目名称:AChart * @类名称:PieChartBuilder * @作者:Qiuzhping * @时间:2014-1-15下午11:20:48 * @作用 :构建饼图,并产生与用户交互,官方的API并没有提供可以借鉴的动态更新饼图的方法, * 考虑到数据都是活动的,不可能总是用静态数据,所以我下面的demo就是模拟动态数据用饼图显示,过程看起来笨拙一点,但是肯定可以使用的, * 具体是通过定时器+Handler实现定时任务,通过Handler更新主线程UI,在更新之前要把之前的数据清除掉,否则那些数据都会被加载,最后 * 重新绘制饼图 */ public class PieChartBuilder extends Activity { private Timer timer = new Timer();// 设计定时器 private TimerTask task;// 定时任务 private Handler handler;// 线程通讯 private String title = "动态饼图示例";// 饼图标题 private CategorySeries mSeries;// 饼图数据 private DefaultRenderer mRenderer;// 饼图描绘器 private GraphicalView mChartView;// 显示PieChart private Context context; private double data[] = new double[9]; private LinearLayout mLinear;// 布局方式 private int[] COLORS = new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.MAGENTA, Color.CYAN, Color.YELLOW, Color.DKGRAY };// 颜色 private double VALUE = 0;// 总数 private SimpleSeriesRenderer renderer;// 饼图每块描绘器 public void back(View v) { Log.i("qiuzhping", "back onClick"); Intent intent = new Intent(); intent.setClass(PieChartBuilder.this, MainActivity.class); startActivity(intent); PieChartBuilder.this.finish(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = getApplicationContext();// 获取上下文对象 setContentView(R.layout.xy_chart);// 设置样式 mLinear = (LinearLayout) findViewById(R.id.chart);// 获取mLinear布局,下面会把图表画在这个布局里面 mLinear.setBackgroundColor(Color.BLACK);// 设置背景色 mRenderer = new DefaultRenderer();// 创建一个描绘器的实例,将被用来创建图表 mRenderer.setZoomButtonsVisible(true);// 显示放大缩小功能按钮 mRenderer.setStartAngle(180);// 设置为水平开始 mRenderer.setDisplayValues(true);// 显示数据 // mRenderer.setFitLegend(false);// 设置是否显示图例 // mRenderer.setLegendTextSize(10);// 设置图例字体大小 // mRenderer.setLegendHeight(10);// 设置图例高度 mRenderer.setShowLegend(false);// 默认是显示的下载需要关闭,因为动态更新数据的时候,图例更新慢 mRenderer.setChartTitle(title);// 设置饼图标题 mRenderer.setChartTitleTextSize(14);// 设置饼图标题大小 mSeries = new CategorySeries(""); for (int i = 0; i < 9; i++) { Random random = new Random(); int R = random.nextInt(255); Log.i("qiuzhping", "Random R=" + R); data[i] = R; VALUE += data[i];// 总的数据大小 } for (int i = 0; i < data.length; i++) { mSeries.add("示例 " + (i + 1), data[i] / VALUE);// 设置种类名称和对应的数值,前面是(key,value)键值对 renderer = new SimpleSeriesRenderer(); if (i < COLORS.length) { renderer.setColor(COLORS[i]);// 设置描绘器的颜色 } else { renderer.setColor(getRandomColor());// 设置描绘器的颜色 } renderer.setChartValuesFormat(NumberFormat.getPercentInstance());// 设置百分比 mRenderer.addSeriesRenderer(renderer);// 将最新的描绘器添加到DefaultRenderer中 } mChartView = ChartFactory.getPieChartView(context, mSeries, mRenderer);// 构建mChartView mLinear.addView(mChartView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); handler = new Handler() {// 这里的Handler实例将配合下面的Timer实例,完成定时更新图表的功能 @Override public void handleMessage(Message msg) { if (msg.what == 1) { updateChart();// 刷新图表具体方法 Handler将此并入主线程 } super.handleMessage(msg); } }; task = new TimerTask() { @Override public void run() {// 通过消息更新 Log.i("task", " task ok "); Message message = new Message(); message.what = 1;// 消息定义标志 handler.sendMessage(message); } }; timer.schedule(task, 500, 1000 * 10);// 执行任务 } @Override public void onDestroy() {// 当结束程序时关掉Timer if (timer != null) { timer.cancel(); Log.i("qiuzhping", "onDestroy timer cancel "); } super.onDestroy(); } private void updateChart() { Log.i("qiuzhping", "updateChart ok"); mSeries.clear(); VALUE = 0;// 初始化 // mRenderer.removeAllRenderers(); for (int i = 0; i < 9; i++) {// 产生动态数据,实际项目中可以通过Web Service // 获取数据,不过这个内容应该放在线程上搞,太耗时了 Random random = new Random(); int R = random.nextInt(255); Log.i("qiuzhping", "Random R=" + R); data[i] = R; VALUE += data[i];// 总的数据大小 } for (int i = 0; i < data.length; i++) { mSeries.add("示例 " + (i + 1), data[i] / VALUE);// 设置种类名称和对应的数值,前面是(key,value)键值对 renderer = new SimpleSeriesRenderer(); if (i < COLORS.length) { renderer.setColor(COLORS[i]);// 设置描绘器的颜色 } else { renderer.setColor(getRandomColor());// 设置描绘器的颜色 } renderer.setChartValuesFormat(NumberFormat.getPercentInstance());// 设置百分比 mRenderer.addSeriesRenderer(renderer);// 将最新的描绘器添加到DefaultRenderer中 } mChartView.repaint(); } private int getRandomColor() {// 分别产生RBG数值 Random random = new Random(); int R = random.nextInt(255); int G = random.nextInt(255); int B = random.nextInt(255); return Color.rgb(R, G, B); } }
如果有哪位朋友想到更合适的方法,可以一起研究研究。。。。
完整项目:http://download.csdn.net/detail/qiu_11/18370487
未完待续。。。。
AChartEngine应用系列文章
(二)AChartEngine应用之PieChart(饼图)
(三)AChartEngine应用之BarChart(柱形图)
(四)AChartEngine应用之PieChart(动态饼图,允许产生动态数据并显示)
(五)AChartEngine应用之LineChart(模拟生命特征值图)