实现核心
1.压缩饼图,使饼图有3D的效果,并不是真正的画了个3D圆柱
2.绘制厚度,带阴影效果,让看上去像是圆柱的高
3.路径添加好了,用颜色填充后绘制一下,添加阴影后还需绘制一遍
饼图添加阴影的思考
之前这加阴影的一段不是很明白,为啥设颜色和阴影都要draw一次
进过反复的测试,我自己分析了一下,每次draw一下想当于,把当前的设置画出来,再次draw就在这基础上,再画最近的设置,这里加颜色和阴影就像是一层一层的画上去。要是不draw的话,再设置颜色相当于重新设置了颜色,之前设置的颜色就无效了。同时要结合path使用,如果设置一场颜色draw一次,再设置颜色draw一次,后面设置的颜色是无用的。需要添加阴影的部分,需要用path路径绘制。
效果图
3D饼图的核心代码如下:
#import "SSSolidCakeView.h" @implementathtml" target="_blank">ion SSSolidCakeView #pragma mark 重写绘制方法 - (void)drawRect:(CGRect)rect { //第一步获得上下文 CGContextRef cakeContextRef = UIGraphicsGetCurrentContext(); //反锯齿,让图形边缘更加柔和(Sets whether or not to allow anti-aliasing for a graphics context.) CGContextSetAllowsAntialiasing(cakeContextRef, TRUE); //缩放坐标系的比例,通过设置y轴压缩,然后画代阴影的厚度,就画出了像是3D饼图的效果 CGContextScaleCTM(cakeContextRef, _xScale, _yScale); //饼图最先的起始角度 CGFloat startAngle =0; for (int i = 0; i<_dataArray.count; i++) { //画饼的横截面,上一部分完整的圆 //cake当前的角度 CGFloat currentAngle = [_dataArray[i] floatValue]; //结束的角度 CGFloat endAngle = startAngle + currentAngle; //每一块cake的起点,也就是圆心 CGContextMoveToPoint(cakeContextRef, _cakeCenter.x, _cakeCenter.y); //添加对应角度扇形 CGContextAddArc(cakeContextRef, _cakeCenter.x, _cakeCenter.y, _cakeRadius, startAngle*M_PI*2, endAngle*M_PI*2, 0); //得到对应的颜色 UIColor *currentColor = _colorArray[i]; //设置边界颜色 CGContextSetStrokeColorWithColor(cakeContextRef, currentColor.CGColor); //设置填充颜色 CGContextSetFillColorWithColor(cakeContextRef, currentColor.CGColor); //画子路径,这里就绘制还不是在画完厚度再绘制,是因为并不需要绘制所有cake的厚度,但是上一部分的圆是都要绘制的 CGContextDrawPath(cakeContextRef, kCGPathFill); //饼图上一部分圆,startAngle处的起点坐标 CGFloat upStartX = _cakeCenter.x+_cakeRadius*cos(startAngle*2*M_PI); CGFloat upStartY = _cakeCenter.y+_cakeRadius*sin(startAngle*2*M_PI); //饼图上一部分圆,endAngle处的终点坐标 CGFloat upEndX = _cakeCenter.x+_cakeRadius*cos(endAngle*2*M_PI); CGFloat upEndY = _cakeCenter.y+_cakeRadius*sin(endAngle*2*M_PI); //饼图厚度在角度结束处y坐标 CGFloat downEndY = upEndY + _cakeHeight; //画圆柱的侧面,饼图的厚度,圆柱的前半部分能看到,后半部分是看不到 //开始的角度如果>=M_PI,就会在圆柱的后面,侧面厚度就没必要画了 if (startAngle<0.5) { //绘制厚度 CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, nil, upStartX, upStartY); //当结束的角度>0.5*2*M_PI时,结束的角度该是M_PI的地方(视觉原因) if (endAngle>0.5) { //上部分的弧 CGPathAddArc(path, nil, _cakeCenter.x, _cakeCenter.y, _cakeRadius, startAngle*2*M_PI, M_PI, 0); //在角度结束的地方,上部分到下部分的直线 CGPathAddLineToPoint(path, nil, _cakeCenter.x-_cakeRadius, _cakeCenter.y+_cakeHeight); //下部分的弧 CGPathAddArc(path, nil, _cakeCenter.x, _cakeCenter.y + _cakeHeight, _cakeRadius, M_PI, startAngle*2*M_PI, 1); //在角度开始的地方,从下部分到上部分的直线 CGPathAddLineToPoint(path, nil, upStartX, upStartY); } else{ //上部分的弧 CGPathAddArc(path, nil, _cakeCenter.x, _cakeCenter.y, _cakeRadius, startAngle*2*M_PI, endAngle*2*M_PI, 0); //在角度结束的地方,上部分到下部分的直线 CGPathAddLineToPoint(path, nil, upEndX, downEndY); //下部分的弧 CGPathAddArc(path, nil, _cakeCenter.x, _cakeCenter.y + _cakeHeight, _cakeRadius, endAngle*2*M_PI, startAngle*2*M_PI, 1); //在角度开始的地方,从下部分到上部分的直线 CGPathAddLineToPoint(path, nil, upStartX, upStartY); } //之前这一段不是很明白,为啥设颜色和阴影都要draw一次 //我自己尝试并理解分析了一下,每次draw一下想当于,把当前的设置画出来,再次draw就在这基础上,再画当前的设置,这里加颜色和阴影就是一层一层的画上去。要是不draw的话,再设置颜色相当于重新设置了颜色,之前设置的颜色就无效了。 CGContextAddPath(cakeContextRef, path); CGContextDrawPath(cakeContextRef, kCGPathFill); //加阴影 [[UIColor colorWithWhite:0.2 alpha:0.4] setFill]; CGContextAddPath(cakeContextRef, path); CGContextDrawPath(cakeContextRef, kCGPathFill); } //最后一句,上一块的结束角度是下一块的开始角度 startAngle = endAngle; } //此时不能用以下的方法填充,会导致饼图就一种颜色 //CGContextFillPath(contextRef); } -(void)setDataArray:(NSArray *)dataArray { _dataArray = dataArray; //重新绘制 [self setNeedsDisplay]; }
这里要说明一下,我的数组是百分比数组,由数值转化为百分比的过程我没有在这里处理。
如何使用view:
self.solidCakeView = [[SSSolidCakeView alloc]init]; self.solidCakeView.dataArray = _dataArray; self.solidCakeView.colorArray = _colorArray; self.solidCakeView.nameArray = _nameArray; self.solidCakeView.cakeCenter = CGPointMake(200, 200); self.solidCakeView.cakeRadius = 100; self.solidCakeView.cakeHeight = 30; self.solidCakeView.xScale = 1; self.solidCakeView.yScale = 0.8; self.solidCakeView.backgroundColor = [UIColor whiteColor]; self.solidCakeView.frame = CGRectMake(0, 0, PhoneScreen_WIDTH-100, PhoneScreen_HEIGHT-20); [self.view addSubview:self.solidCakeView];
3D饼图如何绘制及使用已经用代码介绍完了,相信看到这大家应该也能实现3D饼图了。
本文参考了:http://blog.csdn.net/donny_zhang/article/details/9145379 感谢博主!
总结
以上就是这篇文章的全部内容了,希望本文的内容对各位iOS开发者们能有一定的帮助,如果有疑问大家可以留言交流。
本文向大家介绍extjs图形绘制之饼图实现方法分析,包括了extjs图形绘制之饼图实现方法分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了extjs图形绘制之饼图实现方法。分享给大家供大家参考,具体如下: 这篇文章将介绍extjs中自带的饼图。 代码如下: 注: 1.上面中的createStore是创建饼图所需要的数据的--store。 2.上面中的legend 显示的右边的图例(表明
Highcharts 3D图 以下实例演示了3D饼图。 我们在前面的章节已经了解了 Highcharts 基本配置语法。接下来让我们来看下其他的配置。 配置 chart.options3d 配置 以下列出了 3D 图的基本配置,设置 chart 的 type 属性为 pie,options3d 选项可设置三维效果。 var chart = { type: 'pie', options
我正试图用PDFbox绘制饼图,但各片之间有白线,有人能帮我吗?是否有此选项? 附上我正在使用的绘制圆弧的代码: 结果的附加图像: 谢啦
前端大佬们求助,这种图怎么弄出来啊 求教求教 ![Echarts 3D饼图] 在经历各种 百度 Google Ecahrts社区 及 各大博客 都没搞出来
本文向大家介绍python+matplotlib绘制饼图散点图实例代码,包括了python+matplotlib绘制饼图散点图实例代码的使用技巧和注意事项,需要的朋友参考一下 本文是从matplotlib官网上摘录下来的一个实例,实现的功能是Python+matplotlib绘制自定义饼图作为散点图的标记,具体如下。 首先看下演示效果 实例代码: 总结 以上就是本文关于python+matplot
本文向大家介绍asp.net实现C#绘制太极图的方法,包括了asp.net实现C#绘制太极图的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了asp.net实现C#绘制太极图的方法。分享给大家供大家参考。具体如下: 成品图如下所示: html页面: 注意设置: 后台代码: 希望本文所述对大家的C#程序设计有所帮助。