AChartEngine應用之LineChart(模拟動态生命特征值圖)
接着上一次寫的内容,建構動态曲線圖,并産生與使用者互動,考慮到資料都是活動的,不可能總是用靜态資料,是以我下面的demo就是模拟。項目作用:模拟生命特征值圖,動态顯示分鐘脈搏生命特征值走向每隔1000ms産生50組資料,并填充到表格中,主要使用的到是Handler+Task,因為我是用Activity顯示這個表格每次産生的資料都需要快速的填充到主線程UI中,是以我就用Handler,這裡的資料我都是采用随機數表示,這個demo可以作為開發醫療裝置顯示生命症狀的表格資訊參考,實際項目中如果需要用的每隔XX時間産生XX資料,最好是用Web提供資料,這樣可以實作多個用戶端 共享資料
建構LineChart圖的步驟主要分為以下四步,還需要在項目中引入AChartEngine依賴jar包,在Manifest中添加:<activityandroid:name="org.achartengine.GraphicalActivity" />
1. 設定XYMultipleSeriesRenderer
mXYRenderer = buildRenderer(color, style, true); mXYRenderer.setShowGrid(true);// 顯示表格 mXYRenderer.setGridColor(Color.GREEN);// 據說綠色代表健康色調,不過我比較喜歡灰色 mXYRenderer.setXLabels(20); mXYRenderer.setYLabels(10); mXYRenderer.setYLabelsAlign(Align.RIGHT);// 右對齊 // mXYRenderer.setPointSize((float) 2); mXYRenderer.setShowLegend(false);// 不顯示圖例 mXYRenderer.setZoomEnabled(false); mXYRenderer.setPanEnabled(true, false); mXYRenderer.setClickEnabled(false); setChartSettings(mXYRenderer, title, "時間", "數量", 0, X, 0, Y, Color.WHITE, Color.WHITE);// 這個是采用官方APIdemo提供給的方法 // 設定好圖表的樣式 |
2. 建構資料源CategorySeries
series = new XYSeries(title);// 這個類用來放置曲線上的所有點,是一個點的集合,根據這些點畫出曲線 mDataset = new XYMultipleSeriesDataset(); // 建立一個資料集的執行個體,這個資料集将被用來建立圖表 mDataset.removeSeries(series);// 移除資料集中舊的點集 series.clear();// 點集先清空,為了做成新的點集而準備 for (int k = 0; k < X; k++) {// 實際項目中這些資料最好是由線程搞定,可以從WebService中擷取 int y = (int) (Math.random() * Y); series.add(k, y); } mDataset.addSeries(series);// 在資料集中添加新的點集 mViewChart.invalidate();// 視圖更新,沒有這一步,曲線不會呈現動态 |
3. 通過ChartFactory.getLineChartView生成曲線圖
mViewChart = ChartFactory.getLineChartView(context, mDataset, mXYRenderer);// 通過ChartFactory生成圖表 mLayout.addView(mViewChart, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));// 将圖表添加到布局中去 |
4. 建構定時器任務
private final class StartBtn implements OnClickListener { @Override public void onClick(View arg0) { Log.i("qiuzhping", "startBtn onClick"); handler = new Handler() {// 簡單的通過Handler+Task形成一個定時任務,進而完成定時更新圖表的功能 @Override public void handleMessage(Message msg) { if (msg.what == 1) { Log.i("qiuzhping", "Handler handleMessage"); updateChart(); // 重新整理圖表,handler的作用是将此方法并入主線程,在非主線程是不能修改UI的 super.handleMessage(msg); } } }; task = new TimerTask() {// 定時器 @Override public void run() { Message message = new Message(); message.what = 1;// 設定标志 handler.sendMessage(message); Log.i("qiuzhping", "TimerTask run"); } }; timer.schedule(task, 1000, 1000);// 運作時間和間隔都是1000ms } } |
效果圖:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc5WNXF2do1WZxw2VjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TN2IDMxkTNyEzNxEDM0EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc5WNXF2do1WZxw2VjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TN2IDMxkTNyEzNxEDM0EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
Code:
package com.qiuzhping.achart.app;
import java.util.Timer;
import java.util.TimerTask;
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.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint.Align;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import com.qiuzhping.achart.R;
/**
* @項目名稱:模拟生命特征值圖
* @類名稱:AnalogPulse
* @作者:Qiuzhping
* @時間:2014-1-17上午11:46:51
* @作用 :模拟生命特征值圖,動态顯示分鐘脈搏走向
* 每隔1000ms産生50組資料,并填充到表格中,主要使用的到是Handler+Task,因為我是用Activity顯示這個表格
* 每次産生的資料都需要快速的填充到主線程UI中,是以我就用Handler,這裡的資料我都是采用随機數表示,這個demo可以作為開發
* 醫療裝置顯示生命症狀的表格資訊參考,實際項目中如果需要用的每隔XX時間産生XX資料,最好是用Web提供資料,這樣可以實作多個用戶端 共享資料
* @說明:環境是android4.0
*/
public class LifeEigenvalues extends Activity {
private Button startBtn = null;
private Button stopBtn = null;
private Timer timer = new Timer();// 定時器
private TimerTask task;// 任務
private Handler handler;// 主要用于更新表格視圖
private String title = "線性統計圖示例";
private XYSeries series;// XY資料點
private XYMultipleSeriesDataset mDataset;// XY軸資料集
private GraphicalView mViewChart;// 用于顯示現行統計圖
private XYMultipleSeriesRenderer mXYRenderer;// 線性統計圖主描繪器
private Context context;// 用于擷取上下文對象
private LinearLayout mLayout;
private int X = 50;// X資料集大小
private int Y = 50;//
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.analog_pulse);
startBtn = (Button) findViewById(R.id.startBtn);
startBtn.setOnClickListener(new StartBtn());
stopBtn = (Button) findViewById(R.id.stopBtn);
stopBtn.setOnClickListener(new StopBtn());
context = getApplicationContext();// 擷取上下文對象
mLayout = (LinearLayout) findViewById(R.id.chart);// 這裡獲得xy_chart的布局,下面會把圖表畫在這個布局裡面
series = new XYSeries(title);// 這個類用來放置曲線上的所有點,是一個點的集合,根據這些點畫出曲線
mDataset = new XYMultipleSeriesDataset(); // 建立一個資料集的執行個體,這個資料集将被用來建立圖表
mDataset.addSeries(series);// 将點集添加到這個資料集中
int color = Color.RED;// 設定顔色
PointStyle style = PointStyle.CIRCLE;// 設定外觀周期性顯示
mXYRenderer = buildRenderer(color, style, true);
mXYRenderer.setShowGrid(true);// 顯示表格
mXYRenderer.setGridColor(Color.GREEN);// 據說綠色代表健康色調,不過我比較喜歡灰色
mXYRenderer.setXLabels(20);
mXYRenderer.setYLabels(10);
mXYRenderer.setYLabelsAlign(Align.RIGHT);// 右對齊
// mXYRenderer.setPointSize((float) 2);
mXYRenderer.setShowLegend(false);// 不顯示圖例
mXYRenderer.setZoomEnabled(false);
mXYRenderer.setPanEnabled(true, false);
mXYRenderer.setClickEnabled(false);
setChartSettings(mXYRenderer, title, "時間", "數量", 0, X, 0, Y,
Color.WHITE, Color.WHITE);// 這個是采用官方APIdemo提供給的方法
// 設定好圖表的樣式
mViewChart = ChartFactory.getLineChartView(context, mDataset,
mXYRenderer);// 通過ChartFactory生成圖表
mLayout.addView(mViewChart, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));// 将圖表添加到布局中去
}
@Override
public void onDestroy() {
if (timer != null) {// 當結束程式時關掉Timer
timer.cancel();
Log.i("qiuzhping", "onDestroy timer cancel");
super.onDestroy();
}
}
protected XYMultipleSeriesRenderer buildRenderer(int color,
PointStyle style, boolean fill) {// 設定圖表中曲線本身的樣式,包括顔色、點的大小以及線的粗細等
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
XYSeriesRenderer r = new XYSeriesRenderer();
r.setColor(color);
r.setPointStyle(style);
r.setFillPoints(fill);
r.setLineWidth(3);
renderer.addSeriesRenderer(r);
return renderer;
}
protected void setChartSettings(XYMultipleSeriesRenderer renderer,
String title, String xTitle, String yTitle, double xMin,
double xMax, double yMin, double yMax, int axesColor,
int labelsColor) {// 設定主描繪器的各項屬性,詳情可閱讀官方API文檔
renderer.setChartTitle(title);
renderer.setXTitle(xTitle);
renderer.setYTitle(yTitle);
renderer.setXAxisMin(xMin);
renderer.setXAxisMax(xMax);
renderer.setYAxisMin(yMin);
renderer.setYAxisMax(yMax);
renderer.setAxesColor(axesColor);
renderer.setLabelsColor(labelsColor);
}
/**
* @方法名: updateChart
* @作者:Qiuzhping
* @作用: 主要工作是每隔1000ms重新整理整個統計圖 産生50組資料,完全填充表格
*/
private void updateChart() {// 主要工作是每隔1000ms重新整理整個統計圖
Log.i("qiuzhping", "updateChart ok");
mDataset.removeSeries(series);// 移除資料集中舊的點集
series.clear();// 點集先清空,為了做成新的點集而準備
for (int k = 0; k < X; k++) {// 實際項目中這些資料最好是由線程搞定,可以從WebService中擷取
int y = (int) (Math.random() * Y);
series.add(k, y);
}
mDataset.addSeries(series);// 在資料集中添加新的點集
mViewChart.invalidate();// 視圖更新,沒有這一步,曲線不會呈現動态
}
private final class StartBtn implements OnClickListener {
@Override
public void onClick(View arg0) {
Log.i("qiuzhping", "startBtn onClick");
handler = new Handler() {// 簡單的通過Handler+Task形成一個定時任務,進而完成定時更新圖表的功能
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
Log.i("qiuzhping", "Handler handleMessage");
updateChart(); // 重新整理圖表,handler的作用是将此方法并入主線程,在非主線程是不能修改UI的
super.handleMessage(msg);
}
}
};
task = new TimerTask() {// 定時器
@Override
public void run() {
Message message = new Message();
message.what = 1;// 設定标志
handler.sendMessage(message);
Log.i("qiuzhping", "TimerTask run");
}
};
timer.schedule(task, 1000, 1000);// 運作時間和間隔都是1000ms
}
}
private final class StopBtn implements OnClickListener {
@Override
public void onClick(View arg0) {
Log.i("qiuzhping", "stopBtn onClick");
LifeEigenvalues.this.finish();
}
}
}
對應項目:http://download.csdn.net/detail/qiu_11/6858385
未完待續。。。。
AChartEngine應用系列文章
(一)AChartEngine簡介
(二)AChartEngine應用之PieChart(餅圖)
(三)AChartEngine應用之BarChart(柱形圖)
(四)AChartEngine應用之PieChart(動态餅圖,允許産生動态資料并顯示)
(五)AChartEngine應用之LineChart(模拟生命特征值圖)
(六)AChartEngine應用之LineChart(模拟三角函數sin,cos)
(七)AChartEngine進階應用CombinedXYChart(組合統計圖)