IOS折线图
做项目要统计商品的销售情况,美工那边给了效果图,自己就按照效果图自定义了一个ScrollView。整体效果不错,在做的过程中遇到的问题也记录一下。
现在这个还有许多优化的地方:
1.一个表中只能画一个折线
2.目前的要求最小值为0,没考虑负数的最小值
// // LineChartView.h // chart // // Created by City--Online on 15/9/17. // Copyright © 2015年 City--Online. All rights reserved. // #import <UIKit/UIKit.h> //设置两点的水平间距 #define SPACING 70.0 //文本类型 typedef NS_ENUM(NSInteger, TitleType) { TitleForX, TitleForPoint }; @class LineChartView; @protocol LineChartDataSource <NSObject> @required //折点数量 -(NSInteger)numberForChart:(LineChartView *)chart; //折点数值 -(float)chart:(LineChartView *)chart valueAtIndex:(NSInteger)index; @optional //X轴坐标是否有背景色 -(BOOL)chart:(LineChartView *)chart backGroundColorAtXPointIndex:(NSInteger)index; //X 轴的标题 -(NSString *)chart:(LineChartView *)chart titleForXLabelAtIndex:(NSInteger)index; @end @interface LineChartView : UIScrollView @property(nonatomic,assign)id<LineChartDataSource> dataSource; @end
// // LineChartView.m // chart // // Created by City--Online on 15/9/17. // Copyright © 2015年 City--Online. All rights reserved. // #import "YZPLineChartView.h" @interface YZPLineChartView () @property (nonatomic,strong) CAShapeLayer * linePath; @property(nonatomic,assign)NSInteger maxValue; //最大值 @property(nonatomic,assign)NSInteger count; //点数 @property(nonatomic,assign)CGFloat avgHeight; //刻度 @end @implementation YZPLineChartView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor=[UIColor whiteColor]; _linePath=[CAShapeLayer layer]; _linePath.lineCap=kCALineCapRound; _linePath.lineJoin=kCALineJoinBevel; _linePath.lineWidth=; _linePath.fillColor=[UIColor clearColor].CGColor; self.bounces=NO; self.showsHorizontalScrollIndicator=NO; self.showsVerticalScrollIndicator=NO; _maxValue=; } return self; } //最大值 -(NSInteger)maxValue { ; i<self.count; i++) { NSInteger value=[_dataSource chart:self valueAtIndex:i]; _maxValue=value>_maxValue?value:_maxValue; } return _maxValue; } //点数 -(NSInteger)count { return [_dataSource numberForChart:self]; } //刻度 -(CGFloat)avgHeight { CGFloat height=self.frame.size.height; _avgHeight=(height--)/self.maxValue; return _avgHeight; } -(void)drawRect:(CGRect)rect { [super drawRect:rect]; //每次加载先删除原有图层 int count = [self.layer.sublayers count]; ; i<count; i++) { [self.layer.sublayers[] removeFromSuperlayer]; } //不能通过for in 删除 was mutated while being enumerated 遍历的时候不能删除 // for (CALayer *layer in self.layer.sublayers) { // [layer removeFromSuperlayer]; // } ) { return; } [self.layer addSublayer:_linePath]; self.contentSize=CGSizeMake((self.count)*SPACING, self.bounds.size.height); //画底部边线 [self drawVerticalLineStartPoint:CGPointMake(, self.bounds.size.height-) withEndPoint:CGPointMake(self.contentSize.width, self.bounds.size.height-) withColor:[UIColor grayColor] ]; //画折线 [self drawBrokenLine]; } //画底部边线 -(void)drawBottomLine { UIBezierPath *bottomLine=[UIBezierPath bezierPath]; [bottomLine moveToPoint:CGPointMake(, self.bounds.size.height-)]; [bottomLine addLineToPoint:CGPointMake(self.contentSize.width, self.bounds.size.height-)]; [[UIColor colorWithRed:0.902f green:0.902f blue:0.902f alpha:1.00f] setStroke]; [bottomLine stroke]; } //画竖线 -(void)drawVerticalLineStartPoint:(CGPoint) startPoint withEndPoint:(CGPoint) endPoint withColor:(UIColor *)color { CAShapeLayer *layer=[CAShapeLayer layer]; layer.lineCap=kCALineCapRound; layer.lineJoin=kCALineJoinBevel; layer.lineWidth=0.5; layer.fillColor=[UIColor clearColor].CGColor; [self.layer addSublayer:layer]; UIBezierPath *bottomLinePath=[UIBezierPath bezierPath]; [bottomLinePath moveToPoint:startPoint]; [bottomLinePath addLineToPoint:endPoint]; layer.path=bottomLinePath.CGPath; layer.strokeColor=[UIColor colorWithRed:0.902f green:0.902f blue:0.902f alpha:1.00f].CGColor; } //画点 -(void)drawPointWithCenterPoint:(CGPoint)point radius:(float)radius strokeColor:(UIColor *)strokeColor fillColor:(UIColor *)fillColor { UIBezierPath *drawPoint=[UIBezierPath bezierPath]; [drawPoint addArcWithCenter:point radius:radius startAngle:M_PI* endAngle:M_PI* clockwise:YES]; CAShapeLayer *layer=[[CAShapeLayer alloc]init]; layer.path=drawPoint.CGPath; layer.strokeColor=strokeColor.CGColor; layer.fillColor=fillColor.CGColor; [self.layer addSublayer:layer]; } // 画文字 原本使用[NSstring drawAtPoint: withAttributes:]方法 但是画之后并不随着ScrollView滚动 所以用Label -(void)drawText:(NSString *)text withPoint:(CGPoint)point withType:(TitleType) type withIndex:(NSInteger)index { CGRect frame=[text boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:.f]} context:nil]; UILabel *label=[[UILabel alloc]init]; CGPoint pointForValueString=CGPointMake(point.x-, point.y); ) { pointForValueString.y=point.y-frame.size.height-; } ) { pointForValueString.y=point.y+frame.size.height-; } label.frame=CGRectMake(pointForValueString.x, pointForValueString.y, , ); label.textAlignment=NSTextAlignmentCenter; if (type==TitleForPoint) { label.textColor=[UIColor redColor]; label.font=[UIFont systemFontOfSize:.f]; } else if (type==TitleForX) { label.frame=CGRectMake(pointForValueString.x, pointForValueString.y+, ,); if (_dataSource&&[_dataSource respondsToSelector:@selector(chart:backGroundColorAtXPointIndex:)]) { if ([_dataSource chart:self backGroundColorAtXPointIndex:index]) { label.backgroundColor=[UIColor redColor]; label.textColor=[UIColor whiteColor]; label.layer.cornerRadius=label.bounds.size.width/; label.clipsToBounds=YES; } else { label.backgroundColor=[UIColor whiteColor]; label.textColor=[UIColor colorWithRed:0.298f green:0.298f blue:0.298f alpha:1.00f]; } } else { label.textColor=[UIColor colorWithRed:0.298f green:0.298f blue:0.298f alpha:1.00f]; } label.font=[UIFont systemFontOfSize:.f]; } label.text=text; [self addSubview:label]; } -(void)drawBrokenLine { UIBezierPath *path=[UIBezierPath bezierPath]; ; i<self.count; i++) { CGFloat value=[_dataSource chart:self valueAtIndex:i]; CGPoint point=[self pointWithValue:value index:i]; //画竖线 [self drawVerticalLineStartPoint:CGPointMake((i+) withEndPoint:point withColor: [UIColor blueColor]]; //画折点 [self drawPointWithCenterPoint:point radius: strokeColor:[UIColor redColor] fillColor:self.backgroundColor]; //画X轴刻度点 UIColor *pointColor=[UIColor colorWithRed:0.902f green:0.902f blue:0.902f alpha:1.00f]; [self drawPointWithCenterPoint:CGPointMake((i+) radius: strokeColor:pointColor fillColor:pointColor]; //画文字 NSString *valueString=[NSString stringWithFormat:@"%ld",(long)value]; [self drawText:valueString withPoint:point withType:TitleForPoint withIndex:i]; //画X轴 if (_dataSource&&[_dataSource respondsToSelector:@selector(chart:titleForXLabelAtIndex:)]) { NSString *xstring=[_dataSource chart:self titleForXLabelAtIndex:i]; [self drawText:xstring withPoint:CGPointMake(point.x, self.bounds.size.height-) withType:TitleForX withIndex:i]; } //画折线 //贝塞尔曲线 ) { [path moveToPoint:point]; }else{ [path addLineToPoint:point]; } } path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle=kCGLineJoinRound; path.lineWidth=0.5; [[UIColor redColor]setStroke]; CABasicAnimation *pathAnimation=[CABasicAnimation animationWithKeyPath:@"strokeEnd"]; pathAnimation.duration = ; pathAnimation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; pathAnimation.fromValue=[NSNumber numberWithFloat:0.0f]; pathAnimation.toValue=[NSNumber numberWithFloat:1.0f]; pathAnimation.autoreverses=NO; _linePath.path=path.CGPath; _linePath.strokeColor=[UIColor redColor].CGColor; [_linePath addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; _linePath.strokeEnd = 1.0; } //根据索引计算出折点的位置 -(CGPoint)pointWithValue:(NSInteger)value index:(NSInteger)index { CGFloat height=self.frame.size.height; ); } @end
调用:
#import "ViewController.h" #import "LineChartView.h" @interface ViewController ()<LineChartDataSource> @property (nonatomic,strong) NSArray *points; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _points=@[@,@,@,@,@,@,@,@,@,@]; LineChartView *lineChart=[[LineChartView alloc]initWithFrame:CGRectMake(, , self.view.bounds.size.width, )]; lineChart.dataSource=self; [self.view addSubview:lineChart]; } -(NSInteger)numberForChart:(LineChartView *)chart { return _points.count; } -(float)chart:(LineChartView *)chart valueAtIndex:(NSInteger)index { return [[_points objectAtIndex:index] floatValue]; } -(NSString *)chart:(LineChartView *)chart titleForXLabelAtIndex:(NSInteger)index { return [NSString stringWithFormat:@"10%ld",index]; } -(BOOL)chart:(LineChartView *)chart backGroundColorAtXPointIndex:(NSInteger)index { ) { return true; } else { return false; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
效果:
IOS折线图的更多相关文章
- iOS 折线图、柱状图的简单实现
首先我得感谢某位博主,非常抱歉,因为之前直接下载博主提供这篇文章的demo,然后去研究了,没记住博主的名字.再次非常感谢. 而这个dome我又修改了一些,完善了一些不美观的bug,当然还有,后面会陆续 ...
- IOS折线图二
上周把项目的折线图给做了下,今天想着把它完善完善,自己设置了不同的数据源来测试,哈哈,还真遇到问题了, 就是给图表设置折点数为0时,视图显示的还是原来的,由于数据为空,应该将其设置为空,所以想着怎么把 ...
- iOS 折线图实现
图表绘制的过程实际上是坐标位置的计算过程,至于画线只要有了position,通过CAShapeLayer+BezierPath很快就可以画出来,这里提供一个绘制折线的demo,贵在思路,有需要的可以参 ...
- iOS绘制坐标图,折线图-Swift
坐标图,经常会在各种各样的App中使用,最常用的一种坐标图就是折线图,根据给定的点绘制出对应的坐标图是最基本的需求.由于本人的项目需要使用折线图,第一反应就是搜索已经存在的解决方案,因为这种需求应该很 ...
- iOS 动画绘制线条颜色渐变的折线图
效果图 .................... 概述 现状 折线图的应用比较广泛,为了增强用户体验,很多应用中都嵌入了折线图.折线图可以更加直观的表示数据的变化.网络上有很多绘制折线图的demo,有 ...
- IOS绘制渐变背景色折线图的一种尝试
1.绘制折线图 上次在群里看到一个折线图划的很漂亮,自己想实现一个这样的 ,但是一直没什么头绪,不知道怎么做,就开始在网上查找划线,绘 制渐变色这一块的内容,用最笨的方式,自己尝试的写了一些,也没 有 ...
- UUChart的使用--iOS绘制折线图
UUChart是一个用于绘制图表的第三方,尤其适合去绘制折线图. 二.下载地址: https://github.com/ZhipingYang/UUChartView 三.使用 第一步.首先我们将下载 ...
- IOS使用Core-Plot画折线图
关于Core-Plot的配置.大家能够參考我的上一篇博客:http://1.wildcat.sinaapp.com/?p=99 版权全部.转载请注明原文转自:http://blog.csdn.net/ ...
- iOS:使用贝塞尔曲线绘制图表(折线图、柱状图、饼状图)
1.介绍: UIBezierPath :画贝塞尔曲线的path类 UIBezierPath定义 : 贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度. 曲线的定义有四个点:起始点 ...
随机推荐
- WPF解决方案------调用线程无法访问此对象,因为另一个线程拥有该对象
WPF [调用线程无法访问此对象,因为另一个线程拥有该对象.] 解决方案 在这里以播放图片为例进行说明,代码如下: void _Timer_Elapsed(object sender, Elapsed ...
- 【题解】 UVa11210 Chinese Mahjong
pdf传送门 直接模拟+搜索,考虑一下选哪一个是将,然后搜出顺子和刻子,最后判断一下可不可行就好了! #include<stdio.h> #include<string.h> ...
- BZOJ 2388--旅行规划(分块&单调栈&二分)
2388: 旅行规划 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 405 Solved: 118[Submit][Status][Discuss] ...
- linux系统无法启动,提示give root password for maintenance错误
电脑的虚拟机安装的是centos6.2操作系统,今天打开虚拟机时候,提示 give root password for maintenance (or type control-D to contin ...
- mylyn提交到JIRA的日期格式错误
HTTP Status 400 - Date value '27/Dec/11' for field 'due' is invalid. Valid formats include: 'yyyy/MM ...
- RecyclerView的通用适配器
本来这一个主题应该早就写了,只是项目多,属于自己的时间不多,所以现在才开动!! 前一段时间写了一篇文章,是关于ListView,GriView万能适配器,没有看过的同学,可以先看看那篇文章,然后在来学 ...
- Using the JDBC Driver
Download JDBC Driver This section provides quick start instructions for making a simple connection t ...
- [Objective-C语言教程]指针(15)
Objective-C中的指针简单易学.使用指针可以更轻松地执行某些Objective-C编程任务,并且在不使用指针的情况下无法执行其他任务(如动态内存分配). 所以有必要学习指向成为一个完美的Obj ...
- [CISCO] 转载:冲突域与广播域(区别、知识要点)
[CISCO] 转载:冲突域与广播域(区别.知识要点) 1.传统以太网操作(Ethernet Connection Ethernet) 传统共享式以太网的典型代表是总线型以太网.在这种类型的以太网中, ...
- css中代码格式以及@import的语法结构
CSS中代码格式 CSS是Cascading Style Sheets(层叠样式表)的缩写.是一种对web文档添加样式的简单机制,属于表现层的布局语言. 1.基本语法规范分析一个典型CSS的语句: p ...