Android 借助aChartEngine实现饼图,折线图,柱状图

  • Post author:
  • Post category:其他



1.       下载:


http://code.google.com/p/achartengine/downloads/list


2.       使用aChartEngine引入包时发生编译错误

:java.lang.noclassdeffounderror:org.achartengine.model.categoryseries

解决方法:



    1.    右击你的项目,选择Build path下的configure build path…

2.    选择Order and Export标签

3.    选中achartengine-1.0.0.jar复选框,

4.    将achartengine-1.0.0.jar移动到最下方,点击ok。



完成上述操作如果还报异常,android编译后,SDK17中有些组件用的jar文件名为lib,可以把放achartengine.jar文件名改为libs。


3.       借助于aChartEngine生成饼图还是蛮方便的

1>,定义

// 定义一个类别序列,此序列主要用于存储饼图的百分比及相应的标签

private CategorySeries mSeries;

// 定义一个渲染器

private DefaultRenderer mRenderer;

// 由类别序列和渲染器得到一个图表视图

private GraphicalView mChartView;

2>,初始化

private void initialPieChartBuilder() {

// TODO Auto-generated method stub

mRenderer=new DefaultRenderer();

mRenderer.setApplyBackgroundColor(true);

mRenderer.setBackgroundColor(Color.TRANSPARENT);

//      mRenderer.setChartTitleTextSize(20);

mRenderer.setLabelsTextSize(20);

mRenderer.setLabelsColor(Color.BLACK);

mRenderer.setShowAxes(false);   // 是否显示轴线

//      mRenderer.setAxesColor(Color.RED); //设置轴颜色

mRenderer.setFitLegend(false);

mRenderer.setInScroll(false);

mRenderer.setPanEnabled(false);

mRenderer.setShowCustomTextGrid(false);

mRenderer.setShowLegend(false);       //不显示图例

mRenderer.setShowGrid(false);

mRenderer.setClickEnabled(true);

//      mRenderer.setScale(1.5f);

//      mRenderer.setLegendTextSize(15);

//      mRenderer.setMargins(new int[] { 20, 50, 15, 0 });

//      mRenderer.setZoomButtonsVisible(true);

mRenderer.setStartAngle(45);

mSeries=new CategorySeries(“”);

LinearLayout layout = (LinearLayout) mDetailView.findViewById(R.id.photo_chart);

mChartView = ChartFactory.getPieChartView(context, mSeries, mRenderer);

layout.addView(mChartView, new LayoutParams(LayoutParams.FILL_PARENT,

LayoutParams.FILL_PARENT));

}

上面的过程很简单,就是初始化渲染器,然后获得图表视图,并将生成的图表视图加入LinearLayout中。渲染器的方法也不多,自己可以依据自己的需求来做一些调整,要提一下的是太苛刻的条件使用aChartEngine是做不到的,使用aChartEngine只是给大家提供一个生成简单图表的途径。

3>,动态的生成和刷新图表视图

mSeries.clear();   // 清空类别序列

for(SimpleSeriesRenderer renderer:mRenderer.getSeriesRenderers()){

// 移除老的图表列渲染器

mRenderer.removeSeriesRenderer(renderer);

}

for (int i = 0; i < mPercent.length; i++) {

if (mPercent[i]>0) {

// 添加一个图表列,第一个参数是标签,第二个参数是百分比,CATEGORY和COLORS为自定义数组

mSeries.add(CATEGORY[i] + formatPercent(mPercent[i]), mPercent[i]);

SimpleSeriesRenderer renderer = new SimpleSeriesRenderer();

renderer.setColor(COLORS[i]);

// 为图表列添加渲染器

mRenderer.addSeriesRenderer(renderer);

}

}

if (mChartView != null) {

// 重绘

mChartView.repaint();

}


4.       效果图

二. 生成折线图:

其实生成的过程和饼图类似,只需要注意一点数据集和渲染器不一样罢了,但这两个对象都是必不可少的,下面看一下实现过程:

1. 先定义全局变量

private GraphicalView mChartView;      // 要获取到的折线图View,当然你也可以使用它提供的intent方法重新打开一个Activity,但我要将生成的折线图加载到我的LinearLayout中

private XYMultipleSeriesDataset mDataset; // 数据集,这点和饼图是不一样的

private XYMultipleSeriesRenderer mRenderer; // 渲染器

private XYSeries mSeries;

2. 初始化

private void initialLineChartBuilder() {

// TODO Auto-generated method stub

mRenderer = new XYMultipleSeriesRenderer();

// mRenderer.setApplyBackgroundColor(true);

// mRenderer.setBackgroundColor(BACKGROUND_COLOR);

// mRenderer.setChartTitleTextSize(20);

mRenderer.setLabelsTextSize(context.getResources().getDimension(R.dimen.photo_label_size)); // 设置轴上标签的大小

// mRenderer.setLabelsColor(Color.BLACK);

// mRenderer.setShowAxes(true); // 是否显示轴线

// mRenderer.setAxesColor(Color.RED); //设置轴颜色

// mRenderer.setFitLegend(false);

// mRenderer.setInScroll(false);

// mRenderer.setPanEnabled(false);

// mRenderer.setShowCustomTextGrid(false);

mRenderer.setShowLegend(false); // 不显示图例

mRenderer.setShowGrid(true); // 设置显示网格线

mRenderer.setGridColor(Color.LTGRAY); // 设置网格线的颜色

mRenderer.setClickEnabled(true);

mRenderer.setAxisTitleTextSize(15); // 设置坐标轴标签字体大小

mRenderer.setAxesColor(Color.BLACK); // 设置坐标轴颜色

mRenderer.setXAxisMin(0.5); // 设置X坐标轴起始点

mRenderer.setXAxisMax(7.5); // 设置X坐标轴终点

mRenderer.setYAxisMin(5.5); // 设置Y坐标轴起始点

mRenderer.setYAxisMax(65.5); // 设置Y坐标轴终点

// mRenderer.setBarSpacing(0.5);

mRenderer.setXLabels(0); // X轴方向显示多少个标签,这里显示0,因为我们要自定义X轴的标签

mRenderer.setYLabels(6); // Y轴方向显示多少个标签

mRenderer.setXLabelsColor(Color.BLACK); // 设置X轴标签的显示颜色

mRenderer.setYLabelsColor(0, Color.BLACK); // 设置Y轴标签的显示颜色

mRenderer.setXLabelsAlign(Align.CENTER); // 设置X轴在标签哪边对齐方式

mRenderer.setYLabelsAlign(Align.RIGHT); // 设置Y轴在标签哪边的对齐方式

//mRenderer.setMargins(new int[] { 20, 40, 8, 0 }); // 设置边距 (top, left, bottom, right)

mRenderer.setMarginsColor(BACKGROUND_COLOR); // 如果有设置边距的话,设置边距的颜色

mRenderer.setXLabelsAngle(-45f); //设置X轴label旋转的度数

mRenderer.setBarSpacing(50);

//mRenderer.setPointSize(5); // 设置点的大小

//mRenderer.setZoomButtonsVisible(true);

//mRenderer.setZoomRate(1.5f);

//mRenderer.setPanEnabled(false, false);

//addSeriesRender();

// mRenderer.setScale(1.5f);

// mRenderer.setLegendTextSize(15);

// mRenderer.setZoomButtonsVisible(true);

// mRenderer.setStartAngle(45);

mDataset = new XYMultipleSeriesDataset();

mSeries = new XYSeries(“”);

// mSeries = new CategorySeries(“”);

// LinearLayout layout = (LinearLayout)

// mDetailView.findViewById(R.id.photo_chart);

mChartView = ChartFactory.

getLineChartView

(context, mDataset, mRenderer);  //注意这一点

LinearLayout.LayoutParams mParams=new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);

mParams.weight=1.0f;

mRootLayout.addView(mChartView,mParams);

mChartView.setBackgroundColor(BACKGROUND_COLOR);

mRootLayout.setBackgroundColor(BACKGROUND_COLOR);

}

3, 加载数据

double[] xAxisCoord=new double[]{1,2,3,4,5,6,7};

double[] yAxisCoord=new double[]{45,32,58,15,38,51,27};

String[] xAxisLabel=new String[]{“星期一”,”星期二”,”星期三”,”星期四”,”星期五”,”星期六”,”星期日”};

mSeries.clear();

for (int i = 0; i < xAxisLabel.length; i++) {

mSeries.add(xAxisCoord[i], yAxisCoord[i]);

mRenderer.addXTextLabel(xAxisCoord[i], xAxisLabel[i]);

}

mDataset.addSeries(mSeries);

if (mRenderer.getSeriesRendererCount()<=0) {

addSeriesRender();

}

if (mChartView != null) {

mChartView.repaint();

mChartView.zoomReset();

}


// addSeriesRender方法

private void addSeriesRender() {

// TODO Auto-generated method stub

XYSeriesRenderer renderer = new XYSeriesRenderer();

renderer.setPointStyle(PointStyle.POINT);

renderer.setColor(Color.BLUE);

//renderer.setFillPoints(true);

renderer.setChartValuesTextAlign(Align.CENTER);

//renderer.setChartValuesSpacing(15);

renderer.setChartValuesTextSize(10);

renderer.setDisplayChartValues(true);

renderer.setGradientEnabled(true);

// renderer.setFillBelowLine(true); // 折线下方是否用颜色填充

// renderer.setFillBelowLineColor(Color.BLACK);

renderer.setStroke(BasicStroke.SOLID);

renderer.setLineWidth(2);

mRenderer.addSeriesRenderer(renderer);

}

4. 效果图:

5. 其实借助于aChartEngine所有图的原理都是差不多的,需要数据集和渲染器,有区别的也许就是你有一些特殊的需求,aChartEngine还在不断的完善中,借助于上面的示例,相信你可以组织出更优秀的图例,比如在一个页面上画两个折线图,如你所知,添加两个Series和两个子渲染器即可。抛砖引玉!

三。生成柱图

和折线图的区别也不大,只不过子渲染器要用到的是SimpleSeriesRenderer,这里我是在上面的基础上做了一些修改并且基于我自己的项目为条件,可能有些地方你不是太明白,但你所要了解的就是它的工作流程。

1. 很熟悉,不是吗?

private GraphicalView mChartView;

private XYMultipleSeriesDataset mDataset; // 数据

private XYMultipleSeriesRenderer mRenderer; // 渲染器

private XYSeries mSeries;

2. 初始化

private void initialBarChartBuilder() {

// TODO Auto-generated method stub

mRenderer = new XYMultipleSeriesRenderer();

// mRenderer.setApplyBackgroundColor(true);

// mRenderer.setBackgroundColor(BACKGROUND_COLOR);

// mRenderer.setChartTitleTextSize(20);

mRenderer.setLabelsTextSize(context.getResources().getDimension(R.dimen.photo_label_size)); // 设置轴上标签的大小

// mRenderer.setLabelsColor(Color.BLACK);

// mRenderer.setShowAxes(true); // 是否显示轴线

// mRenderer.setAxesColor(Color.RED); //设置轴颜色

// mRenderer.setFitLegend(false);

// mRenderer.setInScroll(false);

// mRenderer.setPanEnabled(false);

// mRenderer.setShowCustomTextGrid(false);

mRenderer.setShowLegend(false); // 不显示图例

mRenderer.setShowGrid(false); // 设置显示网格线

mRenderer.setGridColor(Color.LTGRAY); // 设置网格线的颜色

mRenderer.setClickEnabled(false);

mRenderer.setAxisTitleTextSize(15); // 设置坐标轴标签字体大小

mRenderer.setAxesColor(Color.BLACK); // 设置坐标轴颜色

//mRenderer.setXAxisMin(0.5); // 设置X坐标轴起始点

//mRenderer.setXAxisMax(6.5); // 设置X坐标轴终点

//mRenderer.setYAxisMin(5.5); // 设置Y坐标轴起始点

//mRenderer.setYAxisMax(65.5); // 设置Y坐标轴终点

// mRenderer.setBarSpacing(0.5);

mRenderer.setXLabels(0); // X轴方向显示多少个标签

mRenderer.setYLabels(6); // Y轴方向显示多少个标签

mRenderer.setXLabelsColor(Color.BLACK); // 设置X轴标签的显示颜色

mRenderer.setYLabelsColor(0, Color.BLACK); // 设置Y轴标签的显示颜色

mRenderer.setXLabelsAlign(Align.CENTER); // 设置X轴在标签哪边对齐方式

mRenderer.setYLabelsAlign(Align.RIGHT); // 设置Y轴在标签哪边的对齐方式

//mRenderer.setMargins(new int[] { 20, 40, 8, 0 }); // 设置边距 (top, left, bottom, right)

mRenderer.setMarginsColor(BACKGROUND_COLOR); // 如果有设置边距的话,设置边距的颜色

mRenderer.setXLabelsAngle(-45f);

mRenderer.setPanEnabled(false, false);

mRenderer.setZoomEnabled(false);

mRenderer.setZoomRate(1.1f);

mRenderer.setBarSpacing(0.5f);

//mRenderer.setPointSize(5); // 设置点的大小

//mRenderer.setZoomButtonsVisible(true);

//mRenderer.setZoomRate(1.5f);

//mRenderer.setPanEnabled(false, false);

//addSeriesRender();

// mRenderer.setScale(1.5f);

// mRenderer.setLegendTextSize(15);

// mRenderer.setZoomButtonsVisible(true);

// mRenderer.setStartAngle(45);

mDataset = new XYMultipleSeriesDataset();

mSeries = new XYSeries(“”);

// mSeries = new CategorySeries(“”);

// LinearLayout layout = (LinearLayout)

// mDetailView.findViewById(R.id.photo_chart);

mChartView = ChartFactory

.getBarChartView(context, mDataset, mRenderer,Type.STACKED);

LinearLayout.LayoutParams mParams=new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);

mParams.weight=1.0f;

mScrollLayout=new LinearLayout(context);

mScrollLayout.setLayoutParams(mParams);

mScrollLayout.setGravity(Gravity.CENTER);

LinearLayout.LayoutParams mChartParams=new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);

mScrollLayout.addView(mChartView,mChartParams);

mRootLayout.addView(mScrollLayout);

mChartView.setBackgroundColor(BACKGROUND_COLOR);

mRootLayout.setBackgroundColor(BACKGROUND_COLOR);

}

3. 加载数据

private void addSeriesRender() {

// TODO Auto-generated method stub

SimpleSeriesRenderer renderer = new SimpleSeriesRenderer();

//renderer.setPointStyle(PointStyle.POINT);

renderer.setColor(context.getResources().getColor(R.color.color_bottle_green));

//renderer.setFillPoints(true);

renderer.setChartValuesTextAlign(Align.CENTER);

//renderer.setChartValuesSpacing(15);

renderer.setChartValuesTextSize(15);

renderer.setDisplayChartValues(true);

//renderer.setGradientEnabled(true);

// renderer.setFillBelowLine(true); // 折线下方是否用颜色填充

// renderer.setFillBelowLineColor(Color.BLACK);

//renderer.setStroke(BasicStroke.SOLID);

//renderer.setLineWidth(2);

mRenderer.addSeriesRenderer(renderer);

}

@Override

protected void refresh() {

// TODO Auto-generated method stub

super.refresh();

//Toast.makeText(context, “refresh”, Toast.LENGTH_LONG).show();

if (mData != null) {

try {

JSONObject mJsonObject = null;

clearDataSet();

//clearRender();

mSeries.clear();

mRenderer.clearXTextLabels();

float mMaxTrend=0,tempTrend=0;

for (int i = 0; i < mData.length(); i++) {

mJsonObject = mData.getJSONObject(i);

tempTrend=Float.parseFloat(mJsonObject.getString(“ServiceTurnOver”));

mSeries.add(i+1, tempTrend);

if (mMaxTrend<tempTrend) {

mMaxTrend=tempTrend;

}

if (mTrendType==TREND_DAYS) {

mRenderer.addXTextLabel(i+1, mDateHandler.getXLableByDay(mDaysData[mDaysData.length-(i+1)]));

}else if (mTrendType==TREND_MONTH) {

mRenderer.addXTextLabel(i+1, mDateHandler.getXLableByMonth(mMonthData[mMonthData.length-(i+1)]));

}

}

mDataset.addSeries(mSeries);

if (mTrendType == TREND_DAYS) {

//for (int i = 0; i < mDaysData.length; i++) {

//mRenderer.addXTextLabel(i+1, mDateHandler.getXLableByDay(mDaysData[mDaysData.length-(i+1)]));

//}

int mYUnit=(int)mMaxTrend/mYDivideStage;

if (mYUnit<=0) {

mYUnit=50;

mMaxTrend=600;

mRenderer.setRange(new double[]{0.5,7.5,0,mMaxTrend+mYUnit});

mRenderer.setYLabels(mYDivideStage);

}else {

mRenderer.setRange(new double[]{0.5,7.5,0,mMaxTrend+mYUnit});

mRenderer.setYLabels(mYDivideStage);

}

mRenderer.setMargins(new int[] { 20, 50, 20, 0 });

} else if (mTrendType == TREND_MONTH) {

//for (int i = 0; i < mMonthData.length; i++) {

//mRenderer.addXTextLabel(i+1, mDateHandler.getXLableByMonth(mMonthData[mMonthData.length-(i+1)]));

//}

int mYUnit=(int)mMaxTrend/mYDivideStage;

if (mYUnit<=0) {

mYUnit=500;

mMaxTrend=6000;

mRenderer.setRange(new double[]{0.5,6.5,0,mMaxTrend+mYUnit});

mRenderer.setYLabels(mYDivideStage);

}else {

mRenderer.setRange(new double[]{0.5,6.5,0,mMaxTrend+mYUnit});

mRenderer.setYLabels(mYDivideStage);

}

mRenderer.setMargins(new int[] { 20, 60, 20, 0 });

}

if (mRenderer.getSeriesRendererCount()<=0) {

addSeriesRender();

}

if (mChartView != null) {

mChartView.repaint();

mChartView.zoomReset();

}

} catch (JSONException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

mDateRangeLabel.setText(formatDate());

detectIfHiddenRightButton();

}

}

4. 效果图: