今日项目需要绘制一条收益曲线:
由于之前没有用Android画过类似曲线图,就在网上search了一把,最后选择了MPAndroidChart, MPAndroidChart是一款基于Android的开源图表库,MPAndroidChart不仅可以在Android设备上绘制各种统计图表,而且可以对图表进行拖动和缩放操作,应用起来非常灵活,它的官方给的例子就不再粘贴,地址如下:https://bitbucket.org/PhilJay/mpandroidchart 从这里可以找到所有官方资料。
简单介绍一下实现过程:
项目采用了最新的jar包,主要注意的是,从2.1版本以后 x轴XLabels改为XAxis,Y轴也是一样,同时Y轴可以分别显示左边和右边的坐标轴。
基本和其他控件用法无异。
lcIncomDetails = (LineChart) findViewById(R.id.chart1);
// 在chart上的右下角加描述
lcIncomDetails.setDescription("");
// 是否显示图例
lcIncomDetails.getLegend().setEnabled(false);
// 设置透明度
lcIncomDetails.setAlpha(0.8f);
// 设置网格底下的那条线的颜色
lcIncomDetails.setBorderColor(Color.rgb(213, 216, 214));
// 设置是否可以触摸,如为false,则不能拖动,缩放等
lcIncomDetails.setTouchEnabled(true);
// 设置是否可以拖拽,缩放
lcIncomDetails.setDragEnabled(true);
lcIncomDetails.setScaleEnabled(true);
// 设置是否能扩大扩小
lcIncomDetails.setPinchZoom(true);
// 设置背景颜色,LineChart的背景,绘图区域外
lcIncomDetails.setBackgroundColor(Color.WHITE);
// 是否绘制图形下面的颜色
lcIncomDetails.setDrawGridBackground(true);
// 绘制图形下面的颜色
lcIncomDetails.setGridBackgroundColor(Color.WHITE);
//y轴的值自适应
lcIncomDetails.setAutoScaleMinMaxEnabled(true);
// 设置点击chart图对应的数据弹出标注
MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);
// set the marker to the chart
lcIncomDetails.setMarkerView(mv);
// enable/disable highlight indicators (the lines that indicate the
// highlighted Entry)
// 设置字体格式,如正楷
Typeface tf = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf");
XAxis xAxis = lcIncomDetails.getXAxis(); // 得到图表的X轴实例
xAxis.setPosition(XAxisPosition.BOTTOM);// 设置X轴的显示位置
xAxis.setAvoidFirstLastClipping(true);
xAxis.enableGridDashedLine(2f, 2f, 0f); // 设置横向表格为虚线
xAxis.setDrawGridLines(true); // 设置是否显示X轴表格
xAxis.setAvoidFirstLastClipping(false); // 设置x轴起点和终点label不超出屏幕
xAxis.setDrawAxisLine(true);
xAxis.setAvoidFirstLastClipping(true);
// 设置显示x轴
xAxis.setSpaceBetweenLabels(0); // 设置x轴label不间隔
xAxis.setTextSize(10f); // 设置字体大小
YAxis leftAxis = lcIncomDetails.getAxisLeft(); // 得到图表的左侧Y轴实例
leftAxis.setStartAtZero(false); // 设置图表起点从0开始
leftAxis.enableGridDashedLine(2f, 2f, 0f); // 设置横向表格为虚线
leftAxis.setDrawLimitLinesBehindData(false);
leftAxis.setTypeface(tf); // 设置字体
leftAxis.setTextSize(10f); // s设置字体大小
leftAxis.setLabelCount(7, false); // 设置Y轴最多显示的数据个数
YAxis rightAxis = lcIncomDetails.getAxisRight();
rightAxis.setEnabled(false);
// 加载数据
setData();
// 从X轴进入的动画
lcIncomDetails.animateX(2000);
lcIncomDetails.animateY(2000); // 从Y轴进入的动画
// mChart.animateXY(3000, 3000); //从XY轴一起进入的动画
// 设置最小的缩放
lcIncomDetails.setScaleMinima(1f, 1f);
// 设置视口
// mChart.centerViewPort(10, 50);
lcIncomDetails.getData().setHighlightEnabled(true);
lcIncomDetails.highlightValue(lcIncomDetails.getHighestVisibleXIndex(), 1);
// 刷新图表
lcIncomDetails.invalidate();
lcIncomDetails.getHighestVisibleXIndex();
private void setData() {
String[] aa = {"09-01", "09-02", "09-03", "09-04", "09-05", "09-06", "09-07", ""};
String[] bb = {"12", "25", "20", "26", "60", "28", "20"};
int[] circleColor =
{Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE,
Color.rgb(244, 117, 117)};
ArrayList xVals = new ArrayList();
for (int i = 0; i < aa.length; i++) {
xVals.add(aa[i]);
}
ArrayList yVals = new ArrayList();
for (int i = 0; i < bb.length; i++) {
yVals.add(new Entry(Float.parseFloat(bb[i]), i));
}
// create a dataset and give it a type
LineDataSet set1 = new LineDataSet(yVals, "DataSet Line");
set1.setDrawCubic(false); // 设置曲线为圆滑的线
set1.setCubicIntensity(0.2f);
set1.setDrawFilled(false); // 设置包括的范围区域填充颜色
set1.setDrawCircles(true); // 设置有圆点
set1.setDrawCircleHole(false);
set1.setHighlightEnabled(false);
set1.setCircleColors(circleColor);
set1.setLineWidth(3f); // 设置线的宽度
set1.setCircleSize(0); // 设置小圆的大小
set1.setHighLightColor(Color.rgb(244, 117, 117));
set1.setColor(Color.rgb(255, 5, 5)); // 设置曲线的颜色
// create a data object with the datasets
LineData data = new LineData(xVals, set1);
// set data
lcIncomDetails.setData(data);
}
运行一下吧:
效果图基本有了,细心的同学可能会注意到代码里面的MyMarkerView,就是点击到x轴的某一个点时弹出的信息了,
这个其实很简单,只要继承MarkerView ,实现其抽象方法:
@Override
public void refreshContent(Entry e, Highlight highlight) {
// TODO Auto-generated method stub
if (e instanceof CandleEntry) {
CandleEntry ce = (CandleEntry) e;
tvContent.setText("昨日收益" + Utils.formatNumber(ce.getHigh(), 0, true)+"M");
} else {
// tvContent.setText("" + Utils.formatNumber(e.getVal(), 0, true));
tvContent.setText("昨日收益" +e.getVal()+"M");
}
}
@Override
public int getXOffset(float xpos) {
// TODO Auto-generated method stub
return -getMeasuredWidth() / 2;
}
@Override
public int getYOffset(float ypos) {
// TODO Auto-generated method stub
return -getMeasuredHeight()-10;
}
MpAndroidChart在动画上有很好的支持,可以根据需求自己添加。整体代码还是很简单的,但较全的涵盖了对MpAndroidChart的LineChart使用方式,希望对准备使用该开源框架的人有些帮助。此外,在一些细节方面,感觉MpAndroidChart在自定义方面表现比较差,比如圆点的显示,只能全部显示或者全部不显示,在实现项目中的只显示最后一个收益的时候有些费力;线的颜色,虽然可以设置某一段的颜色不同,但同一段内的颜色值只能是唯一的,不能渐变。希望后期能提供更多的接口,给开发者提供更多灵活性!
demo代码下载:获取源代码