美文网首页
IOS 自定义折线图[OC]

IOS 自定义折线图[OC]

作者: zhangml0522 | 来源:发表于2018-03-19 09:52 被阅读0次

    swift版:https://www.jianshu.com/p/f581194cb02c

    预览

    折线图

    变量初始化

    //内边距
    static CGFloat borderX = 40;
    static CGFloat borderY = 20;
    //x和y的个数
    //x = 4: 2014,2015,2016,2017
    //y = 6: 0,500,100,1500,2000,2500
    static CGFloat x = 4;
    static CGFloat y = 6;
    //x和y每个单位代表的值
    static CGFloat yValue = 500;
    static CGFloat xValue = 1;
    //x和y的起始值
    static CGFloat yStart = 0;
    static CGFloat xStart = 2014;
    //x和y的单位长度
    CGFloat widthX;
    CGFloat heightY;
    

    构造函数

    -(instancetype)initWithArrayAndFrame:(NSArray *)array andFrame:(CGRect)frame{
        if (self = [super initWithFrame:frame]) {
            self.backgroundColor = [UIColor whiteColor];
            self.array = array;
            //计算单位长度
            widthX = (self.frame.size.width-borderX*2)/x;
            heightY = (self.frame.size.height-borderY*2)/y;
            //画x轴的label:2014,2015...
            [self drawX];
            //画y轴的label:0,500,1000...
            [self drawY];
            //画折线
            [self drawLine];
        }
        return self;
    }
    

    画坐标轴,虚线,和数据点

    -(void)drawRect:(CGRect)rect{
       //画坐标轴
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
        CGContextSetLineWidth(context, 1);
        CGContextMoveToPoint(context, borderX, borderY);
        CGContextAddLineToPoint(context, borderX, rect.size.height-borderY);
        CGContextAddLineToPoint(context, rect.size.width-borderX, rect.size.height-borderY);
        CGContextStrokePath(context);
        //画y轴的分割虚线
        CGContextRef context2 = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor);
        CGContextSetLineWidth(context2, 1);
        for (int i=1; i<y; i++) {
            UILabel *yLabel = (UILabel*)[self viewWithTag:2000 + i];
            CGContextMoveToPoint(context2, borderX-3, yLabel.frame.origin.y+heightY/2);
            CGContextAddLineToPoint(context2, rect.size.width-borderX, yLabel.frame.origin.y+heightY/2);
        }
        CGContextStrokePath(context2);
        //画x轴的分割点
        CGContextRef context3 = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(context3, [UIColor lightGrayColor].CGColor);
        CGContextSetLineWidth(context3, 1);
        for (int i=0; i<x; i++) {
            //通过tag获取x轴对应label
            UILabel *xLabel = (UILabel*)[self viewWithTag:1000 + i];
            CGContextMoveToPoint(context3, xLabel.frame.origin.x+widthX, rect.size.height-borderY);
            CGContextAddLineToPoint(context3, xLabel.frame.origin.x+widthX, rect.size.height-borderY+5);
        }
        CGContextStrokePath(context3);
        //画传入数组值对应的点
        CGContextRef context4 = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
        CGContextSetLineWidth(context, 2.0);
        //y轴的总值
        float yTotalValue = yStart + yValue*y;
        //y轴的长度
        float height = self.frame.size.height - borderY*2;
        for (int i=0; i<x; i++) {
            //计算点的纵坐标
            float pointy = self.frame.size.height - [self.array[i] floatValue]/yTotalValue*height - borderY;
            CGContextMoveToPoint(context4, widthX/2+widthX*i+borderX, pointy);
            // x,y为圆点坐标,radius半径,startAngle为开始的弧度,endAngle为 结束的弧度,clockwise 0为顺时针,1为逆时针。
            CGContextAddArc(context4, widthX/2+widthX*i+borderX, pointy, 5, 0, 2*M_PI, 0);
        }
        CGContextDrawPath(context4, kCGPathFill);
    }
    

    写X轴Y轴的数字

    -(void)drawX{
        for (int i=0; i<x; i++) {
            UILabel *xLabel = [[UILabel alloc]initWithFrame:CGRectMake(borderX+widthX*i, self.frame.size.height-borderY+5, widthX, 10)];
            NSInteger x = xStart+xValue*i;
            xLabel.text = [NSString stringWithFormat:@"%ld",x];
            xLabel.font = [UIFont systemFontOfSize:10];
            [xLabel setTextAlignment:NSTextAlignmentCenter];
            //设置tag,画分割线的时候用
            xLabel.tag = 1000+i;
            [self addSubview:xLabel];
        }
    }
    
    -(void)drawY{
        for (int i=0; i<y; i++) {
            UILabel *yLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, self.frame.size.height-borderY-heightY/2-heightY*i, 35, heightY)];
            NSInteger y = yStart+yValue*i;
            yLabel.text = [NSString stringWithFormat:@"%ld",y];
            yLabel.font = [UIFont systemFontOfSize:10];
            [yLabel setTextAlignment:NSTextAlignmentRight];
            yLabel.tag = 2000+i;
            [self addSubview:yLabel];
        }
    }
    

    画折线

    -(void)drawLine{
    
        float yTotalValue = yStart + yValue*y;
        float height = self.frame.size.height - borderY*2;
        float pointy = self.frame.size.height - [self.array[0] floatValue]/yTotalValue*height - borderY;
        //在第一个点下方写数值
        UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(widthX/2+borderX, pointy, 50, 20)];
        label.text = [NSString stringWithFormat:@"%ld",[self.array[0] integerValue]];
        label.font = [UIFont systemFontOfSize:10];
        [self addSubview:label];
        //贝塞尔曲线设置起始点
        UIBezierPath *linePath = [UIBezierPath bezierPath];
        [linePath moveToPoint:CGPointMake(widthX/2+borderX, pointy)];
        //开始画折线和后续的数值
        for (int i=1; i<x; i++) {
            float pointy = self.frame.size.height - [self.array[i] floatValue]/yTotalValue*height - borderY;
            [linePath addLineToPoint:CGPointMake(widthX/2+widthX*i+borderX, pointy)];
            
            UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(widthX/2+widthX*i+borderX, pointy, 50, 20)];
            label.text = [NSString stringWithFormat:@"%ld",[self.array[i] integerValue]];
            label.font = [UIFont systemFontOfSize:10];
            [self addSubview:label];
        }
        
        CAShapeLayer *lineLayer = [CAShapeLayer layer];
        lineLayer.lineWidth = 1;
        lineLayer.strokeColor = [UIColor blackColor].CGColor;
        lineLayer.path = linePath.CGPath;
        lineLayer.fillColor = nil;
        [self.layer addSublayer:lineLayer];
        //设置动画
        CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        pathAnimation.duration = 3;
        pathAnimation.repeatCount = 1;
        pathAnimation.removedOnCompletion = YES;
        pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
        pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
        [lineLayer addAnimation:pathAnimation forKey:@"strokeEnd"];
        pathAnimation.delegate = self;
        
    
    }
    

    使用

    NSArray *array = @[@(1342),@(2123),@(1654),@(1795)];
        ChartView *cv = [[ChartView alloc]initWithArrayAndFrame:array andFrame:CGRectMake(0, 70, 320, 250)];
        [self.view addSubview:cv];
    

    相关文章

      网友评论

          本文标题:IOS 自定义折线图[OC]

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