在上一篇文章中讲解了Android自定义折线图
这一篇来讲解一下曲线图,曲线图需要用到三阶贝塞尔曲线,关于这部分的基础,你可以参考这个教程(推荐)
http://www.gcssloop.com/category/customview
效果图
实现思路
其实整体上和上一篇折线图差不多,区别就是把折线变成了曲线
计算数据源的坐标
/**
* 计算数据源的坐标
*/
private void getPoints() {
mPoints.clear();
float aver = (lableCountY - 1) * intervalY / (maxValueY - minValueY); //y轴最小单位的距离
for (int i = 0; i < mPointDataBeanList.size(); i++) {
PointDataBean pointDataBean = mPointDataBeanList.get(i);
float value = pointDataBean.getValue();
//x坐标间距之间包含5个点(包含2端)
int pw = firstPointX + (i * intervalX) ;
int ph = (int) (mHeight - paddingBottom - leftRightExtra - value * aver + minValueY * aver);
mPoints.add(new PointF(pw, ph));
//设置折线上数据点的坐标
pointDataBean.setX(pw);
pointDataBean.setY(ph);
}
}
画曲线
根据曲线上的数据点的坐标来绘制曲线,只要2个数据点和2个控制点就可以确定一条曲线了。具体算法如下:
/**
* 画曲线
*
* @param canvas
*/
private void drawLine(Canvas canvas) {
// canvas.save();
// float t = 0.5f;//比例
PointF startp = new PointF();
PointF endp = new PointF();
Path path = new Path();
path.moveTo(mShowPoints.get(0).x, mShowPoints.get(0).y);
for (int i = 0; i < mShowPoints.size() - 1; i++) {
startp = mShowPoints.get(i);
endp = mShowPoints.get(i + 1);
float wt = (startp.x + endp.x) / 2;
PointF p3 = new PointF();
PointF p4 = new PointF();
p3.y = startp.y;
// p3.x = startp.x + (endp.x - startp.x) * t;
p3.x = wt;
p4.y = endp.y;
// p4.x = startp.x + (endp.x-startp.x) * (1 - t);
p4.x = wt;
path.cubicTo(p3.x, p3.y, p4.x, p4.y, endp.x, endp.y);
canvas.drawPath(path, linePaint);
}
}
点击曲线展示效果
这一点其实很简单,点击曲线上的点的时候,可以获取到点击的坐标,曲线上的点也有坐标,那我只需要找到离点击的点最近点一个数据点,展示对应的数据即可,具体代码见GitHub
完整代码:
https://github.com/zhouxu88/CustomView
网友评论