RecyclerBezierChart图表绘制

1,126 阅读2分钟

本篇介绍曲线图标RecyclerBezierChart 的绘制, 同样图表的公共部分的绘制这里不再做介绍,主体图表的绘制逻辑在BezierChartRender类中,其中包含主体曲线的绘制以及底部fill部分的渐变色的绘制。曲线的绘制用的三阶贝塞尔曲线,关于贝塞尔曲线相关的知识读者可自行Google,Android中的三阶贝塞尔曲线的绘制API接口,以下为Path构建三阶曲线,其中包含两个Control Points.

这里的绘制逻辑主要参考了MPAndroidChart中的曲线绘制.

首先将Entry的 Y值转换成对应的PointF,这个之前图表都有同样的操作,存入originPointFList, 然后通过originPointFList计算对应的 Control Points List, 存入 controList, 其中ControlPoint 这个类笔者自定义的包含了两个Control Point 点,紧接着Control Point的计算再介绍。

得到originPointFList, controList后,每次迭代套用Path.cubicTo(controlPoint1, controlPoint2, endPoint) API即可,最终得到 cubicPath.

曲线图底部是渐变Color区域,这里构建了封闭的Path cubicFillPath, 其中包含了cubicPath。

private void drawCubicFill(RecyclerView parent, Canvas c, List<PointF> pointFList, Path spline, float bottom) {
    spline.lineTo(pointFList.get(pointFList.size() - 1).x, bottom);
    spline.lineTo(pointFList.get(0).x, bottom);
    spline.close();
    drawFilledPath(parent, c, spline);
}

整个主体图表的绘制逻辑大致如上,非常简单。

下面是刚提到的关于 Control Point 的计算, 这里定义了一个类 ControlPoint, 包含两个Control Point点。上面计算controList 方法也就作为 它的static 方法放在ControlPoint 中了。

List<ControlPoint> controlList = ControlPoint.getControlPointList(originPointFList, mBarChartAttrs.bezierIntensity);

其中 bezierIntensity 表示控制贝塞尔曲线曲率强度的一个参数系数。

对于不是第一个,最后点, 计算公式:

controlPoint.x = cur.x + (next.x - pre.x) * bezierIntensity; Y值同理。

两个边界位置Index 边界的原因稍作变动,具体如下:

至此曲线图的绘制结束,非常简单,最后附上一张RecyclerBezierChart的gif 图。

本专栏到这里几个常用的图表的纯绘制介绍完了,接下来大致两到三章节介绍图表动态相关的逻辑,选中高亮的控制,长按选中滑动跟RecyclerView本身滑动的一个冲突上的解决;控制同一天显示在一屏时的回弹的控制逻辑。