iOS 坐标折线图

作者: 蒋昉霖 | 来源:发表于2016-03-14 11:44 被阅读2720次

    项目需求,今天研究了一下关于折线图的一些东西,属于Quartz2D的范畴

    一个好用的第三方库PNChart

    Quartz2D简介

    • Quartz2D:二维的绘图引擎
    • 可以跨平台开发(Mac和iPhone)
    • 常用的是截屏/剪裁/自定义UI控件

    想要绘图,就必须重写drawRect:方法,因为只有这个方法里才能获取上下文

    绘制步骤

    1. 获取图形上下文
    2. 描述路径(起点和终点)
    3. 把路径添加到上下文
    4. 渲染上下文

    如果你发现你的图形不对或者出不来就检查4步,缺一不可

    系统原生方法
    - (void)drawLine
    {
        // 1,获取图形上下文
        // 目前我们所有的上下文都是以UIGraphics
        // CGContexRef Ref:引用 CG:目前所用到的类型和函数,一般都是CG开头  CoreGraphics
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        
        // 2,描述路径
        // 创建路径
        CGMutablePathRef path = CGPathCreateMutable();
        
        // 设置起点
        // path:给哪个路径设置起点
        CGPathMoveToPoint(path, NULL, 50, 50);
        
        // 添加一条线到某一点
        CGPathAddLineToPoint(path, NULL, 200, 200);
        
        // 3.把路径添加到上下文
        CGContextAddPath(ctx, path);
        
        // 4.渲染上下文
        CGContextStrokePath(ctx);
    }
    
    系统第一层封装
    - (void)drawLine1
    {
        // 获取上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        
        // 这个方法系统会自动给你生成路径,自动给你添加到上下文,但是底层还是封装的drawLine里写的方法
        // 描述路径
        // 设置起点
        CGContextMoveToPoint(ctx, 50, 50);
        // 终点
        CGContextAddLineToPoint(ctx, 200, 200);
        
        // 渲染上下文
        CGContextStrokePath(ctx);
    }
    
    贝瑟尔曲线方法
    - (void)drawLine2
    {
        // 创建路径
        UIBezierPath *path = [UIBezierPath bezierPath];
        
        // 设置起点
        [path moveToPoint:CGPointMake(50, 50)];
        
        // 添加一根线到某个点上
        [path addLineToPoint:CGPointMake(200, 200)];
        
        // 绘制路径
        [path stroke];
    }
    
    系统方法实现两条线
    - (void)drawCtxState
    {
        // 获取上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        // 描述路径
        // 起点
        CGContextMoveToPoint(ctx, 50, 50);
        
        CGContextAddLineToPoint(ctx, 100, 50);
        
        // 设置起点
    //    CGContextMoveToPoint(ctx, 80, 60);
        // 默认下一根线的起点就是上一根线终点
        CGContextAddLineToPoint(ctx, 100, 200);
        CGContextAddLineToPoint(ctx, 200, 60);
        CGContextAddLineToPoint(ctx, 50, 50);
        
        // 设置绘图状态,一定要渲染之前
        // 这个只渲染线的颜色
    //    [[UIColor redColor] setStroke];
        // 线的颜色和填充物的颜色都渲染
        [[UIColor redColor] set];
        
        // 线宽
        CGContextSetLineWidth(ctx, 15);
        
        // 设置连接样式
        CGContextSetLineJoin(ctx, kCGLineJoinBevel);
    
        // 设置顶角样式
        CGContextSetLineCap(ctx, kCGLineCapRound);
        
        //渲染上下文
        CGContextStrokePath(ctx);
        
        // 填充满图
    //    CGContextFillPath(ctx);
    }
    
    贝瑟尔方法实现两线
    - (void)drawUIBezierPathState
    {
        UIBezierPath *path = [UIBezierPath bezierPath];
        
        [path moveToPoint:CGPointMake(50, 50)];
        
        [path addLineToPoint:CGPointMake(200, 200)];
        
        [path addLineToPoint:CGPointMake(40, 100)];
        
        [path setLineWidth:5];
        
        [[UIColor greenColor] set];
        
        [path stroke];
        
        // 两条不搭嘎的线,用两条路径
        UIBezierPath *path1 = [UIBezierPath bezierPath];
        
        [path1 moveToPoint:CGPointMake(70, 60)];
        
        [path1 addLineToPoint:CGPointMake(160, 180)];
        
        // 如果想实现两条线颜色不同等方法,分别写两次渲染即可
        path1.lineWidth = 13;
        
        [[UIColor blueColor] set];
        
        [path1 stroke];
    }
    

    图形上下文状态栈方法更改第二条曲线状态

    - drawSaveGStateLine
    {
        // 1.获取上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        
        // 2.描述路径
        // 第一根
        UIBezierPath *path = [UIBezierPath bezierPath];
        
        [path moveToPoint:CGPointMake(10, 125)];
        
        [path addLineToPoint:CGPointMake(240, 125)];
        
        // 把路径添加到上下文
        // .CGPath 可以UIkit的路径转换成CoreGraphics路径
        CGContextAddPath(ctx, path.CGPath);
        
        // 必须先添加上下文,保存现有状态
        // 保存一份上下文的状态
        CGContextSaveGState(ctx);
    
        // 设置上下文状态
        CGContextSetLineWidth(ctx, 10);
    //    path.lineWidth = 200;
        
        [[UIColor redColor] set];
       
        // 渲染上下文
        CGContextStrokePath(ctx);
        
    //    [path stroke];
        
        // 第二根
        // 2.描述路径
        // 第一根
        path = [UIBezierPath bezierPath];
        
        [path moveToPoint:CGPointMake(125, 10)];
        
        [path addLineToPoint:CGPointMake(125, 240)];
        
        // 把路径添加到上下文
        // .CGPath 可以UIkit的路径转换成CoreGraphics路径
        CGContextAddPath(ctx, path.CGPath);
        
        // 还原状态
        CGContextRestoreGState(ctx);
    //    // 设置上下文状态
    //    CGContextSetLineWidth(ctx, 1);
    //    
    //    [[UIColor blackColor] set];
        
        // 渲染上下文
        CGContextStrokePath(ctx); 
    }
    

    好了,这是现在系统收录的用语做直线的方法

    然后介绍一下一个好用的,做折线图的第三方框架

    这个第三方的Demo其实已经写的很简单了,这里面有几个样式,我们今天只讲一下折线图


    Snip20160314_1.png

    下面是我直接粘的Demo的代码,进行简单注释
    调用的时候写入如下代码即可,数据自己换一下

            self.titleLabel.text = @"Line Chart";
            // 放折线图的框框
            self.lineChart = [[PNLineChart alloc] initWithFrame:CGRectMake(0, 135.0, SCREEN_WIDTH, 200.0)];
            // 设计X轴
            self.lineChart.yLabelFormat = @"%1.1f";
            // 设置X轴颜色
            self.lineChart.backgroundColor = [UIColor clearColor];
            // 设置X轴显示的内容
            [self.lineChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5",@"SEP 6",@"SEP 7"]];
            // 是否显示轴,默认为NO
            self.lineChart.showCoordinateAxis = YES;
            
            //Use yFixedValueMax and yFixedValueMin to Fix the Max and Min Y Value
            //Only if you needed
            // Y轴设置
            self.lineChart.yFixedValueMax = 300.0;
            self.lineChart.yFixedValueMin = 0.0;
    
            [self.lineChart setYLabels:@[
                @"0 min",
                @"50 min",
                @"100 min",
                @"150 min",
                @"200 min",
                @"250 min",
                @"300 min",
                ]
             ];
            
            // Line Chart #1
            // 第一组数据
            NSArray * data01Array = @[@60.1, @160.1, @126.4, @0.0, @186.2, @127.2, @176.2];
            // 相应参数
            PNLineChartData *data01 = [PNLineChartData new];
            data01.dataTitle = @"Alpha";
            data01.color = PNFreshGreen;
            data01.alpha = 0.3f;
            data01.itemCount = data01Array.count;
            data01.inflexionPointStyle = PNLineChartPointStyleTriangle;
            data01.getData = ^(NSUInteger index) {
                CGFloat yValue = [data01Array[index] floatValue];
                return [PNLineChartDataItem dataItemWithY:yValue];
            };
            
            // Line Chart #2
            // 第二组数据
            NSArray * data02Array = @[@0.0, @180.1, @26.4, @202.2, @126.2, @167.2, @276.2];
            PNLineChartData *data02 = [PNLineChartData new];
            data02.dataTitle = @"Beta";
            data02.color = PNTwitterColor;
            data02.alpha = 0.5f;
            data02.itemCount = data02Array.count;
            data02.inflexionPointStyle = PNLineChartPointStyleCircle;
            data02.getData = ^(NSUInteger index) {
                CGFloat yValue = [data02Array[index] floatValue];
                return [PNLineChartDataItem dataItemWithY:yValue];
            };
            
            // 加入数据源
            self.lineChart.chartData = @[data01, data02];
            // 渲染出来
            [self.lineChart strokeChart];
            self.lineChart.delegate = self;
            
            [self.view addSubview:self.lineChart];
    
            self.lineChart.legendStyle = PNLegendItemStyleStacked;
            self.lineChart.legendFont = [UIFont boldSystemFontOfSize:12.0f];
            self.lineChart.legendFontColor = [UIColor redColor];
            
            // 放标注的框框
            UIView *legend = [self.lineChart getLegendWithMaxWidth:100];
            [legend setFrame:CGRectMake(30, 340, legend.frame.size.width, legend.frame.size.width)];
            [self.view addSubview:legend];
    

    哦了,就这么简单

    附带github上网址
    https://github.com/kevinzhow/PNChart

    相关文章

      网友评论

        本文标题:iOS 坐标折线图

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