iOS 坐标折线图

项目需求,今天研究了一下关于折线图的一些东西,属于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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容

  • Quartz2D以及drawRect的重绘机制字数1487 阅读21 评论1 喜欢1一、什么是Quartz2D Q...
    PurpleWind阅读 771评论 0 3
  • 什么是Quartz 2D 1>Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac OS X系统(跨平台,...
    青葱烈马阅读 747评论 0 3
  • 第一步:先科普一下基础知识: Core Graphics是基于C的API,可以用于一切绘图操作 Core Grap...
    真爱要有你才完美阅读 2,447评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 想必大家都问过同样的一个问题:“为什么我的时间不够用?”下面请跟随我走进《寻找时间的人》(凯特•汤普森 著)这本...
    寂若秋叶阅读 306评论 0 2