close
当前位置: 物联网在线 > 技术文库 > ios >

PNChart 源码解析

PNChart 是国内开发者开发的iOS图表框架,现在已经7900多颗star了。它涵盖了折线图,饼图,散点图等图表。图表的可定制性很高,而且UI设计简洁大方。

该框架分为两层:视图层和数据层。视图层里有两层继承关系,第一层是所有类型图表的父类 PNGenericChart ,第二层就是所有类型的图表。提供一张图来直观感受一下:

PNChart 源码解析

层级图

在这张图里,需要注意以下几点:

带箭头的线和不带箭头的线的区别。

Data 类对应图表的一组数据,因为当前类型的图表支持多组数据(例如:饼状图没有 Data 类,因为饼状图没有多组数据,而折线图 LineChart 是支持多组数据的,所以有 Data 类。

Item 类负责将传入图表的某个真实值转化为图表中显示的值,具体做法会在下文详细讲解。

BarChart 类里面的每一根柱子都是 PNBar 的实例(该类型的图表不在本篇讲解的范围之内)。

今天就来介绍一下该框架里的折线图。一旦学会了折线图的绘制,了解了绘图原理,那么其他类型的图表就可以触类旁通。

上文提到过,该框架的折线图是支持多组数据的,也就是在同一张图表上显示多条折线。先带大家看一下效果图:

PNChart 源码解析

折线图

折线图在效果上还是很简洁美观的(并支持动画效果),如果现在的你还不知道如何使用 CAShapeLayer 和 UIBezierPath 画图并附加动画效果,那么本篇源码解析非常适合你。

阅读本文之后,你可以掌握有关图形绘制的相关知识,也可以掌握自定义各种图形( UIView )的方法,而且你也应该有能力作出这样的图表,甚至更好!

在开始讲解之前,我先粗略介绍一下利用 CAShapeLayer 画图的过程。这个过程有三个大前提:

因为 UIView 是对 CALayer 的封装,所以我们可以通过改变 UIView 所持有的 layer 属性来直接改变 UIView 的显示效果。

CAShapeLayer 是 CALayer 的子类。

CAShapeLayer 的使用是依赖于 UIBezierPath 的。 UIBezierPath 就是“路径”,可以理解为形状。不难理解,想象一下,如果我们想画一个图形,那么这个图形的形状(包括颜色)是必不可少的,而这个角色,就需要 UIBezierPath 来充当。

那么了这三个大前提,我们就可以知道如何画图了:

实例化一个 UIBezierPath ,并赋给 CAShapeLayer 实例的 path 属性。

将这个 CAShapeLayer 的实例添加到 UIView 的 layer 上。

简单的代码演示上述过程:

UIBezierPath *path = [UIBezierPathbezierPath]; ...自定义path... CAShapeLayer *shapLayer = [CAShapeLayeralloc] init]; shapLayer.path = path; [self.view.layeraddSubLayer:shapeLayer];

现在大致了解了画图的过程,我们来看一下该框架的作者是如何实现一个折线图的吧!

二. 源码解析

首先看一下整个绘制折线图的步骤:

图表的初始化。

获取横轴和纵轴的数据。

计算折线上所有拐点的x,y值。

计算每个拐点中间的圆圈的贝塞尔曲线(UIBezierPath)。

生成每个拐点上面的Label(可有可无)。

计算每条线段的贝塞尔曲线(UIBezierPath)。

将上面得到的贝塞尔曲线赋给每条线段和圆圈的layer(CAShapeLayer)。

绘制所有折线(所有线段+所有圆圈)。

添加动画(可有可无)。

绘制x,y坐标轴。

在集合代码具体讲解之前,我们要清楚三点(非常非常重要):

此折线图框架是可以设置拐点的样式的:可以设置为没有样式,也可以设置有样式:圆圈,方块,三角形。

如果没有样式,则是简单的线段与线段的连接,在拐点处没有任何其他控件。

如果是有样式的,那么这条折线里的每条线段(在本篇文章里统一说成线段)之间是 分离的 ,因为线段中间有一个拐点控件。本篇文章介绍的是圆圈样式(如上图所示,拐点控件是一个圆圈)。

上文提到过,该折线图框架可以在一张图表里同时显示多条折线,也就是可以设置多组数据(一条折线对应一组数据)。因此,上面的3,4,5,6,7项都是用各自不同的一个数组保存的,数组里的每一个元素对应一条折线的数据。

既然同一个张图表可以显示多条折线:

那么有些属性就是这些折线共有的,比如横坐标的value,这些属性保存在 PNLineChart 的实例里面。

有些属性是每条折线私有的,比如每条折线的颜色,纵坐标value等等,这些属性保存在 PNLineChartData 里面。每一条折线对应一个 PNLineChartData 实例。这些实例汇总到一个数组里面,这个数组由 PNLineChart 的实例管理。


(责任编辑:ioter)

用户喜欢...

IBM解析2018年最流行的五项IoT趋势

2017年,物联网技术(loT)为传统行业带来了变革的风声和兴奋的议论。这是一场实质性的转变。我们已经能够看到,几乎所有的行业都在投资物联网,而且其中的佼佼者已经开始迅速采取行...


自动扫地机器人好用吗?智能特性全面解析

生活在如今这样一个节奏快、工作压力大的时代,我们的压力也是越发的大了,但是人类的智慧是强大的,智能家居...


深度解析FPGA四大设计要点

FPGA的用处比我们平时想象的用处更广泛,原因在于其中集成的模块种类更多,而不仅仅是原来的简单逻辑单元(LE)。早期的FPGA相对比较简单,所有的功能单元仅仅由管脚、内部buffer、LE、RAM构...


从图像到知识:深度神经网络实现图像理解的原理解析

摘要:本文将详细解析深度神经网络识别图形图像的基本原理。针对卷积神经网络,本文将详细探讨网络中每一层在图像识别中的原理和作用,例如卷积层(convolutional layer),采样层(pooling la...


单片机最小系统解析(电源、晶振和复位电路)

我们在学习过程中,很多指标都是直接用的概念指标,比如我们说 +5 V 代表1,GND 代表0等等。但在实际电路中的电压值并不是完全精准的,那这些指标允许范围是什么呢?随着我们所学的内容...


技术解析:微流控芯片为什么这样强大?

从1990年Manz等人首次提出了微型全分析系统的概念,到2003年Forbes杂志将微流控技术评为影响人类未来15件最重要的发明之一,微流控技术得到了飞速的发展,其中的微流控芯片技术作为当前分...


解析单片机与CPU的区别

多人都认为,单机片和CPU不是属于两种不同的东西吗?他们怎么可以拿来比较,其实有专业人士就知道单机片和CPU 的关系可以说是十分的密切。本文来分享一下,他们到底隐藏着什么秘密。...


陆金所计葵生:深度解析大数据和AI对未来金融影响

陆金所联席董事长兼CEO计葵生在北京大学数字金融研究中心「数字金融的中国时代」第二届年会上发表主题演讲,深...


滴滴插件化方案 VirtualApk 源码解析

之前一直没有写过插件化相关的博客,刚好最近滴滴和360分别开源了自家的插件化方案,赶紧学习下,写两篇博客,第一篇是滴滴的方案: https://github.com/didi/VirtualAPK 那么其中的难点很明显是...


STM32 FSMC驱动TFTLCD 难点解析

本篇文章三个主题:FSMC有关配置、一串字符显示原理、汉字显示原理。 一、FSMC的有关配置(博主用的是FSMC_A10): 来自别人家的博客 FSMC的介绍就不介绍了,网上一大片。我们就讨论讨论为...