美文网首页
IOS使用Core Graphics绘制折线图

IOS使用Core Graphics绘制折线图

作者: 老南 | 来源:发表于2019-05-14 17:21 被阅读0次

    先上效果图

    折线图

    好了,上代码

    - (void)drawRect:(CGRect)rect{    

    //step1.绘制带圆角底图

    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(10, 10)];    

    [path addClip];

    //step2.绘制渐变底色

    CGContextRef context = UIGraphicsGetCurrentContext();    

    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();

    CGFloat locations[2]={0,1.0};//渐变域

    NSMutableArray *colors = [NSMutableArray arrayWithCapacity:2];

    [colors addObject:(id)[UIColor colorWithRed:250/255.0 green:233/255.0 blue:222/255.0 alpha:1].CGColor];

     [colors addObject:(id)[UIColor colorWithRed:252/255.0 green:79/255.0 blue:8/255.0 alpha:1].CGColor];

    CGGradientRef gradient = CGGradientCreateWithColors(space, (CFArrayRef)colors, locations);

    CGPoint startPoint = CGPointZero;

    CGPoint endPoint = CGPointMake(0, self.bounds.size.height);

    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);

    //tips:如果折线图需要多次刷新,最好把这些固定参数在初始化时就赋值好,在drwaRect内新建过多变量在高刷新频率下会影响性能

    //step3.绘制白色折线段

     [[UIColor whiteColor]setFill];

     [[UIColor whiteColor]setStroke];

    for (int i = 0; i < _elevationPoints.count; i++) {

         if (i == 0) {

             [graphPath moveToPoint:CGPointMake([self getViewPointXWithCoordHeight:                [_distancPoints[i] doubleValue]],[self getViewPointYWithCoordHeight:[_elevationPoints[i] doubleValue]])];//这里为获取每个点坐标的自定义方法,可忽略

        }else{

            [graphPath addLineToPoint:CGPointMake([self getViewPointXWithCoordHeight:[_distancPoints[i] doubleValue]], [self getViewPointYWithCoordHeight:        [_elevationPoints[i] doubleValue]])];

        }

    graphPath.lineWidth = 2.0;    

     [graphPath stroke];

    //note:屏幕坐标和drawrect内的Y坐标不一样 一个从屏幕上方到下方递增,一个刚好相反,注意做好坐标转换

    //step4:绘制折线下面的白色透明渐变色

    CGContextSaveGState(context);//储存当前绘制状态

    UIBezierPath *clippingPath = [graphPath copy];//复制折线段

    [clippingPath addLineToPoint:CGPointMake([self getViewPointXWithCoordHeight:[_distancPoints[_distancPoints.count -1] doubleValue]],rect.size.height - BottomBorder)];

    [clippingPath addLineToPoint:CGPointMake([self getViewPointXWithCoordHeight:[_distancPoints[0] doubleValue]],rect.size.height - BottomBorder)];

    [clippingPath closePath]; //将折线段添加两条垂直线(一条垂直X轴,一条垂直Y轴)并闭合,形成封闭路径

    [clippingPath addClip];//获取封闭路径为编辑区域

    CGContextDrawLinearGradient(context, gradient, CGPointMake(Margin, BottomBorder), CGPointMake(Margin, rect.size.height ),0);//绘制渐变色

    CGContextRestoreGState(context);//恢复至储存位置的绘制状态(既编辑区域又返回为整个圆角rect,FillColor和StrokeColor返回为白色)

    //step5:绘制折点

    for (int i = 0; i < _elevationPoints.count; i++) {

        double pointY = [self getViewPointYWithCoordHeight:[_elevationPoints[i] doubleValue]] - 2.5;

        double pointX = [self getViewPointXWithCoordHeight:[_distancPoints[i] doubleValue]] - 2.5;

        UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(pointX, pointY, 5, 5)];

        [circle fill];

    }

    //step6:绘制坐标系白色横线以及数字标识

     UIBezierPath *linePath = [UIBezierPath bezierPath];

    NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init];

     [style setAlignment:NSTextAlignmentCenter];

    for (int i = 0; i < 5; i++) {

        double pointY = [self getViewPointYWithCoordHeight:[_elevationLines[i] integerValue]];

        [linePath moveToPoint:CGPointMake(Margin,pointY)];

        [linePath addLineToPoint:CGPointMake(rect.size.width - Margin, pointY)];

        NSString *height = [NSString stringWithFormat:@"%lu",[_elevationLines[i]integerValue]];

        [height drawInRect:CGRectMake(Margin/2-20, pointY-10, 40, 20)     withAttributes:@{NSFontAttributeName:[UIFont     systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor     whiteColor],NSParagraphStyleAttributeName:style}];

    }

    [[UIColor colorWithWhite:1.0 alpha:0.8] setStroke];

    linePath.lineWidth = 1.0;

    [linePath stroke];

    //step7:绘制底部横向数字和单位

    NSString *elevationStr = @"(m)海拔";

    [elevationStr drawInRect:CGRectMake(Margin/2-20, TopBorder/2-10, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor whiteColor],NSParagraphStyleAttributeName:style}];

    NSString *distanceStr = [NSString stringWithFormat:@"%.02f km",self.totalDistance/1000];

    [distanceStr drawInRect:CGRectMake(rect.size.width - Margin - 40, rect.size.height-BottomBorder + 10, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor whiteColor],NSParagraphStyleAttributeName:style}];

    NSString *midDistanceStr = [NSString stringWithFormat:@"%.02f",self.totalDistance/2000];

    [midDistanceStr drawInRect:CGRectMake(rect.size.width / 2.0 - 40, rect.size.height-BottomBorder + 10, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor whiteColor],NSParagraphStyleAttributeName:style}];

    NSString *startDistanceStr = @"0";

     [startDistanceStr drawInRect:CGRectMake(Margin - 40, rect.size.height-BottomBorder+10, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor whiteColor],NSParagraphStyleAttributeName:style}];

    }

    整体流程就是如此,这里提供的是思路和方法,具体绘制实现需要读者自己去计算每个点的位置、每条线的位置以及单位数量等

    相关文章

      网友评论

          本文标题:IOS使用Core Graphics绘制折线图

          本文链接:https://www.haomeiwen.com/subject/fbxlvqtx.html