Android RecyclerChart其它图表绘制示例详解
cxy107750 人气:0正文
之前章节介绍了RecyclerChart 中一些通用的图表的相关绘制逻辑,本章节介绍两种Special的Chart的绘制,一种是心电图,一种是睡眠图。首先我们来看下心电图EcgChart的绘制。
1. 心电图
EcgChart 跟LineChart形态上是相似的,但是EcgChart的点相对于LineChart密集的多,之前的LineChart相当于每个RecyclerView的Itemview 中的Model对应的value值,而心电图的ItemDataModel背后有一个List的value值与之对应,针对1080px width的手机而言,极大可能地超出了1px一个Point,所以这里的绘制逻辑换成每个Item中对应一段path, path 是由ItemDataModel的List,注意处理前后两个Path的衔接处即可, 这里具体List的大小可根据需求来定,原始的每个Item中是20个Point。首先先看下横屏无线右滑的EcgChart动图gif:
绘制的逻辑代码, 因为每个ItemView的width也很小就没有像之前的LineChart单独处理边界的绘制问题了。
private <T extends BarEntry> void drawLineChartWithoutPoint(Canvas canvas, RecyclerView parent, YAxis mYAxis) { final float parentRightBoard = parent.getWidth() - parent.getPaddingRight(); final float parentLeft = parent.getPaddingLeft(); //BaseBarChartAdapter adapter = (BaseBarChartAdapter) parent.getAdapter(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); T barEntry = (T) child.getTag(); float preValue = Integer.MIN_VALUE; if (i > 0){ View pointF1Child = parent.getChildAt(i - 1); T barEntryLeft = (T) pointF1Child.getTag(); if (barEntryLeft instanceof EcgEntry){ List<Float> values = ((EcgEntry) barEntryLeft).values; if (values.size() > 0){ preValue = values.get(values.size() - 1); } } } if (barEntry instanceof EcgEntry){ List<Float> values = ((EcgEntry) barEntry).values; RectF rectF = ChartComputeUtil.getBarChartRectF(child, parent, mYAxis, mLineChartAttrs, barEntry); if (rectF.left < parentLeft || rectF.right > parentRightBoard){ continue; } float innerItemWidth = rectF.width()/values.size(); float startX = rectF.left; // preValue 用来衔接两个ItemView中的path,防止断连的问题。 preValue = preValue == Integer.MIN_VALUE?values.get(0): preValue; float firstPosition = ChartComputeUtil.getYPosition(preValue, parent, mYAxis, mLineChartAttrs); Path pathItem = new Path(); pathItem.moveTo(startX, firstPosition); for (int j = 0; j < values.size(); j++) { float yPosition = ChartComputeUtil.getYPosition(values.get(j), parent, mYAxis, mLineChartAttrs); pathItem.lineTo(startX + j * innerItemWidth, yPosition ); } canvas.drawPath(pathItem, mLineChartPaint); } } }
EcgChart整体的绘制逻辑还是比较简单的, 这里的Entry对象也如上所述的包含一个List
public class EcgEntry extends BarEntry{ public List<Float> values = new ArrayList<>(); public EcgEntry(int i, float value, long timestamp, int type) { super(i, value, timestamp, type); } }
2. 睡眠图
之前在MPChart的绘制中有介绍过睡眠泳道图的绘制,不同与之前的Chart图表,每个Itemview 是等宽的,这里的Item是根据睡眠时长然后睡眠的Type来确定不同的高度、颜色等。这里先看下睡眠泳道动图gif:
看下代码在SleepChartAdapter中设置不同的ItemView的宽度,setLinearLayout函数设置:
以上代码里通过SleepItemEntry计算出ItemWidth的宽度,然后传给setLinearLayout函数:
介绍完设置 Sleep泳道图 ItemView 不一致的宽度,下边就是如何绘制了, 因为Adpter里ItemView已经设置了它的width了,所以拿到ItemView的宽度之后,就可以直接根据它的宽度,然后不同的type确定其高度。
确定每一个RectF之后,绘制即可:
本文主要介绍在除了基本的BarChart、LineChart、BezierChart等之外,可以看到RecyclerChart 可以绘制更多的可能性的图表,在RecyclerView的 Adapter, dataModel, Render的配合下会有不同的可能性,能够解决各种不同的需求,同样例如之前的MPChart中介绍的SegmentBarChart这种变种的柱状图等,都可以实现的。
加载全部内容