报表框架achart的使用

AChartEngine是为android应用而设计的绘图工具库,使用它可以很方便地完成各种图形的绘制,官网地址是AChartEngine,由于是比较早的项目,所以项目主业放在了GoogleCode上,不过在GitHub上也有镜像。目前官方最新版本是1.1.0,现在已经支持的图标样式如下:

  • line chart
  • area chart
  • scatter chart
  • time chart
  • bar chart
  • pie chart
  • bubble chart
  • doughnut chart
  • range (high-low) bar chart
  • dial chart / gauge
  • combined (any combination of line, cubic line, scatter, bar, range bar, bubble) chart
  • cubic line chart

部分效果图如下:




当然如果想完全搞明白框架的实现逻辑,会非常的困难,也没什么必要,实际上只需要会用即可,官方的API文档也非常的详细。接下来,就记录一下自己实际项目里实现的一个绘制饼状图(Pie Chart)的小demo.

首先,当然需要先导入achartengine-1.1.0.jar这个jar包,然后可以将官方提供的demo中的布局文件xy_chat.xml拿出来直接使用,我们看到AChartEngine在实现了如此之多的图形绘制的前提下,只有一个布局文件,可见这个框架是多么地精致严谨,其对代码的抽取简直已经达到了极致。当然,对应的string值也需要修改一下,不再赘述。下面是我修改过的布局文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="add_values" />

<TableLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">

<TableRow>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="x" android:padding="5dip"/>
<EditText android:id="@+id/xValue" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_weight="1" android:enabled="false"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="y" android:padding="5dip"/>
<EditText android:id="@+id/yValue" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_weight="1" android:enabled="false"/>
<Button android:id="@+id/add" android:text="add"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:enabled="false"/>
</TableRow>
</TableLayout>

<LinearLayout android:id="@+id/chart" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" />

<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="wrap_content" >
<Button android:id="@+id/new_series" android:text="new_series"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>

</LinearLayout>

然后,如果要实现一个饼状图,在官方demo里也有对应的代码实例,下图展示了现有的代码实例,其中PieChartBuilder.java就是饼状图的代码实例,可以直接拿来用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
* Copyright (C) 2009, 2010 SC 4ViewSoft SRL
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package cn.easydone.achartdemo;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.model.CategorySeries;
import org.achartengine.model.SeriesSelection;
import org.achartengine.renderer.DefaultRenderer;
import org.achartengine.renderer.SimpleSeriesRenderer;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;

public class PieChartBuilder extends Activity {
public static final String TYPE = "type";

//颜色,官方的提供了四种颜色,也就是说最多添加四个类别,如果实际项目里要添加更多类别,在这里添加即可
private static int[] COLORS = new int[] { Color.GREEN, Color.BLUE, Color.MAGENTA, Color.CYAN };

//要绘制的是什么图形 线性图 饼状图 树状图
private CategorySeries mSeries = new CategorySeries("");

private DefaultRenderer mRenderer = new DefaultRenderer();

private String mDateFormat;

private Button mAdd;

private EditText mX;

//显示的控件
private GraphicalView mChartView;

@Override
protected void onRestoreInstanceState(Bundle savedState) {
super.onRestoreInstanceState(savedState);
mSeries = (CategorySeries) savedState.getSerializable("current_series");
mRenderer = (DefaultRenderer) savedState.getSerializable("current_renderer");
mDateFormat = savedState.getString("date_format");
}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("current_series", mSeries);
outState.putSerializable("current_renderer", mRenderer);
outState.putString("date_format", mDateFormat);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.xy_chart);
mX = (EditText) findViewById(R.id.xValue);
//设置显示效果
mRenderer.setApplyBackgroundColor(true);
mRenderer.setBackgroundColor(Color.argb(100, 50, 50, 50));
mRenderer.setChartTitleTextSize(20);
mRenderer.setLabelsTextSize(15);
mRenderer.setLegendTextSize(15);
mRenderer.setMargins(new int[] { 20, 30, 15, 0 });
mRenderer.setZoomButtonsVisible(true);
mRenderer.setStartAngle(90);

mAdd = (Button) findViewById(R.id.add);
mAdd.setEnabled(true);
mX.setEnabled(true);

mAdd.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
double x = 0;
try {
x = Double.parseDouble(mX.getText().toString());
} catch (NumberFormatException e) {
mX.requestFocus();
return;
}
mSeries.add("Series " + (mSeries.getItemCount() + 1), x);
SimpleSeriesRenderer renderer = new SimpleSeriesRenderer();
renderer.setColor(COLORS[(mSeries.getItemCount() - 1) % COLORS.length]);
mRenderer.addSeriesRenderer(renderer);
mX.setText("");
mX.requestFocus();
if (mChartView != null) {
mChartView.repaint();
}
}
});
}

@Override
protected void onResume() {
super.onResume();
if (mChartView == null) {
LinearLayout layout = (LinearLayout) findViewById(R.id.chart);
mChartView = ChartFactory.getPieChartView(this, mSeries, mRenderer);
mRenderer.setClickEnabled(true);
mRenderer.setSelectableBuffer(10);
mChartView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SeriesSelection seriesSelection = mChartView.getCurrentSeriesAndPoint();
if (seriesSelection == null) {
Toast
.makeText(PieChartBuilder.this, "No chart element was clicked", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(
PieChartBuilder.this,
"Chart element data point index " + seriesSelection.getPointIndex()
+ " was clicked" + " point value=" + seriesSelection.getValue(),
Toast.LENGTH_SHORT).show();
}
}
});
mChartView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
SeriesSelection seriesSelection = mChartView.getCurrentSeriesAndPoint();
if (seriesSelection == null) {
Toast.makeText(PieChartBuilder.this, "No chart element was long pressed",
Toast.LENGTH_SHORT);
return false; // no chart element was long pressed, so let something
// else handle the event
} else {
Toast.makeText(PieChartBuilder.this, "Chart element data point index "
+ seriesSelection.getPointIndex() + " was long pressed", Toast.LENGTH_SHORT);
return true; // the element was long pressed - the event has been
// handled
}
}
});
layout.addView(mChartView, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
} else {
mChartView.repaint();
}
}
}

最终效果如下:

如果需要绘制其他的图形,在官方demo中的其他代码中修改就是。