CoreAnimation实现一个折线表
将折现表封装到一个view里,暴露给使用者的只有一个传入数据的方法。
//
// ChartLine.h
// BoxingChampion
//功能:根据传入的数组,绘制折线图 注意 其frame的宽 不能小于20,高不能小于50
// Created by on 14-12-29.
// Copyright (c) 2014年 . All rights reserved.
// #import <UIKit/UIKit.h> @interface ChartLine : UIView /*
功能:绘制折线图
参数:折线图的数据,如@[@1,@2]
返回值:无
*/
-(void)setData:(NSArray *)array_data; @end
在.m文件中,重写-(id)initWithFrame:(CGRect)frame
方法。
一个折线表,我们可以将它分为三个图层来表示:1、坐标轴图层。2、背景色图层。3、数据折线图层。其中坐标图层应设定贝塞尔曲线,根据路径绘制坐标轴。
// 添加坐标轴曲线路径
UIBezierPath *path_coordinate=[[UIBezierPath alloc] init];
[path_coordinate moveToPoint:CGPointMake(8, 12)]; //带有箭头状的坐标轴
[path_coordinate addLineToPoint:CGPointMake(10, 10)];
[path_coordinate addLineToPoint:CGPointMake(12, 12)];
[path_coordinate addLineToPoint:CGPointMake(10, 10)];
[path_coordinate addLineToPoint:CGPointMake(10, self.frame.size.height-10)];
[path_coordinate addLineToPoint:CGPointMake(self.frame.size.width-10, self.frame.size.height-10)];
[path_coordinate addLineToPoint:CGPointMake(self.frame.size.width-12, self.frame.size.height-12)];
[path_coordinate addLineToPoint:CGPointMake(self.frame.size.width-10, self.frame.size.height-10)];
[path_coordinate addLineToPoint:CGPointMake(self.frame.size.width-12, self.frame.size.height-8)]; //坐标轴路径图层
CAShapeLayer *layer_coordinate=[CAShapeLayer layer];
layer_coordinate.frame=
CGRectMake(0, 0, self.layer.frame.size.width, self.layer.frame.size.height);
layer_coordinate.lineCap=kCALineCapButt;
layer_coordinate.lineWidth=2;
layer_coordinate.fillColor=[[UIColor clearColor] CGColor];
layer_coordinate.strokeColor=[[UIColor orangeColor] CGColor];
layer_coordinate.strokeEnd=1;
layer_coordinate.path=[path_coordinate CGPath];
背景色图层应有渐变色效果,且背景色都在坐标轴所包围的象限内
//淡色背景图层
CAGradientLayer *layer_background=[CAGradientLayer layer];
layer_background.frame=CGRectMake(11, 13, self.layer.frame.size.width-22,self.layer.frame.size.height-24);//保证在第一象限
[layer_background setColors:[NSArray arrayWithObjects:
(id)[[UIColor whiteColor] CGColor],
[[UIColor colorWithRed:1.000 green:0.827 blue:0.000 alpha:1.000] CGColor] ,nil]];
layer_background.locations=@[@0.1];//从0.1处开始渐变 location 坐标是左上角(0,0),在右下角(1,1) 使用时应注意
layer_background.startPoint=CGPointMake(0,0);
layer_background.endPoint=CGPointMake(0, 1);
将两个图层添加到视图图层上
//添加图层
[self.layer addSublayer:layer_coordinate];
[self.layer addSublayer:layer_background];
最后当用户调用setData:方法时,绘制折线图
-(void)setData:(NSArray *)array_data
{
//获取输入元素的个数
NSInteger i_dataCount=[array_data count]; //取出元素中得最大值和最小值
CGFloat f_maxData=[[array_data objectAtIndex:0] floatValue];
CGFloat f_minData=[[array_data objectAtIndex:0]floatValue];
for (NSInteger i=0;i<i_dataCount; i++)
{
if (f_maxData<[[array_data objectAtIndex:i] floatValue])
{
f_maxData=[[array_data objectAtIndex:i] floatValue];
}
if (f_minData>[[array_data objectAtIndex:i] floatValue])
{
f_minData=[[array_data objectAtIndex:i] floatValue];
}
} //计算每个数据之间横坐标的间隔
CGFloat x_perDataPointInterval=(self.layer.frame.size.width-20)/(i_dataCount+1);
if (0==(f_maxData-f_minData))//防止分母为零
{
NSLog(@"Y轴逻辑最大值和逻辑最小值相同");
return;
} //计算每个数据1 占据几个像素点
CGFloat y_perPointInterval=(self.layer.frame.size.height-50)/(f_maxData-f_minData); //折线路径
UIBezierPath *path_data=[[UIBezierPath alloc] init]; //第一个元素起始点的坐标
[path_data moveToPoint:CGPointMake(10+x_perDataPointInterval,
self.layer.frame.size.height-(20+([[array_data objectAtIndex:0] floatValue]-f_minData)*y_perPointInterval))]; for (NSInteger i=0; i<i_dataCount-1; i++)
{
//每个元素在视图中的坐标
[path_data addLineToPoint:CGPointMake(10+x_perDataPointInterval*(i+2),
self.layer.frame.size.height-(20+([[array_data objectAtIndex:(i+1)] floatValue]-f_minData)*y_perPointInterval))];
} //折线图层
CAShapeLayer *layer_data=[CAShapeLayer layer];
layer_data.frame=CGRectMake(0, 0, self.layer.frame.size.width, self.layer.frame.size.height);
layer_data.lineCap=kCALineCapRound;
layer_data.lineWidth=1;
layer_data.fillColor=[[UIColor clearColor] CGColor];
layer_data.strokeColor=[[UIColor redColor] CGColor];
layer_data.strokeEnd=1;
layer_data.path=[path_data CGPath]; [self.layer addSublayer:layer_data];
}
CoreAnimation实现一个折线表的更多相关文章
- 利用CoreAnimation实现一个时间的进度条
(个人原创,转载请注明出处 http://www.cnblogs.com/pretty-guy/p/7460334.html) 在iOS中实现进度条通常都是通过不停的设置progress来完成的,这样 ...
- 一、CoreAnimation之图层树详解
CoreAnimation :在字面意思为“核心动画”,但是如果您认为它仅仅是一个动画框架,那可能就要错过一些经典功能了.动画,只是CoreAnimation功能的一小部分,毕竟人家的源头是一个叫做L ...
- 手把手教你打造一个心电图效果View Android自定义View
大家好,看我像不像蘑菇-因为我在学校呆的发霉了. 思而不学则殆 丽丽说得对,我有奇怪的疑问,大都是思而不学造成的,在我书读不够的情况下想太多,大多等于白想,所以革命没成功,同志仍需努力. 好了废话不说 ...
- 利用sklearn对MNIST手写数据集开始一个简单的二分类判别器项目(在这个过程中学习关于模型性能的评价指标,如accuracy,precision,recall,混淆矩阵)
.caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...
- jq 折面板+tab切换(自己封装的插件哦!!)
如上图所示的一个折面板效果+tab切换:最重要的js代码如下: 对于布局简单介绍下: hot_wrap_li 这个是带箭头的横条: Arrow 这个是箭头的div:hot_wrap_li_wrap 这 ...
- 移动端图表插件jChart.js的修改
bug1: 折线图,设置datasetGesture : true时,Y轴的刻度值居然会变.会变也就算了,居然没地方设置不能变. bug2: 折线图,设置tap.point事件,和datasetGes ...
- 练习: bs4 简单爬取 + matplotlib 折线图显示 (关键词,职位数量、起薪)
要看一种技术在本地的流行程度,最简单的就是找招聘网站按关键词搜索. 比如今天查到的职位数量是vue 1296个,react 1204个,angular 721个.国际上比较流行的是react,本地市场 ...
- ElementUI 不维护了?供我们选择的 Vue 组件库还有很多!
前文回顾:Vue+Spring Boot 前后端分离的商城项目开源啦! Vue 组件千千万,只要不行咱就换. ElementUI 近况 根据我最近的观察,得知一些关于 ElementUI 维护人员都退 ...
- http程序接口、调用(最入门级,文末附Demo)
HTTP协议简介 既然是基于HTTP协议开发,那么就首先要了解下HTTP协议的相关内容- 在TCP/IP体系结构中,HTTP属于应用层协议,位于TCP/IP协议的顶层.浏览Web时,浏览器通过HTTP ...
随机推荐
- [51Testing情人节活动]情人节,爱要有“礼”才完美!
2.14情人节,你还在纠结送TA什么礼物么? 你还苦于不敢表白么? 在微信里勇敢说出你的爱 51Testing帮你给TA特别的惊喜! Ps.用这个做借口表个白也不错哦! 本期51官方微信特别选出三种精 ...
- nodejs 基本问题答疑
传统服务器架构1.服务器接到请求2.创建一个新的响应程序的实例 node服务器架构1.服务器接到请求2.检查处理程序是否存在,如果存在直接处理,不存在则创建. node的做法节省了内存 ubuntu下 ...
- Cleaner Robot - CodeForces 589J(搜索)
有一个M*N的矩阵,有一个会自动清洁的机器人,这个机器人会按照设定好的程序来打扫卫生,如果当前方向前面可以行走,那么直接走,如果不可以走那么会向右转动90度,然后回归上一步判断.求机器人最多能打扫的面 ...
- java读取配置文件
java 读取文件可以用字节流和字符流. 由于一个汉字占两个字节,所以如果配置文件中有汉字,用字节流读取,会出现乱码. 用字符流则不会出现乱码. 配置文件 b.properties 文件如下: fam ...
- MySQL自定义查询字段排序
同事在做抽奖排名的时候有个问题 需要按照 一等奖 二等奖 三等奖 未中奖 的形式输出数据 问到我如何排序. 数据库设计如下 用一个prize_code字段标示了是否中奖 1是一等奖 2是二等奖 3是三 ...
- C# 动态创建出来的窗体间的通讯 delegate2
附件:http://files.cnblogs.com/xe2011/CSharp_WindowsForms_delegate02.rar 窗体2 和窗体3 都是动态创建出来的 现在 FORM3.TE ...
- Java 线程第三版 第一章Thread导论、 第二章Thread的创建与管理读书笔记
第一章 Thread导论 为何要用Thread ? 非堵塞I/O I/O多路技术 轮询(polling) 信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...
- 第三篇——第二部分——第五文 配置SQL Server镜像——域环境SQL Server镜像日常维护
本文接上面两篇搭建镜像的文章: 第三篇--第二部分--第三文 配置SQL Server镜像--域环境:http://blog.csdn.net/dba_huangzj/article/details/ ...
- 全文索引(三)lucene 分词 Analyzer
分词: 将reader通过阅读对象Analyzer字处理,得到TokenStream处理流程被称为分割. 该解释可能是太晦涩.查看示例,这个东西是什么感性的认识. 样品:一段文本"this ...
- Swift 实现图片转字符画的功能
本文介绍一个IOS APP , 将图片转换成ASCII字符画,使用Swift语言编写. 举个例子,我们使用著名的蕾娜照片作为原图片 经APP转换后形成的字符画,我们打印出来,效果如下: 放大她的脸部可 ...