转自:http://www.cnblogs.com/coldwinter/archive/2013/05/02/3055127.html
AchartEngine是Android平台上的绘制科学统计图表的第三方应用库。可以绘制基本的折线图、曲线拟合图、直方图、圆饼图等多种图表。开发者提供了详细的接口介绍、DEMO工程与源码,因此可以很方便地使用它进行二次开发。
这段时间在工作中使用了这一绘图库,故在此记录使用的方法,为以后再次使用节约时间。
1 源码与开发环境
最新的库文件及源码可以在https://code.google.com/p/achartengine/中下载与查阅。开发者提供了一个全面的DEMO工程,绘制了折线图、曲线图、直方图、点图、圆饼图、圆环图、混合图等多种统计图表。工程可以在Eclipse下的Android开发环境中编译。
2 源码整体简析
DEMO工程中的ChartDemo Activity是工程的主活动。显示了要绘制的图表列表。每种图表都由一个类实现。所有的类都继承自AbstractDemoChart类。如下图所示。
AbstractDemoChart类实现了IDemoChart接口,这个接口用于主活动的ListView中每一项的显示。IDemoChart中的NAME与DESC分别是主活动ListView中每一项的名称与描述。
在介绍具体各项方法的实现前,先直观描述一下绘图的流程。在工程中绘图需要实现两部分,分别是数据模型(data model)与绘制器(renderer)。
数据模型包括以下几种。
XYSeries: 最常用的数据结构,主要包括一系列的double型(x,y)点对及一个名称(title)。
XYValueSeries:包括一系列的(x,y,value)点对及一个名称(title)。
XYMultipleSeriesDataset:包含一系列XYSeries,是最终的数据结构
TimeSeries:与XYSeries类似,x变为Date型,可以转化为XYSeries。
CategorySeries:与XYSeries类似,x变为string型,可以转化为XYSeries。
MultipleCategorySeries:一系列CategorySeries。
…
全部的数据结构参见
不同的数据模型用于不同的图表显示。XYSeries可以用于折线图、直方图。CategorySeries可以用于圆饼图。每种数据模型都提供了丰富的操作接口,用于插入删除数据等多种操作。我们可以根据需要将数据存为合适的数据模型。
绘制器声明了绘制图表的类型。主要包括以下几种。
具体的renderer参见
SimpleSeriesRenderer、XYSeriesRenderer用于设置每张图中每一个序列的绘制方法。而DefaultRenderer和XYMultipleSeriesRenderer用于设置整张图的绘制格式。它们之间的关系类似于XYSeries 与XYMultipleSeriesDataset之间的关系。
要画一张图,我们需要设置好需要绘制的数据及绘制的方法。确定好data model及renderer后,再调用合适的绘制方法绘制图形。库提供了两种绘制图形的方法,一种是get***Intent( )(如getLineChartIntent())直接新建一个Activity全屏显示生成的图表,另一种是get***View( )(如getLineChartView())生成一个View,用户可以自行设置它的显示。
3 Demo源码分析
本文选用了CombinedTemperatureChart进行分析。这张图绘制了折线图、太阳图和直方图。调用源码分析如下:
public Intent execute(Context context) { //设置了折线图中的title String[] titles = new String[] { "Crete Air Temperature", "Skiathos Air Temperature" }; //准备折线图的数据模型 List<double[]> x = new ArrayList<double[]>(); for (int i = 0; i < titles.length; i++) { x.add(new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }); } List<double[]> values = new ArrayList<double[]>(); values.add(new double[] { 12.3, 12.5, 13.8, 16.8, 20.4, 24.4, 26.4, 26.1, 23.6, 20.3, 17.2, 13.9 }); values.add(new double[] { 9, 10, 11, 15, 19, 23, 26, 25, 22, 18, 13, 10 }); int[] colors = new int[] { Color.GREEN, Color.rgb(200, 150, 0) }; PointStyle[] styles = new PointStyle[] { PointStyle.CIRCLE, PointStyle.DIAMOND }; //设置了总体的绘图器,并将折线图的绘制要求加入其中 XYMultipleSeriesRenderer renderer = buildRenderer(colors, styles); renderer.setPointSize(5.5f); int length = renderer.getSeriesRendererCount(); for (int i = 0; i < length; i++) { XYSeriesRenderer r = (XYSeriesRenderer) renderer.getSeriesRendererAt(i); r.setLineWidth(5); r.setFillPoints(true); } setChartSettings(renderer, "Weather data", "Month", "Temperature", 0.5, 12.5, 0, 40, Color.LTGRAY, Color.LTGRAY); renderer.setXLabels(12); renderer.setYLabels(10); renderer.setShowGrid(true); renderer.setXLabelsAlign(Align.RIGHT); renderer.setYLabelsAlign(Align.RIGHT); renderer.setZoomButtonsVisible(true); renderer.setPanLimits(new double[] { -10, 20, -10, 40 }); renderer.setZoomLimits(new double[] { -10, 20, -10, 40 }); //以下是太阳图,分别设置好数据sunSeries和绘图器lightRenderer XYValueSeries sunSeries = new XYValueSeries("Sunshine hours"); sunSeries.add(1, 35, 4.3); sunSeries.add(2, 35, 4.9); sunSeries.add(3, 35, 5.9); sunSeries.add(4, 35, 8.8); sunSeries.add(5, 35, 10.8); sunSeries.add(6, 35, 11.9); sunSeries.add(7, 35, 13.6); sunSeries.add(8, 35, 12.8); sunSeries.add(9, 35, 11.4); sunSeries.add(10, 35, 9.5); sunSeries.add(11, 35, 7.5); sunSeries.add(12, 35, 5.5); XYSeriesRenderer lightRenderer = new XYSeriesRenderer(); lightRenderer.setColor(Color.YELLOW); //以下是直方图,分别设置好数据waterSeries和绘图器waterRenderer XYSeries waterSeries = new XYSeries("Water Temperature"); waterSeries.add(1, 16); waterSeries.add(2, 15); waterSeries.add(3, 16); waterSeries.add(4, 17); waterSeries.add(5, 20); waterSeries.add(6, 23); waterSeries.add(7, 25); waterSeries.add(8, 25.5); waterSeries.add(9, 26.5); waterSeries.add(10, 24); waterSeries.add(11, 22); waterSeries.add(12, 18); renderer.setBarSpacing(0.5); XYSeriesRenderer waterRenderer = new XYSeriesRenderer(); waterRenderer.setColor(Color.argb(250, 0, 210, 250)); //设置总的数据模型,并将折线图的数据插入 XYMultipleSeriesDataset dataset = buildDataset(titles, x, values); //插入太阳图和直方图数据,index 为插入元素的位置 dataset.addSeries(0, sunSeries); dataset.addSeries(0, waterSeries); //插入太阳图和直方图绘图器 renderer.addSeriesRenderer(0, lightRenderer); renderer.addSeriesRenderer(0, waterRenderer); waterRenderer.setDisplayChartValues(true); waterRenderer.setChartValuesTextSize(10); //绘制图形 String[] types = new String[] { BarChart.TYPE, BubbleChart.TYPE, LineChart.TYPE, CubicLineChart.TYPE }; Intent intent = ChartFactory.getCombinedXYChartIntent(context, dataset, renderer, types, "Weather parameters"); return intent; }
4 总结
AChartEngine提供了丰富的绘图方法。在使用前可以查看DEMO工程,选择合适的绘制方法。确定了绘制方法后,设置好数据模型与绘图器,调用该方法即可绘制图形。