在上一篇文章中講解了Android自定義折線圖
這一篇來(lái)講解一下曲線圖巾钉,曲線圖需要用到三階貝塞爾曲線俊鱼,關(guān)于這部分的基礎(chǔ)铸题,你可以參考這個(gè)教程(推薦)
http://www.gcssloop.com/category/customview
效果圖
實(shí)現(xiàn)思路
其實(shí)整體上和上一篇折線圖差不多姐军,區(qū)別就是把折線變成了曲線
計(jì)算數(shù)據(jù)源的坐標(biāo)
/**
* 計(jì)算數(shù)據(jù)源的坐標(biāo)
*/
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坐標(biāo)間距之間包含5個(gè)點(diǎn)(包含2端)
int pw = firstPointX + (i * intervalX) ;
int ph = (int) (mHeight - paddingBottom - leftRightExtra - value * aver + minValueY * aver);
mPoints.add(new PointF(pw, ph));
//設(shè)置折線上數(shù)據(jù)點(diǎn)的坐標(biāo)
pointDataBean.setX(pw);
pointDataBean.setY(ph);
}
}
畫曲線
根據(jù)曲線上的數(shù)據(jù)點(diǎn)的坐標(biāo)來(lái)繪制曲線缺狠,只要2個(gè)數(shù)據(jù)點(diǎn)和2個(gè)控制點(diǎn)就可以確定一條曲線了器净。具體算法如下:
/**
* 畫曲線
*
* @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);
}
}
點(diǎn)擊曲線展示效果
這一點(diǎn)其實(shí)很簡(jiǎn)單型雳,點(diǎn)擊曲線上的點(diǎn)的時(shí)候,可以獲取到點(diǎn)擊的坐標(biāo)山害,曲線上的點(diǎn)也有坐標(biāo)纠俭,那我只需要找到離點(diǎn)擊的點(diǎn)最近點(diǎn)一個(gè)數(shù)據(jù)點(diǎn),展示對(duì)應(yīng)的數(shù)據(jù)即可浪慌,具體代碼見(jiàn)GitHub
完整代碼:
https://github.com/zhouxu88/CustomView