zoukankan      html  css  js  c++  java
  • iOS绘制收益柱状图

     项目需求,参考了其他绘图demo,自己绘制出来了,不过代码改得有点乱,添加了很多变量,时间关系没用太合适的命名,逻辑处理也没进行优化。

    看看效果图(虚线区域都是画的,其他区域添加的都是控件),附上源码


     

     

    #import <UIKit/UIKit.h>

     

    typedef enum : NSUInteger {

        CSYieldTypeWeek = 0,    //周收益

        CSYieldTypeMonth = 1,   //月收益

        CSYieldTypeYear = 2,    //年收益

    } CSYieldType;  //收益类型

     

    typedef enum : NSUInteger {

        CSTimePointJanuary  = 0,         //一月份

        CSTimePointFebruary,

        CSTimePointMarch,

        CSTimePointApril,

        CSTimePointMay,             //.

        CSTimePointJun,             //.

        CSTimePointJuly,            //.

        CSTimePointAugust,

        CSTimePointSeptember,

        CSTimePointOctober,

        CSTimePointNovember,

        CSTimePointDecember,        //十二月份

        CSTimePointThisWeek,    //本周

        CSTimePointLastWeek,        //上周

        

    } CSTimePoint;

     

    @interface CSYieldChartView : UIView

    @property (nonatomic,assign)CSYieldType yieldType; //收益类型

    @property (nonatomic,assign)CSTimePoint timePoint;  //时间点

    @property (nonatomic,strong) NSArray *yields; //收益数组

    @property (nonatomic,strong) NSArray *dayPoints;   //时间点数组

     

    //刷新图表

    - (void)refreshChartWithYields:(NSArray *)yields dayPoints:(NSArray *)dayPoints yieldType:(CSYieldType)yieldType timePoint:(CSTimePoint)timePoint;

     

    @end

     

     

    #define yieldLineSpace 4

     

    #define lineLeftMargin 40

    #define lineRightMargin 10

    #define lineTopMargin 10

    #define lineBottomMargin 30

     

    #define lineWidth 0.5f

     

    #define itemLeftMargin 16

    #define itemRightMargin 16

    #define itemSpace 6

    #define itemWidthRatio (5/12.f)

     

    #define positiveItemHexColor 0xe83846   //正收益条颜色值

    #define negativeItemHexColor 0x17c7ba   //负收益条颜色值

     

    #import "CSYieldChartView.h"

    #import "UIColor+Addition.h"

    @implementation CSYieldChartView

     

    -(void)refreshChartWithYields:(NSArray *)yields dayPoints:(NSArray *)dayPoints yieldType:(CSYieldType)yieldType timePoint:(CSTimePoint)timePoint

    {

        self.yields = yields;

        self.dayPoints = dayPoints;

        self.yieldType = yieldType;

        self.timePoint = timePoint;

        

        [self setNeedsDisplay];

    }

    - (void)drawRect:(CGRect)rect

    {

        

        //声明最大的收益

        float maxYield = 0;

        

        //获取最大的收益绝对值

        for (NSNumber *number in _yields) {

            if (maxYield < fabs([number floatValue])) {

                maxYield = fabs([number floatValue]);

            }

        }

        

        //若最大收益少于10,则将最大值设为10

        if (maxYield < 10.0) {

            maxYield = 10.0;

        }

        

        //分几段

        NSInteger sectionNum = 2;

        

        //平均每段的收益

        CGFloat sectionYield = maxYield / 2;

        

        UIColor *currentColor = [UIColor lightGrayColor];

        

        CGContextRef contextRef = UIGraphicsGetCurrentContext();

        CGContextBeginPath(contextRef);

        CGContextSetLineWidth(contextRef, lineWidth); //设置线粗

        

        CGContextSetStrokeColorWithColor(contextRef, currentColor.CGColor);   //设置画笔颜色

        

        //中线的y坐标

        CGFloat centerLineY = (self.frame.size.height - lineTopMargin - lineBottomMargin)/2.f + lineTopMargin;

        

        //设置段落风格

        NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];

        paragraph.alignment = NSTextAlignmentRight;

        //设置字体颜色

        UIColor *textColor = [UIColor lightGrayColor];

        //设置字体大小

        UIFont *textFont = [UIFont systemFontOfSize:10];

        

        //0收益中线

        CGContextMoveToPoint(contextRef, lineLeftMargin, centerLineY);

        CGContextAddLineToPoint(contextRef, self.frame.size.width - lineRightMargin, centerLineY);

        CGContextStrokePath(contextRef);

        

        //0收益率

        [@"0%" drawInRect:CGRectMake(0, centerLineY - 7, lineLeftMargin - yieldLineSpace, lineLeftMargin) withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

        

        //线与线的垂直距离

        CGFloat lineSpace = (self.frame.size.height - lineTopMargin - lineBottomMargin) / 4.f;

        

        for (int i = 0; i < sectionNum; i++) {

            CGFloat topLineY = centerLineY - lineSpace * (i + 1);

            CGFloat bottomLineY = centerLineY + lineSpace * (i + 1);

            

            //虚线 线宽与空格宽

            CGFloat dashes[] = {2,1};

            CGContextSetLineDash(contextRef, 0.0, dashes, 2);

            

            CGContextSetStrokeColorWithColor(contextRef, currentColor.CGColor);   //设置画笔颜色

     

            //中线以上

            CGContextMoveToPoint(contextRef, lineLeftMargin, topLineY);

            CGContextAddLineToPoint(contextRef, self.frame.size.width - lineRightMargin, topLineY);

            CGContextStrokePath(contextRef);

            

            //收益率

            [[NSString stringWithFormat:@"%.f%%",sectionYield * (i + 1)] drawInRect:CGRectMake(0, topLineY - 7, lineLeftMargin - yieldLineSpace, lineLeftMargin) withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

     

            CGContextSetStrokeColorWithColor(contextRef, currentColor.CGColor);   //设置画笔颜色

            

            //中线以下

            CGContextMoveToPoint(contextRef, lineLeftMargin, bottomLineY);

            CGContextAddLineToPoint(contextRef, self.frame.size.width - lineRightMargin, bottomLineY);

            CGContextStrokePath(contextRef);

            

            //负收益率

            [[NSString stringWithFormat:@"-%.f%%",sectionYield * (i + 1)] drawInRect:CGRectMake(0, bottomLineY - 7, lineLeftMargin - yieldLineSpace, lineLeftMargin) withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

        }

        

        if (0 == _yields.count) {

            paragraph.alignment = NSTextAlignmentCenter;

            

            NSDictionary *attributes = @{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:[UIFont systemFontOfSize:40]};

            

            CGSize textSize = [@"暂无数据" sizeWithAttributes:attributes];

            

            [@"暂无数据" drawInRect:CGRectMake(lineLeftMargin + itemLeftMargin,centerLineY - textSize.height / 2.f,self.width - lineLeftMargin - itemLeftMargin - lineRightMargin - itemRightMargin,textSize.height) withAttributes:attributes];

            

            return;

        }

        

        

        NSString *lastDay = [_dayPoints lastObject];

        

        //最多有几个柱(如果是月收益,且收益数小于22,按22算,否则按收益数多少算)

        NSInteger partNum = (_yields.count < 22 && _yieldType == CSYieldTypeMonth) ? 22 : _yields.count;

        

        paragraph.alignment = NSTextAlignmentLeft;

        

        //绘制柱状图

        CGFloat averageSpace = (self.frame.size.width - lineLeftMargin - itemLeftMargin - lineRightMargin - itemRightMargin) / (partNum - 1);

        

        //柱宽

        CGFloat itemWidth = averageSpace * itemWidthRatio;

        

        for (int i=0; i<partNum; i++) {

            

            if (i > _yields.count - 1//后面暂时还没收益就不画柱状条

            {

                break;

            }

            

            if (i % 5 == 0) {

                //绘制日期

                NSString *dayStr = nil;

                if (self.yieldType == CSYieldTypeMonth && 0 == i) {

                    dayStr = [NSString stringWithFormat:@"%@()",_dayPoints[0]];

                }

                else

                {

                    dayStr = [NSString stringWithFormat:@"%@",_dayPoints[i]];

                }

                [dayStr drawInRect:CGRectMake(lineLeftMargin + itemLeftMargin - 5 + averageSpace * i, self.frame.size.height - (lineBottomMargin - 6), 50, 15)withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

            }

            else if (i == _yields.count - 1)    //最后一个柱状图日期

            {

                [[NSString stringWithFormat:@"%@",lastDay]  drawInRect:CGRectMake(lineLeftMargin + itemLeftMargin - 5 + averageSpace * i, self.frame.size.height - (lineBottomMargin - 6), 50, 15)withAttributes:@{NSParagraphStyleAttributeName:paragraph,NSForegroundColorAttributeName:textColor,NSFontAttributeName:textFont}];

            }

            

            //绘制柱状图

            float yield = [_yields[i] floatValue];

            

            

            float radius = itemWidth/2.f;   //柱状末尾的半圆半径

            

            //虚线 线宽与空格宽 (之前设了虚线,现在把虚线的间隙变为0

            CGFloat dashes[] = {1,0};

            CGContextSetLineDash(contextRef, 0.0, dashes, 2);

            

            

            CGFloat itemX = lineLeftMargin + itemLeftMargin + averageSpace * i - itemWidth/2.f;

            CGFloat itemY = centerLineY - (lineSpace * sectionNum) * yield / maxYield;

            

            

            //是否要画半圆(如果收益高度低于宽度,就不画半圆)

            BOOL shouldDrawCircle = (fabs(itemY - centerLineY) > itemWidth/2.f) ? YES : NO;

            

            if (yield >= 0) {

                

                if (shouldDrawCircle) {

                    itemY += radius;

                }

                

                //正收益颜色

                CGContextSetStrokeColorWithColor(contextRef, [UIColor colorWithHex:positiveItemHexColor].CGColor);

                CGContextSetFillColorWithColor(contextRef, [UIColor colorWithHex:positiveItemHexColor].CGColor);

            }

            else

            {

                

                if (shouldDrawCircle) {

                    itemY -= radius;

                }

                

                //负收益颜色

                CGContextSetStrokeColorWithColor(contextRef, [UIColor colorWithHex:negativeItemHexColor].CGColor);

                CGContextSetFillColorWithColor(contextRef, [UIColor colorWithHex:negativeItemHexColor].CGColor);

            }

            

            

    //        CGContextSetShadow(contextRef,CGSizeMake(2, 0) , 2);  //阴影效果

            

            CGMutablePathRef pathRef = CGPathCreateMutable();

            CGPathMoveToPoint(pathRef, NULL, itemX, centerLineY);

            CGPathAddLineToPoint(pathRef, NULL, itemX, itemY);

            CGPathAddLineToPoint(pathRef, NULL, itemX + itemWidth, itemY);

            CGPathAddLineToPoint(pathRef, NULL, itemX + itemWidth, centerLineY);

            CGPathCloseSubpath(pathRef);

            CGContextAddPath(contextRef, pathRef);

            CGContextFillPath(contextRef);

            CGContextAddPath(contextRef, pathRef);

            CGContextStrokePath(contextRef);

            

            

            if (shouldDrawCircle) {

                //画线末圆角

                CGPathMoveToPoint(pathRef, NULL, itemX + itemWidth/2.f, itemY);

                if (yield >= 0) {

                    CGPathAddArc(pathRef, NULL, itemX + itemWidth/2.f, itemY, itemWidth/2.f, M_PI, 0, NO);

                }

                else

                {

                    CGPathAddArc(pathRef, NULL, itemX + itemWidth/2.f, itemY, itemWidth/2.f, 0, M_PI, NO);

                }

                CGPathCloseSubpath(pathRef);

                CGContextAddPath(contextRef, pathRef);

                CGContextFillPath(contextRef);

                CGContextAddPath(contextRef, pathRef);

                CGContextStrokePath(contextRef);

            }

        }

    }

     @end

  • 相关阅读:
    欧拉函数(线性筛)(超好Dong)
    欧拉函数(线性筛)(超好Dong)
    线性素数筛(欧拉筛)(超级好的MuBan)
    线性素数筛(欧拉筛)(超级好的MuBan)
    Fire Game (FZU 2150)(BFS)
    Fire Game (FZU 2150)(BFS)
    Fantasy of a Summation (LightOJ
    Java——接口
    Java——异常处理
    Java——数组
  • 原文地址:https://www.cnblogs.com/hcsaaron/p/4454104.html
Copyright © 2011-2022 走看看