习惯先上图
使用Android图表引擎AChartEngine来实现
具体实现
1 设置XYMultipleSeriesDataset
<span style="font-size:18px;">private XYMultipleSeriesDataset getdemodataset() {
dataset = new XYMultipleSeriesDataset();// xy轴数据源
series = new XYSeries("流量监控");
dataset.addSeries(series);
return dataset;
}</span>
2 设置XYMultipleSeriesRenderer此处设置图表的具体显示情况,比如折线颜色,形状,图例字体大小,是否填充等等...
<span style="font-size:18px;">private XYMultipleSeriesRenderer getdemorenderer() {
// 定义每条线的点的样式
render = new XYMultipleSeriesRenderer();
XYSeriesRenderer r = new XYSeriesRenderer();
r.setColor(Color.parseColor("#04f604"));// 折线的颜色
r.setPointStyle(PointStyle.CIRCLE);// 折线点的样式
r.setDisplayChartValues(true);// 设置显示折线的点对应的值
r.setFillPoints(true);
r.setChartValuesSpacing(3);
r.setFillBelowLine(true);// 设置折线下方是否填充
r.setFillBelowLineColor(Color.parseColor("#04f604"));// 设置填充色
r.setLineWidth(3f);// 设置折线的宽度
render.addSeriesRenderer(r);
render.setChartTitle("APP性能监控");// 图表的标题
render.setChartTitleTextSize(20);// 设置整个图表标题文字的大小
render.setAxisTitleTextSize(20);// 设置轴标题文字的大小
render.setAxesColor(Color.WHITE);
render.setXTitle("当前时间");
render.setYTitle("流量大小");
render.setLabelsTextSize(20);// 设置轴刻度文字的大小
render.setLabelsColor(Color.WHITE);
render.setXLabelsColor(Color.WHITE);
render.setYLabelsColor(0, Color.WHITE);
render.setLegendTextSize(20);// 设置图例文字大小
// render.setShowLegend(false);//显示不显示在这里设置,非常完美
render.setYLabelsAlign(Align.RIGHT);// 刻度值相对于刻度的位置
render.setShowGrid(true);// 显示网格
render.setShowCustomTextGrid(true);// 设置是否显示X轴网格
render.setGridColor(Color.WHITE);
render.setYAxisMax(10);// 设置y轴的范围
render.setYAxisMin(0);
render.setYLabels(10);// 分几等份
render.setInScroll(true);
render.setLabelsTextSize(16);
render.setLabelsColor(Color.WHITE);
render.setPanEnabled(false, false);// 禁止报表的拖动
render.setPointSize(5f);// 设置点的大小(图上显示的点的大小和图例中点的大小都会被设置)
render.setMargins(new int[] { 20, 30, 90, 10 }); // 设置图形四周的留白
render.setXLabels(0);// 取消X坐标的数字,只有自己定义横坐标是才设为此值
return render;
}</span>
3 结合计时器和随机数模拟实时更新
<span style="font-size:18px;">/**
* 更新折线图
*/
private void updatechart() {
// 判断当前点集中到底有多少点,因为屏幕总共只能容纳xLenght个,所以当点数超过xLenght时,长度永远是xLenght
int length = series.getItemCount();
int a = length;
if (length > xLenght) {
length = xLenght;
}
// 获取当前时间
addX = nowTime.format(new java.util.Date());
// 用随机数模拟数据
addY = (int) (Math.random() * 10);
// 得出数据之和
allSum = addY + allSum;
// 移除数据集中旧的点集
dataset.removeSeries(series);
// 当数据集中不够五个点的时候直接添加就好,因为初始化的时候只有一个点,所以前几次更新的时候直接添加
if (a < xLenght) {
series.add(a + 1, addY);// 第一个参数代表第几个点,要与下面语句中的第一个参数对应
render.addXTextLabel(a + 1, addX);
xkedu[a] = addX;
}
// 超过了xLenght个点要去除xcache【0】换成【1】的.....
else {
// 将旧的点集中x和y的数值取出来放入backup中,造成曲线向左平移的效果
for (int i = 0; i < length - 1; i++) {
ycache[i] = (float) series.getY(i + 1);
xkedu[i] = xkedu[i + 1];
}
// 点集先清空,为了做成新的点集而准备
series.clear();
// 将新产生的点首先加入到点集中,然后在循环体中将坐标变换后的一系列点都重新加入到点集中
for (int k = 0; k < length - 1; k++) {
series.add(k + 1, ycache[k]);
render.addXTextLabel(k + 1, xkedu[k]);
}
xkedu[xLenght - 1] = addX;
series.add(xLenght, addY);
render.addXTextLabel(xLenght, addX);
}
// 在数据集中添加新的点集
dataset.addSeries(series);
// 视图更新,没有这一步,曲线不会呈现动态
chart.invalidate();
}</span>
4 生成线性表
<span style="font-size:18px;">// 生成线性表,0.3f表示曲线弧度,三次贝塞尔曲线,所以有些并不过焦点
chart = ChartFactory.getCubeLineChartView(this, getdemodataset(),
getdemorenderer(), 0.3f);
// 先remove再add可以实现统计图更新
linearLayout.removeAllViews();
linearLayout.addView(chart, new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));</span>
5 计时器定时刷新图表
<span style="font-size:18px;">/**
* 通过发送消息结合计时器实现更新
*/
private void sendMessage() {
handle = new Handler() {
public void handleMessage(Message msg) {
updatechart();
nowValue.setText(String.valueOf(addY));
sumNumber.setText("" + allSum);
}
};
task = new TimerTask() {
public void run() {
Message msg = new Message();
msg.what = 200;
handle.sendMessage(msg);
}
};
timer.schedule(task, 0, 1000);
}</span>
本次代码有点杂乱无章,后续会上规范代码.