IOS开发---绘制饼图

IOS绘制图形同其它绘制图形的方法相同,首先都需要创建图形上下文,之后push当前要绘制的上下文,设置颜色、阴影等等。。。

代码参考Muh Hon Cheng的PlotCreator的程序。

首先定义类ChartObject用来存储饼图上每个pie的信息

float value;存储当前pie的值

float startAngle;pie的开始的角度

float endAngle;pie的结束角度

NSString *title;  存储当前pie的标题

UIColor *color; 存储当前pie的颜色


ChartObject类具体代码如下:

@interface ChartObject : NSObject

{

    float value;

    float startAngle;

    float endAngle;

    NSString *title;

    UIColor *color;

}


@property (nonatomic, assign)float value, startAngle, endAngle;

@property (nonatomic, strong)NSString *title;

@property (nonatomic, strong)UIColor *color;


- (id)initWithTitle:(NSString*)_title value:(float)_value;

+ (id)pieComponentWithTitle:(NSString*)_title value:(float)_value;

@end


@implementation ChartObject

@synthesize value,startAngle,endAngle,title,color;


- (id)initWithTitle:(NSString *)_title value:(float)_value

{

    self = [super init];

    if (self) {

        self.title = _title;

        self.value = _value;

        self.color = PCColorDefault;

    }

    return self;

}


+ (id)pieComponentWithTitle:(NSString*)_title value:(float)_value

{

    return [[super alloc]initWithTitle:_title value:_value];

}


- (void)dealloc

{

    [title release];

    [color release];

    [super dealloc];

}


@end


下面定义用于显示的视图类ChartView

ChartView是具体的绘图类

绘图的例子如:

   CGContextRef ctx = UIGraphicsGetCurrentContext();

         UIGraphicsPushContext(ctx);         

         CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f);  

         CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), TOP_MARGIN);

         CGContextFillEllipseInRect(ctx, CGRectMake(x, y, diameter, diameter));

         UIGraphicsPopContext();   

在ChartView类用变量数组存储饼图的信息,数组中的每一项为ChartObject类

ChartObject类中的title和value可以在初始化时定义,开始的角度和结束的角度在ChartView中赋值。 

具体计算方法看代码的注释。

代码如下:

@interface ChartView : UIView           //显示信息的页面

#define TOP_MARGIN 15             //阴影的宽度

#define LABEL_TOP_MARGIN 15

{

    NSMutableArray *chartObjectsArray;

    int diameter;                           //直径

}

@property (strong, nonatomic)NSMutableArray *chartObjectsArray;

@property (assign, nonatomic)int diameter;

@end


@implementation ChartView

@synthesize chartObjectsArray;

@synthesize diameter;

- (id)init

{

    self = [super init];

    if (self) {

        chartObjectsArray = [[NSMutableArray alloc]initWithCapacity:0];

        [self setBackgroundColor:[UIColor clearColor]];

    }

    return self;

}


- (void)drawRect:(CGRect)rect       //UIView drawRect 方法

{

    if (self.diameter == 0) {

        diameter = MIN(rect.size.width, rect.size.height) - 2*TOP_MARGIN;

    }

    NSLog(@"diameter = %d",diameter);

    float gap = 1;          //边缘线宽度

    

    float x = (rect.size.width - diameter)/2;       

    float y = (rect.size.height - diameter)/2//圆所在矩形的起始点

    NSLog(@"x = %f,y = %f",x,y);

    float inner_radius = diameter/2;        //半径

    float origin_x = x + diameter/2;

    float origin_y = y + diameter/2;        //rect的中心点origin_xorigin_y

    NSLog(@"origin_x = %f,origin_y = %f",origin_x,origin_y);

    // label stuff

    //float left_label_y = LABEL_TOP_MARGIN;

    //float right_label_y = LABEL_TOP_MARGIN;//左右标题方块的阴影

     if ([chartObjectsArray count]>0)

     {

         float total = 0;

         for (ChartObject *component in chartObjectsArray)

         {

             total += component.value;

         }//total为计算后总的值

         

         /*-----------------------------------画阴影画圆-----------------------------------*/

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         UIGraphicsPushContext(ctx);         //获取图像上下文

         CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f);  // white color

         CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), TOP_MARGIN);//TOP_MARGIN阴影的宽度

         CGContextFillEllipseInRect(ctx, CGRectMake(x, y, diameter, diameter));//画白圆

         UIGraphicsPopContext();             //pop图像上下文

         /*-----------------------------------画阴影画圆-----------------------------------*/

         

         float nextStartDeg = 0;        //当前项目开始的角度

         float endDeg = 0;              //当前项目结束的角度

         for (int i=0; i<[chartObjectsArray count]; i++)   

         {

             /*-----------------------------------画饼图-----------------------------------*/

             ChartObject *component  = [chartObjectsArray objectAtIndex:i];

             float perc = [component value]/total;   //当前项目占总项目的百分比

             endDeg = nextStartDeg+perc*360;     //计算结束的角度值

             CGContextSetFillColorWithColor(ctx, [component.color CGColor]);//设置填充的颜色

             CGContextMoveToPoint(ctx, origin_x, origin_y);  //将上下文移动到起始点

             CGContextAddArc(ctx, origin_x, origin_y, inner_radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0);    //画扇型       1顺时针,0逆时针

             CGContextClosePath(ctx); //关闭上下文

             CGContextFillPath(ctx);  //填充视图

             CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1);

             [component setStartAngle:nextStartDeg];

             [component setEndAngle:endDeg];

             /*-----------------------------------画饼图-----------------------------------*/

             

             /*-----------------------------------画边缘线----------------------------------*/

             CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1);   //设置上下文为黑色

             CGContextSetLineWidth(ctx, gap);               //设置要画的线的宽度

             CGContextMoveToPoint(ctx, origin_x, origin_y); //将环境上下文移动到圆心

             CGContextAddArc(ctx, origin_x, origin_y, inner_radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0);                        //沿边缘画线

             CGContextClosePath(ctx);

             CGContextStrokePath(ctx);

             /*-----------------------------------画边缘线----------------------------------*/


             /*------------------------------------标签-----------------------------------*/

             

             /*

             NSInteger O_x,O_y,E_x,E_y = 0;        //原点为origin_x,origin_y;半径长度为inner_radius;

             UIFont *font =[UIFont fontWithName:@"GeezaPro" size:10];

             if (nextStartDeg >= 180 || (nextStartDeg < 180 && endDeg > 270))   //当扇形为左面时

             {

                 NSString *percentageText = [NSString stringWithFormat:@"%@\n%.1f%%",component.title,component.value/total*100];//当前项目占总项目的百分比

                 NSLog(@"stratplace = %f,endplace = %f",nextStartDeg,endDeg);

                 NSLog(@"percent = %@",percentageText);

                

                 if (endDeg > 270 && nextStartDeg < 180)    //二三四象限

                 {

                     double o = 90+endDeg-360;

                     O_x = origin_x - 2*cos(2*M_PI*o/360)*inner_radius;

                     O_y = origin_y - sin(2*M_PI*o/360)*inner_radius;

                     E_x = origin_x - cos(2*M_PI*o/360)*inner_radius;

                     E_y = origin_y + sin(2*M_PI*o/360)*inner_radius;

                     

                 }

                 else  //nextStartDeg >=180

                 {

                     if (endDeg <= 270) //第三象限

                     {

                         double o = 270 - endDeg;

                         double p = nextStartDeg - 180;

                         double des = abs((origin_x - cos(2*M_PI*o/360)*inner_radius) - (origin_x - sin(2*M_PI*p/360)*inner_radius));

                         O_x = origin_x - cos(2*M_PI*o/360)*inner_radius - des - 30; //(30)

                         O_y = origin_y + sin(2*M_PI*o/360)*inner_radius;

                         E_x = origin_x - sin(2*M_PI*p/360)*inner_radius;

                         E_y = origin_y + cos(2*M_PI*p/360)*inner_radius;   // (30)

                     }

                     else       

                     {

                         if (nextStartDeg >= 270)//第四象限

                         {

                             double o = 360 - endDeg;

                             double p = nextStartDeg - 270;

                             double des = abs((origin_x - cos(2*M_PI*p/360)*inner_radius) - (origin_x - sin(2*M_PI*o/360)*inner_radius));

                             O_x = origin_x - cos(2*M_PI*p/360)*inner_radius - des;

                             O_y = origin_y - cos(2*M_PI*o/360)*inner_radius - 30;//(30)

                             E_x = origin_x - sin(2*M_PI*o/360)*inner_radius;

                             E_y = origin_y - sin(2*M_PI*p/360)*inner_radius - 30;//(30)

                         }

                         else   //三四象限

                         {

                             double o = nextStartDeg - 180;

                             double p = endDeg - 270;

                             if (sin(2*M_PI*o/360)*inner_radius == cos(2*M_PI*p/360)*inner_radius)//x相等时

                             {

                                 O_x = origin_x - sin(2*M_PI*o/360)*inner_radius - 40 - 30; //(30)

                                 E_x = origin_x - sin(2*M_PI*o/360)*inner_radius - 30;  //(30)

                             }

                             else

                             {

                                 double des = abs((origin_x - sin(2*M_PI*o/360)*inner_radius) - (origin_x - cos(2*M_PI*p/360)*inner_radius));

                                 NSLog(@"des = %f",des);

                                 O_x = MIN((origin_x - sin(2*M_PI*o/360)*inner_radius),(origin_x - cos(2*M_PI*p/360)*inner_radius)) -des - 30;  //(30)

                                 E_x = MAX((origin_x - sin(2*M_PI*o/360)*inner_radius),(origin_x - cos(2*M_PI*p/360)*inner_radius)) - 30; //(30)

                             }

                             O_y = origin_y - sin(2*M_PI*p/360)*inner_radius;

                             E_y = origin_y + cos(2*M_PI*o/360)*inner_radius;

                         }

                     }

                 }

                    CGContextSetFillColorWithColor(ctx, [component.color CGColor]);

                 CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), 2);

                 CGRect percFrame = CGRectMake(O_x,O_y,E_x,E_y);//设置方块

                 NSLog(@"ox = %f,oy = %f,ex = %f,ey = %f",percFrame.origin.x,percFrame.origin.y,percFrame.size.width,percFrame.size.height);

                 [percentageText drawInRect:percFrame withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight];

             }

             else           //当扇形为右面时

             {

                 NSString *percentageText = [NSString stringWithFormat:@"%.1f%%",component.value/total*100];//当前项目占总项目的百分比

                 NSLog(@"stratplace = %f,endplace = %f",nextStartDeg,endDeg);

                 NSLog(@"percent = %@",percentageText);

                   //( >= 180 || 0~180 )

                 if ((endDeg - nextStartDeg) >= 180)    //角度大于等于180

                 {

                     

                 }

                 else   //角度小于180

                 {

                     

                 }

                

             }

             */

             /*------------------------------------标签-----------------------------------*/

             nextStartDeg = endDeg;

         }

     }

    customTableView *itemTableView = [[customTableView alloc]initWithFrame:CGRectMake(origin_x +diameter, origin_y-inner_radius, 200, 500) style:UITableViewStylePlain];

    float total=0;

    for (ChartObject *component in chartObjectsArray)

    {

        total += component.value;

    }//total为计算后总的值

    [itemTableView setTableitemsArray:chartObjectsArray];

    [itemTableView setTot

    [self addSubview:itemTableView];

}


- (void)dealloc

{

    [chartObjectsArray removeAllObjects];

    [chartObjectsArray release];

    [super dealloc];

}

@end

在绘制标签时想过用三角函数计算该显示的矩形位置,但是可能计算失误,本人比较懒,懒得细究就用个tableview显示了,有兴趣的朋友,和有更好方法的朋友请指教小弟一二,小弟在此感激不禁。

文章中如有错误之处,请大家多多批评。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值