用CAShapeLayer实现一个简单的饼状图(PieView)

自己写了一个简单的PieView,demo在这里:https://github.com/Phelthas/LXMPieView

效果如图:

参考了https://github.com/kevinzhow/PNChart  和 https://github.com/xyfeng/XYPieChart 的代码

实现方法:

绘制饼状图所需的值只有各个扇形对应的值及对应的颜色,但可能会有很多附加的元素需要显示(比如字体颜色,字体大小等),

所以将每个扇形所需的数据封装为一个model对象,方便以后扩展。

1,绘制每个扇形,需要知道扇形的startAngle和endAngle,所以需要计算每个扇形所占的百分比及角度,

然后第一个扇形的start是0,end是第一个扇形的角度,

第二个扇形的start是第一个扇形的end,第二个扇形的end是前两个扇形的角度之和,以此类推

这里写死了饼状图从-0.5*Pi的位置开始绘制,所以计算出每个扇形的startAngle和endAngle,分别保存到数组中。

2,绘制各个扇形,

用UIBezierPath的- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise NS_AVAILABLE_IOS(4_0);方法

注意这里这里要用 moveToPoint和 addLineToPoint方法绘制成闭合曲线,方便后面判断。

依次add到self.layer上即可

3,添加描述label

这里是计算出每个label应该位于的中心位置,然后把label 直接add到view上。中心位置根据点在圆中的位置用几何方法(忘了的补初中数学)算出来。

4,旋转动画

这里还是用layer的mask属性来达到部分渲染的效果,参考我之前的解释:http://www.cnblogs.com/Phelthas/p/4643400.html

5,添加点击事件

这里只用了一个tapGesture添加到view上,然后通过gesture的location来判断点中的是哪个区域。

那怎么判断location这个点在不在某个区域内呢???

苹果提供了一个高大上的方法:

/* Return true if `point‘ is contained in `path‘; false otherwise. A point
   is contained in a path if it is inside the painted region when the path
   is filled; if `eoFill‘ is true, then the even-odd fill rule is used to
   evaluate the painted region of the path, otherwise, the winding-number
   fill rule is used. If `m‘ is non-NULL, then the point is transformed by
   `m‘ before determining whether the path contains it. */

CG_EXTERN bool CGPathContainsPoint(CGPathRef __nullable path,
    const CGAffineTransform * __nullable m, CGPoint point, bool eoFill)

CG_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);

例:

CGPoint location = [sender locationInView:sender.view];

CGAffineTransform transform = CGAffineTransformIdentity;

NSInteger index = -1;

for (int i = 0; i < self.subLayerArray.count; i ++) {
        CAShapeLayer *shapeLayer = self.subLayerArray[i];
        if (CGPathContainsPoint(shapeLayer.path, &transform, location, 0)) {
            index = i;
            break;
        }

}

6,用delegate的方式将点击事件回调出去

这个只是为了方便外部调用而进行的封装,同时也是为了逻辑分离,代码整洁~~

时间: 2024-12-15 07:11:28

用CAShapeLayer实现一个简单的饼状图(PieView)的相关文章

简单的饼状图

#import <UIKit/UIKit.h> @interface WHBKPieChartView : UIView @property(nonatomic,strong) NSArray *dataResource; @end #import "WHBKPieChartView.h" @implementation WHBKPieChartView -(void)setDataResource:(NSArray *)dataResource{ _dataResourc

D3.js的v5版本入门教程(第十三章)—— 饼状图

D3.js的v5版本入门教程(第十三章) 这一章我们来绘制一个简单的饼状图,我们只绘制构成饼状图基本的元素——扇形.文字,从这一章开始,内容可能有点难理解,因为每一章都会引入比较多的难理解知识点,在这里作者本人也只是粗略的讲解每个新知识点的意思!如果不是很理解的话,需要读者自行查看官网API 为了绘制一个饼状图,我们还是需要以下新的知识点 d3.arc( {} ),弧形生成器,用以绘制弧形,需要传入一些用以绘制弧形基本的数据的对象,例如,该对象的属性可以包括(我用官网api的示例) d3.pie

Android开发自定义控件实现一个饼状图

实现一个如图所示的控件,包括两部分,左边的饼状图和中间的两个小方块,及右边的两行文字 实现起来比较简单,只是一些绘图API的调用 核心代码在onDraw函数里边,,对静态控件进行绘制即可 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /*饼状图的x坐标*/ float centreX= getWidth()/5; /*饼状图的y坐标*/ float centreY= getHeight()/2; /*

highcharts+jsp+springDataJpa实现饼状图,树状图

1.饼状图 1. 创建spirngboot项目,引入以下启动器. <!-- servlet 依赖. --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> </dependency> <!-- jstl依赖. --&g

Android图表库MPAndroidChart(七)—饼状图可以再简单一点

Android图表库MPAndroidChart(七)-饼状图可以再简单一点 接上文,今天实现的是用的很多的,作用在统计上的饼状图,我们看下今天的效果 这个效果,我们实现,和之前一样的套路,我先来说下这个的应用场景,假设,我是一名小学老师,现在教务处让我设置一个图表,说明下我带的班级期末考试有多少人优秀,多少人及格和不及格等等,而这些呢,我已经算出来百分比了,只剩下画图了,那好,我们就来实现以下吧 一.基本实现 首先是我们的布局 <com.github.mikephil.charting.cha

JavaScript+svg绘制的一个饼状图

svg参考:https://www.w3.org/TR/SVG/ <body onload='document.body.appendChild( pieChart([12,23,34,45],640,400,200,200,150, ["red","blue","yellow","green"], ["North","South","East","W

iOS:使用贝塞尔曲线绘制图表(折线图、柱状图、饼状图)

1.介绍: UIBezierPath :画贝塞尔曲线的path类 UIBezierPath定义 : 贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度. 曲线的定义有四个点:起始点.终止点(也称锚点)以及两个相互分离的中间点. 滑动两个中间点,贝塞尔曲线的形状会发生变化. UIBezierPath :对象是CGPathRef数据类型的封装,可以方便的让我们画出 矩形 . 椭圆 或者 直线和曲线的组合形状 初始化方法: + (instancetype)bezierPath; /

AngularJS in Action读书笔记5(实战篇)——在directive中引入D3饼状图显示

前言: "宁肯像种子一样等待  也不愿像疲惫的陀螺  旋转得那样勉强" 这是前几天在查资料无意间看到的一位园友的签名,看完后又读了两遍,觉得很有味道.后来一寻根究底才知这是出资大诗人汪国真之口,出处<她>.且抛开上下文,单从这短短几句,正恰如其分的折射出有一群人,他们穿着不那么fashion,言辞不那么犀利,但是内心某一块地方像是躁动的火山,拥有无尽的动力和激情,矢志不渝种子般投身到技术研究和心得分享当中. 或许每一次的生长都是那么悄无声息,但是无数次的坚持只是为了破土那日

Echarts生成饼状图、条形图以及线形图 JS封装

1.在我们开发程序中,经常会用到生成一些报表,比方说饼状图,条形图,折线图等.不多说了,直接上封装好的代码,如下Echarts.js所示 以下代码是封装在Echarts.js文件中 /** * Created by Administrator on 2015/8/7. */ var charec; // 路径配置 require.config({ paths: { echarts: 'http://echarts.baidu.com/build/dist' } }); // 按需加载所需图表 r