之前章节介绍了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函数设置:

RecyclerChart其它图表绘制

以上代码里通过SleepItemEntry计算出ItemWidth的宽度,然后传给setLinearLayout函数:

RecyclerChart其它图表绘制

介绍完设置 Sleep泳道图 ItemView 不一致的宽度,下边就是怎么制作了, 由于Adpter里ItemView已经设置了它的width了,所以拿到ItemView的宽度之后,就能够直接依据它的宽度,然后不同的type确认其高度。

RecyclerChart其它图表绘制

确认每一个RectF之后,制作即可:

RecyclerChart其它图表绘制

本文首要介绍在除了基本的BarChart、LineChart、BezierChart等之外,能够看到RecyclerChart 能够制作更多的可能性的图表,在RecyclerView的 Adapter, dataModel, Render的配合下会有不同的可能性,能够解决各种不同的需求,同样例如之前的MPChart中介绍的SegmentBarChart这种变种的柱状图等,都能够完成的。