如何用两种不同的方法动态绘制饼状图

简介: 如何用两种不同的方法动态绘制饼状图

按照惯例先来交代故事背景,有人在问饼状图怎么动态来画?然后博主就在想,刚好最近一直在看动画的东西,虽然没直接画饼状图,但是通过属性调整,饼状图绘制起来也是妥妥的啊。于是综合前一阵子所学,用了以下两种方法来实现饼状图的绘制。首先,来看下效果图:

1.png

如有卡顿,请自行忽略,真机上是不会出现的。


第一种方法:使用CAShapeLayer,贝塞尔曲线和CABasicAnimation来画


原理:1.使用贝塞尔曲线决定绘制圆的路径和角度;

2.用CAShapeLayer来重合贝塞尔曲线的路径;

3.用基础动画来实现绘制的动态性。


1.使用贝塞尔曲线决定绘制圆的路径和角度

//用贝塞尔曲线来画扇形,实际上画的是圆,因为半径为边线中间到原点的距离,所以设置半径为线宽的一半,这样线宽就覆盖了中间填充部分的颜色,形成扇形。
UIBezierPath *bezierPath=[UIBezierPath bezierPathWithArcCenter:CGPointMake((self.view.frame.size.width)/2, (self.view.frame.size.height)/2) radius:60 startAngle:0 endAngle:M_PI/3*4 clockwise:YES];

2.用CAShapeLayer来重合贝塞尔曲线的路径

CAShapeLayer *shanxingLayer = [CAShapeLayer layer];
//这里设置填充线的宽度
shanxingLayer.lineWidth = 120;
//设置拐角样式
shanxingLayer.lineCap = kCALineCapButt;
//绘制的线的颜色
shanxingLayer.strokeColor = [[UIColor redColor] CGColor];
//填充色设置为nil是为了防止填充色混淆,因为这个本身实际上是画圆,第一步有解释
shanxingLayer.fillColor = nil;
//路径
shanxingLayer.path = bezierPath.CGPath;    [self.view.layer addSublayer:shanxingLayer];

3.用基础动画来实现绘制的动态性

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
//设置绘制动画持续的时间
animation.duration = 1;
//速度控制函数
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
//起始值
animation.fromValue = [NSNumber numberWithFloat:0.0f];
//结束值
animation.toValue = [NSNumber numberWithFloat:1.0f];
//是否翻转绘制
animation.autoreverses = NO;
//当前对象在非active时间段的行为
animation.fillMode = kCAFillModeForwards;
//重复次数
animation.repeatCount = 1;
[shanxingLayer addAnimation:animation forKey:@"strokeEnd"];
//表示绘制到百分比多少就停止,这个我们用1表示完全绘制
shanxingLayer.strokeEnd=1.0f;

到这里就可以完成饼状图(扇形)的动态绘制了。代码中有详细的注解,博主就不多说明了。


第二种方法:利用CAShapeLayer的strokeStart和strokeSEnd两个属性和定时器


原理:1.CAShapeLayer的strokeStart和strokeEnd两个属性,前面博客在画圆时有用到这俩属性,strokeStart是起始位置,为三点钟方向,strokeEnd为结束绘制点,为一绘制的百分比,把贝塞尔曲线的路径给它;

2.利用定时器动态的改变绘制的百分比。


1.CAShapeLayer的strokeStart和strokeEnd两个属性,前面博客在画圆时有用到这俩属性,strokeStart是起始位置,为三点钟方向,strokeEnd为结束绘制点,为一绘制的百分比,把贝塞尔曲线的路径给它

- (void)draw
{
    layer = [CAShapeLayer layer];
    //这里设置填充线的宽度,这个参数很重要
    layer.lineWidth = 120;
    //拐角设置
    layer.lineCap = kCALineCapButt;
    //绘制的线的颜色
    layer.strokeColor = [[UIColor redColor] CGColor];
    layer.fillColor = nil;
    layer.strokeStart=0;
    layer.strokeEnd=end/10;
    [self.view.layer addSublayer:layer];
    //用贝塞尔曲线来画扇形,实际上画的是圆,因为半径为边线中间到原点的距离,所以设置半径为线宽的一半,这样线宽就覆盖了中间填充部分的颜色,形成扇形
    UIBezierPath *bezierPath=[UIBezierPath bezierPathWithArcCenter:CGPointMake((self.view.frame.size.width)/2, (self.view.frame.size.height)/2) radius:60 startAngle:0 endAngle:M_PI/2*3 clockwise:YES];
    layer.path = bezierPath.CGPath;
}

2.利用定时器动态的改变绘制的百分比

- (void)updateLayer
{
    //起始点为0,结束点不断增加,圆的弧线越来越长,到结束点闭合就变成了圆,我们这里按贝斯阿尔曲线路径到结束点为一扇形
    if ( end < 10)
    {
        end ++;
    }
    else
    {
        [timer invalidate];
    }
    NSLog(@"----");
    layer.strokeEnd = end/10.0;
}

如果你对动画稍有了解,如果你看过博主的其它博文,那这里的代码对你来说小菜一碟,完全没有难度,如果是新手,因为代码从未接触过,你会觉得难,其实就好比你初次接触Object-C一样。

目录
相关文章
|
数据库 Python
matplotlib绘制饼图之基本配置——万能模板案例
matplotlib绘制饼图之基本配置——万能模板案例
448 0
matplotlib绘制饼图之基本配置——万能模板案例
|
3月前
|
数据可视化
R语言多图合成:优雅地在一个画布上展示多个图形
【8月更文挑战第30天】R语言提供了多种方法来实现多图合成,从基础的`par()`函数到高级的`gridExtra`、`ggplot2`和`cowplot`包,每种方法都有其独特的优势和应用场景。通过掌握这些技术,你可以根据实际需求灵活地组合图形,从而更高效地展示和解读数据。希望本文能为你提供一些有益的参考和启示。
|
2月前
|
JSON JavaScript Linux
绘图框架 plotly 知识点补充(绘制子图,图表保存)
绘图框架 plotly 知识点补充(绘制子图,图表保存)
58 13
|
6月前
|
编解码 数据可视化
R语言动态可视化:绘制历史全球平均温度的累积动态折线图动画gif视频图
R语言动态可视化:绘制历史全球平均温度的累积动态折线图动画gif视频图
|
6月前
|
数据可视化
Echarts5.3.2可视化案例-时间轴动态柱形图
Echarts5.3.2可视化案例-时间轴动态柱形图
|
6月前
|
Python
matplotlib绘制动态瀑布图
matplotlib绘制动态瀑布图
Echarts实战案例代码(48):堆叠图实现图形和坐标轴对齐的解决方案
Echarts实战案例代码(48):堆叠图实现图形和坐标轴对齐的解决方案
156 0
Echarts实战案例代码(9):图表纹理填充的解决方案(柱图为例)
Echarts实战案例代码(9):图表纹理填充的解决方案(柱图为例)
1495 0
Echarts实战案例代码(42):饼图不同区域的渐变实现的解决方案
Echarts实战案例代码(42):饼图不同区域的渐变实现的解决方案
277 0
|
XML 前端开发 数据可视化
【图形基础篇】03 # 声明式图形系统:如何用SVG图形元素绘制可视化图表?
【图形基础篇】03 # 声明式图形系统:如何用SVG图形元素绘制可视化图表?
126 0
【图形基础篇】03 # 声明式图形系统:如何用SVG图形元素绘制可视化图表?