IOS使用Core Graphics绘制折线图

2019-05-14  本文已影响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}];

}

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

上一篇下一篇

猜你喜欢

热点阅读