最近在帮老师做一个课题,其中app端需要显示折线图以便直观地看数据波动,上网查了些资料后发现了这款图标引擎,另外感谢李坤老师的博客,帮助很大。
废话不多说,下面写代码。
一.AChartEngine是一款非常强大的绘图引擎,不过我这里只需用到折线图,所以并没有其他图的使用。首先我们要导入achartengine-xxx.jar,我这里使用的是achartengine-0.7.0.jar.
二.工欲善其事,必先利其器。由于在项目中需要使用图表的地方不止一处,我根据自己实际所需情况先封了个工具类。
package xidian.zhr.utils; import java.util.ArrayList;
import java.util.List; import org.achartengine.ChartFactory;
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.content.Context;
import android.graphics.Color;
import android.graphics.Paint.Align;
import android.view.View;
import android.widget.LinearLayout; public class AChartEngineUtil
{ /**
* 获取坐标序列
* @param size 序列点数
* @param values y轴值
* @return 坐标x轴序列 或 坐标y轴序列
*/
public static List<double[]> getlist(int size,List<String> values)
{
List<double[]> xy = new ArrayList<double[]>(); double[] list = new double[size];
for(int i = 0 ; i < size ;i++)
{
list[i] = (values.isEmpty())? i : Double.valueOf(values.get(i));
} xy.add(list); return xy;
} /**
* 构建XYMultipleSeriesRenderer.
*
* @param colors 每个序列的颜色
* @param styles 每个序列点的类型(可设置三角,圆点,菱形,方块等多种)
* ( PointStyle.CIRCLE, PointStyle.DIAMOND,PointStyle.TRIANGLE, PointStyle.SQUARE )
* @return XYMultipleSeriesRenderer
*/
public static XYMultipleSeriesRenderer buildRenderer(int[] colors,PointStyle[] styles)
{
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
// 控制横纵轴的属性字大小
renderer.setAxisTitleTextSize(15);
// 控制横纵轴的值大小
renderer.setChartTitleTextSize(20);
renderer.setLabelsTextSize(15);
renderer.setLegendTextSize(15);
renderer.setPointSize(5f);
renderer.setMargins(new int[]
{ 20, 30, 15, 0 });
int length = colors.length;
for (int i = 0; i < length; i++)
{
XYSeriesRenderer r = new XYSeriesRenderer();
r.setColor(colors[i]);
r.setPointStyle(styles[i]);
renderer.addSeriesRenderer(r);
}
return renderer;
} /**
* 设置renderer的一些坐标轴属性.
*
* @param renderer 要设置的renderer
* @param title 图表标题
* @param xTitle X轴标题
* @param yTitle Y轴标题
* @param xMin X轴最小值
* @param xMax X轴最大值
* @param yMin Y轴最小值
* @param yMax Y轴最大值
* @param axesColor X轴颜色
* @param labelsColor Y轴颜色
*/
public static void setChartSettings(XYMultipleSeriesRenderer renderer,
String title, String xTitle, String yTitle, double xMin,
double xMax, double yMin, double yMax, int axesColor,
int labelsColor)
{
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);
} /**
* 构建和时间有关的XYMultipleSeriesDataset,这个方法与buildDataset在参数上区别是需要List<Date[]>作参数.
*
* @param titles 序列图例
* @param xValues X轴值
* @param yValues Y轴值
* @return XYMultipleSeriesDataset
*/
public static XYMultipleSeriesDataset buildDataset(String[] titles,
List<double[]> xValues, List<double[]> yValues)
{
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
int length = titles.length;
for (int i = 0; i < length; i++)
{
XYSeries series = new XYSeries(titles[i]);
double[] xV = xValues.get(i);
double[] yV = yValues.get(i);
int seriesLength = xV.length;
for (int k = 0; k < seriesLength; k++)
{
series.add(xV[k], yV[k]);
}
dataset.addSeries(series);
}
return dataset;
} /**
* 绘制图表
* @param context 当前环境
* @param layout 承载图标的容器
* @param titles 折线名称
* @param colors 折线颜色
* @param data y轴坐标数据
* @param xname x轴名字
* @param yname y轴名字
*/
public static void setchart(Context context,LinearLayout layout,String[] titles,int[] colors,
List<String> data,String xname,String yname)
{ //获取x轴坐标
List<double[]> x = getlist(data.size(), new ArrayList<String>());
//获取y轴坐标
List<double[]> values = getlist(data.size(),data); PointStyle[] styles = new PointStyle[] {PointStyle.CIRCLE};
//构建XYMultipleSeriesRenderer
XYMultipleSeriesRenderer renderer = buildRenderer(colors, styles); setChartSettings(renderer, "", xname, yname, 0.5, 12.5, 0, 30,Color.LTGRAY, Color.LTGRAY); int length = renderer.getSeriesRendererCount();//获取点数量
for (int i = 0; i < length; i++)
{
((XYSeriesRenderer) renderer.getSeriesRendererAt(i)).setFillPoints(true);//设置图上的点为实心
}
renderer.setXLabels(12);//设置x轴显示12个点,根据setChartSettings的最大值和最小值自动计算点的间隔
renderer.setYLabels(10);//设置y轴显示10个点,根据setChartSettings的最大值和最小值自动计算点的间隔
renderer.setShowGrid(true);//是否显示网格
renderer.setXLabelsAlign(Align.RIGHT);//刻度线与刻度标注之间的相对位置关系
renderer.setYLabelsAlign(Align.CENTER);//刻度线与刻度标注之间的相对位置关系
renderer.setZoomButtonsVisible(true);//是否显示放大缩小按钮
renderer.setPanLimits(new double[] { -10, 300, -10, 300 }); //设置拖动时X轴Y轴允许的最大值最小值.
renderer.setZoomLimits(new double[] { -10, 300, -10, 300 });//设置放大缩小时X轴Y轴允许的最大最小值. //构建view
View v = ChartFactory.getLineChartView(context,buildDataset(titles, x, values),renderer); layout.addView(v);
}
}
三.下面是我的界面代码,由于这课题并不在乎界面,我这里也就简陋了点
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@color/black"
xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout
android:layout_width="fill_parent"
android:layout_height="25dp"
android:orientation="horizontal"
android:layout_marginLeft="25dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:gravity="left|center_vertical"
android:background="@drawable/prompt">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:textSize="15dp"
android:text="@string/glu_value"
android:layout_marginLeft="60dp"
android:paddingTop="3dp"/>
</LinearLayout> <LinearLayout
android:id="@+id/gluc_glulay"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="230dp"
android:gravity="center_horizontal">
</LinearLayout> <LinearLayout
android:layout_width="fill_parent"
android:layout_height="25dp"
android:orientation="horizontal"
android:layout_marginLeft="25dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:gravity="left|center_vertical"
android:background="@drawable/prompt">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:textSize="15dp"
android:text="@string/insulin_value"
android:layout_marginLeft="60dp"
android:paddingTop="3dp"/>
</LinearLayout> <LinearLayout
android:id="@+id/gluc_ydslay"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="230dp"
android:gravity="center_horizontal">
</LinearLayout> </LinearLayout>
四.下面来到我们的Activity,这部分代码就很简单了,就是实例化控件以及筹备数据,再调用工具类绘图方法即可,就不全部贴出了。
glu_chart = (LinearLayout)findViewById(R.id.gluc_glulay);
yds_chart = (LinearLayout)findViewById(R.id.gluc_ydslay);
sqlitedatabase = DbManager.open(GlucoseChartA
ctivity.this);
GlucoseDao glucoseDao = new GlucoseDao(sqlitedatabase);
glulist = glucoseDao.getglucose(getsql(" and GlucoseDate = ? "), new String[]{TimeUtil.getNowDate()});
//获取数据
List<String> glu_data = new ArrayList<String>();
List<String> yds_data = new ArrayList<String>();
for(int i = 0; i< glulist.size() ;i++)
{
glu_data.add(String.valueOf(glulist.get(i).getGlucoseValue()));
yds_data.add(String.valueOf(glulist.get(i).getGlucoseYDSValue()));
}
//调用工具类方法
AChartEngineUtil.setchart(GlucoseChartActivity.this,glu_chart,new String[]{"血糖值"},new int[]{Color.GREEN},glu_data,"时间","血糖值");
AChartEngineUtil.setchart(GlucoseChartActivity.this,yds_chart,new String[]{"胰岛素值"},new int[]{Color.YELLOW},yds_data,"时间","胰岛素值");
五,最后看看我们的效果图,我这里随便拟了几条数据