柱状图

来源:互联网 发布:小米手机网络信号差 编辑:程序博客网 时间:2024/04/29 09:01

由于一个项目的需求,需要写一个柱状图,在网上看了不少demo,最后用了一个比较简单易懂的demo模板,对于初学者很有帮助,现在我把这个demo贴出来,供大家学习。如有侵权,请联系博主,立即删掉。

封装一个BarChartView

  • BarChartView.h
@property(nonatomic,strong) NSArray *dataResource;- (UIColor *)colorWithIndex:(int)index;
  • BarChartView.m
    1、 宏定义柱状图的刻度线宽度、条数、间距、左右距、条状图宽
#define BarChartBoxH self.frame.size.height / 7#define BarChartBoxW (self.frame.size.width - BarChartRightSpacing - BarChartLeftSpacing) / 5//间距#define BarChartLeftSpacing  40*ADAPTER_WIDTH//条形图左距#define BarChartRightSpacing 25*ADAPTER_WIDTH//条形图右距#define barChartColumnW 12*ADAPTER_WIDTH//条形图列宽

注意,算间距和宽度需按照自己的数据源而定

2、延展

@interface BarChartView()@property(nonatomic,strong) NSMutableArray *yArr;//y轴刻度@property(nonatomic,copy) NSString *yUnit;@property(nonatomic, assign) int level;@property(nonatomic, copy) NSString *type;@end

3、Getter、Setter方法、初始化方法

-(instancetype)initWithFrame:(CGRect)frame{    if(self = [super initWithFrame:frame]){        self.backgroundColor = [UIColor whiteColor];    }    return self;}-(NSMutableArray *)yArr{    if(!_yArr){        _yArr = [NSMutableArray array];    }    return _yArr;}-(void)setDataResource:(NSArray *)dataResource{    _dataResource = dataResource;    self.yUnit = @"(元)";    [self getYDataArrWithDataResource:_dataResource];//获取y轴上的值}

4、根据数据源得到y轴刻度,由数据源中最大的值决定y轴的数值单位

-(void)getYDataArrWithDataResource:(NSArray *)dataResource{    CGFloat maxValue = [self maxValueWithDataResource:dataResource];//获取最大值    [self getUnitWithMaxValue:maxValue];//获取刻度值}-(CGFloat)maxValueWithDataResource:(NSArray *)dataResource{    //获取最大值    NSDictionary *dic = self.dataResource[0];    CGFloat maxValue = [dic[@"money"] floatValue];    for(int i = 1 ; i < dataResource.count ; i++){        NSDictionary *dic = self.dataResource[i];        CGFloat compareValue = [dic[@"money"] floatValue];        if(maxValue < compareValue){            maxValue = compareValue;        }    }    return maxValue;}-(void)getUnitWithMaxValue:(int )maxValue{    int unitNum = 0;    int tempValue = 1;    for(int i = 0 ; true ; i++){        tempValue *= 10;        if((maxValue / tempValue) == 0){            unitNum = i + 1;            break;        }    }    if((maxValue / (int)pow(10, unitNum - 1)) < 5){        self.type = @"f";        switch (unitNum) {            case 1://个 上限十            case 2://十                //以元位单位 上限五十                self.level = 1;                [self.yArr addObjectsFromArray:@[@"0",@"10",@"20",@"30",@"40",@"50"]];                self.yUnit = @"(元)";                break;            case 3: //百   上限五百                self.level = 10;                self.yUnit = @"(十)";                [self.yArr addObjectsFromArray:@[@"0",@"10",@"20",@"30",@"40",@"50"]];                break;            case 4://以百为单位 10,00  上限五千                self.level = 100;                self.yUnit = @"(百)";                [self.yArr addObjectsFromArray:@[@"0",@"10",@"20",@"30",@"40",@"50"]];                break;            case 5://以千为单位 10,000  上限五万                self.level = 1000;                self.yUnit = @"(千)";                [self.yArr addObjectsFromArray:@[@"0",@"10",@"20",@"30",@"40",@"50"]];                break;            case 6://以万为单位 10,0000 上限五十万                self.level = 10000;                self.yUnit = @"(万)";                [self.yArr addObjectsFromArray:@[@"0",@"10",@"20",@"30",@"40",@"50"]];                break;            case 7://以十万为单位 10,00000  上限制五百万                self.level = 100000;                self.yUnit = @"(十万)";                [self.yArr addObjectsFromArray:@[@"0",@"10",@"20",@"30",@"40",@"50"]];                break;            case 8://以百万为单位 10,000000 上限制五千万                self.level = 1000000;                self.yUnit = @"(百万)";                [self.yArr addObjectsFromArray:@[@"0",@"10",@"20",@"30",@"40",@"50"]];                break;            case 9://以百万为单位 10,000000 上限制五亿                self.level = 1000000;                self.yUnit = @"(千万)";                [self.yArr addObjectsFromArray:@[@"0",@"10",@"20",@"30",@"40",@"50"]];                break;            default:                break;        }    }else{        self.type = @"l";        switch (unitNum) {            case 1://个 上限十            case 2://十                //以元位单位 上限百                self.level = 1;                [self.yArr addObjectsFromArray:@[@"0",@"20",@"40",@"60",@"80",@"100"]];                self.yUnit = @"(元)";                break;            case 3: //百   上限千                self.level = 10;                self.yUnit = @"(十)";                [self.yArr addObjectsFromArray:@[@"0",@"20",@"40",@"60",@"80",@"100"]];                break;            case 4://以百为单位 10,00  上限万                self.level =  100;                self.yUnit = @"(百)";                [self.yArr addObjectsFromArray:@[@"0",@"20",@"40",@"60",@"80",@"100"]];                break;            case 5://以千为单位 10,000  上限十万                self.level = 1000;                self.yUnit = @"(千)";                [self.yArr addObjectsFromArray:@[@"0",@"20",@"40",@"60",@"80",@"100"]];                break;            case 6://以万为单位 10,0000 上限百万                self.level = 10000;                self.yUnit = @"(万)";                [self.yArr addObjectsFromArray:@[@"0",@"20",@"40",@"60",@"80",@"100"]];                break;            case 7://以十万为单位 10,00000  上限制千万                self.level = 100000;                self.yUnit = @"(十万)";                [self.yArr addObjectsFromArray:@[@"0",@"20",@"40",@"60",@"80",@"100"]];                break;            case 8://以百万为单位 10,000000 上限制亿                self.level = 1000000;                self.yUnit = @"(百万)";                [self.yArr addObjectsFromArray:@[@"0",@"20",@"40",@"60",@"80",@"100"]];                break;            case 9://以百万为单位 10,000000 上限制十亿                self.level = 1000000;                self.yUnit = @"(千万)";                [self.yArr addObjectsFromArray:@[@"0",@"10",@"20",@"30",@"40",@"50"]];                break;            default:                break;        }    }}

5、绘制柱状图

-(void)drawRect:(CGRect)rect{    //创建画布    CGContextRef ctr = UIGraphicsGetCurrentContext();    NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];    paragraph.alignment = NSTextAlignmentRight;    NSDictionary *attribute = @{NSFontAttributeName:[UIFont systemFontOfSize:12],NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:[UIColor colorWithRed:187.0/255.0 green:187.0/255.0 blue:187.0/255.0 alpha:1.0]};    [self.yUnit drawInRect:CGRectMake(2*ADAPTER_WIDTH,  BarChartBoxH - 22*ADAPTER_HEIGHT, BarChartLeftSpacing - 4*ADAPTER_WIDTH, 22*ADAPTER_HEIGHT) withAttributes:attribute];    //绘制区域轴    for (int i = 0 ; i < 6 ; i++) {//横线        [[UIColor colorWithRed:187.0/255.0 green:187.0/255.0 blue:187.0/255.0 alpha:1.0]set];        CGContextSetLineWidth(ctr, 0.5);        CGContextMoveToPoint(ctr, BarChartLeftSpacing, BarChartBoxH * (i + 1));        CGContextAddLineToPoint(ctr, self.frame.size.width - BarChartRightSpacing, BarChartBoxH * (i + 1));        CGContextStrokePath(ctr);        //绘制y轴刻度        [self.yArr[5 - i] drawInRect:CGRectMake(8, BarChartBoxH * (i + 1) - 7, BarChartLeftSpacing - 10, 22) withAttributes:attribute];    }    //绘制x轴    for (int i = 0 ; i < 6 ; i++) {//x轴刻度线        CGContextSetLineWidth(ctr, 0.5);        [[UIColor colorWithRed:187.0/255.0 green:187.0/255.0 blue:187.0/255.0 alpha:1.0]set];        CGContextMoveToPoint(ctr, BarChartLeftSpacing + i * BarChartBoxW, BarChartBoxH * 6);        CGContextAddLineToPoint(ctr, BarChartLeftSpacing + i * BarChartBoxW, BarChartBoxH * 6 + 3);        CGContextStrokePath(ctr);    }    for (int i = 0 ; i < 5 ; i++) {        //绘制X轴坐标        NSDictionary *dataDic = self.dataResource[i];        NSString *monthStr = dataDic[@"classification"];        NSString *moneyStr = dataDic[@"money"];        CGFloat num = [moneyStr floatValue] / self.level;        CGFloat scale = 0.0;        if([self.type isEqualToString:@"f"]){            scale = num / 50;        }else{            scale =  num / 100;;        }        [self drawMyRectWithCornerX:BarChartLeftSpacing + BarChartBoxW * (i + 0.5) - barChartColumnW * 0.5 andY:BarChartBoxH * 6 andRadius:barChartColumnW / 2 andWidth:barChartColumnW andHeight:- 5 * scale * BarChartBoxH andCtr:ctr andColor:[self colorWithIndex:i]];        //绘制柱子        NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];        paragraph.alignment = NSTextAlignmentCenter;        NSDictionary *attribute = @{NSFontAttributeName:[UIFont systemFontOfSize:12],NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:[UIColor colorWithRed:187.0/255.0 green:187.0/255.0 blue:187.0/255.0 alpha:1.0]};        [monthStr drawInRect:CGRectMake(BarChartLeftSpacing + BarChartBoxW * i, BarChartBoxH * 6 + 5 , BarChartBoxW, 22) withAttributes:attribute];    }   }//每条柱子的颜色-(UIColor *)colorWithIndex:(int)index{    UIColor *color;    switch (index) {        case 0:            color = [UIColor colorWithRed:252/255.0 green:90/255.0 blue:133/255.0 alpha:1.0];            break;        case 1:            color = [UIColor colorWithRed:254/255.0 green:215/255.0 blue:210/255.0 alpha:1.0];            break;        case 2:            color = [UIColor colorWithRed:254/255.0 green:198/255.0 blue:76/255.0 alpha:1.0];            break;        case 3:            color = [UIColor colorWithRed:57/255.0 green:58/255.0 blue:58/255.0 alpha:1.0];            break;        case 4:            color = [UIColor colorWithRed:93/255.0 green:171/255.0 blue:127/255.0 alpha:1.0];            break;        default:            break;    }    return color;}/** *  绘制圆弧矩形 * *  @param x      起始点的横坐标 *  @param y      起始点的纵坐标 *  @param radius 圆角弧形的半径 *  @param width  矩形的宽度 *  @param height 矩形的高度 *  @param ctr    绘图上下文 *  @param color  背景颜色 */- (void)drawMyRectWithCornerX:(CGFloat)x andY:(CGFloat)y andRadius:(CGFloat)radius andWidth:(CGFloat)width andHeight:(CGFloat)height andCtr:(CGContextRef)ctr andColor:(UIColor *)color{    [color set];    CGContextMoveToPoint(ctr, x, y);    if(radius > fabs(height)){        CGContextAddArc(ctr, x, y, fabs(height), M_PI * 2, M_PI, 1);    }else{        CGContextAddLineToPoint(ctr, x, y - fabs(height) + radius);        CGContextAddArc(ctr, x + width / 2, y - fabs(height) + radius, radius, - M_PI , 0, 0);        CGContextAddLineToPoint(ctr, x + width,  y - fabs(height) + radius);        CGContextAddLineToPoint(ctr, x + width, y);        CGContextAddLineToPoint(ctr, x, y);    }    CGContextFillPath(ctr);}

博主现在还在研究柱状图的动画,之后效果出来会一起po出来滴~~~

0 0