美文网首页
iOS自定义雷达图

iOS自定义雷达图

作者: __May__ | 来源:发表于2018-11-02 15:58 被阅读0次

    因为工作需要雷达图,有很多开源的也很好,但是代码太多了,太杂,只需要雷达图,所以就自己定义了 可设置多个边如图

    使用方式

     BJRadarMapHelp *help = [[BJRadarMapHelp alloc]init];

        help.size = CGSizeMake(self.view.frame.size.width -100*KWidthRate, self.view.frame.size.width -100*KWidthRate);

        help.count= array.count>1?array.count:6;//设置顶点个数

        self.radarview.helper = help;

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            [self.radarview setValueArray:array];

        });


    代码如下 .h  这里添加了一个辅助类来设置各种属性数据

    @interfaceBJRadarMapHelp :NSObject

    @property (nonatomic, assign) NSInteger count;

    @property (nonatomic, assign) NSInteger  lineCount;

    @property (nonatomic, assign) CGFloat  lineWidth;

    @property (nonatomic, assign) CGFloat space;

    @property (nonatomic, strong) UIFont *textFont;

    @property (nonatomic, strong) UIColor *textColor;

    @property (nonatomic, assign) CGSize  size;//view的size

    @property (nonatomic, strong) UIColor  *lineColor;

    @property (nonatomic, strong) UIColor  *fillColor;

    @end

    @interfaceBJRadarMapView :UIView

    @property (nonatomic, strong)BJRadarMapHelp  *helper;

    @property (nonatomic, strong) NSArray  *valueArray;//值  value 为字典  字典包含title 和 rate两个key

    - (instancetype)init;

    @end

    .m

    #define RadarTextTag  590

    @implementation BJRadarMapHelp

    - (instancetype)init{

        self= [superinit];

        if(self) {

            [selfinitData];

        }

        return self;

    }

    //设置默认值

    - (void)initData{

        _count=6;

        _textFont = UIFont_Font(16);

        _lineColor = [UIColor colorWithHexString:@"#9D9D9E"];

        _lineCount = 5;

        _space=30;

        _size=CGSizeMake(220,220);

        _fillColor = [UIColor colorWithHexString:@"#31D486"];

        _lineWidth = 1;

        _textColor = [UIColor whiteColor];

    }

    @end

    @interface BJRadarMapView()

    @property (nonatomic, assign)CGSize  viewSize;

    @property (nonatomic, assign)CGFloat  radiusLen ;//多边形半径

    @property (nonatomic, assign)CGFloat  space ;//多边形与self 之间的距离

    @property (nonatomic, strong) NSMutableArray  *topPointArray;//n个顶点的坐标点的坐标

    @property(nonatomic,strong)NSArray  *valuePointArray;//n个顶点的坐标点的坐标

    @property (nonatomic, strong)CAShapeLayer *frontSpiderLayer;

    @property(nonatomic,strong)CAShapeLayer*backGroundSpiderLayer;

    @end

    @implementation BJRadarMapView

    - (instancetype)init{

        self= [superinit];

        if(self){

            self.backgroundColor = [UIColor clearColor];

            self.topPointArray = [NSMutableArray array];

            [selfsetUpView];

        }

        return self;

    }

    - (void)setUpView{

        self.backGroundSpiderLayer = [CAShapeLayer layer];

        [self.backGroundSpiderLayer setBackgroundColor:[UIColor clearColor].CGColor];

        self.backGroundSpiderLayer.fillColor = [UIColor clearColor].CGColor;

        [self.layer addSublayer:self.backGroundSpiderLayer];

        self.frontSpiderLayer = [CAShapeLayer layer];

        [self.frontSpiderLayer setBackgroundColor:[UIColor clearColor].CGColor];

        [self.layer addSublayer:self.frontSpiderLayer];

    }

    - (void)setHelper:(BJRadarMapHelp*)helper{

        _helper= helper;

        [self updateBackView];

    }

    - (void)setValueArray:(NSArray*)valueArray{

        _valueArray= valueArray;

        if(valueArray.count<1) {

            return;

        }

        [self updateForward];

    }

    - (void)updateForward{

        self.frontSpiderLayer.path = nil;

        self.frontSpiderLayer.frame = CGRectMake(0, 0, _helper.size.width, _helper.size.height);

        [self drawForwardsWith:self.frontSpiderLayer];

        [self loadText];

    }

    - (void)updateBackView{

        //赋值基本数据

        self.space = _helper.space;

        self.viewSize = CGSizeMake(_helper.size.width-_space*2, _helper.size.height - _space*2);

        self.radiusLen = (_helper.size.width-_space*2)/2;

        //初始化layer和数组

        self.backGroundSpiderLayer.path = nil;

        [self.topPointArray removeAllObjects];

        self.backGroundSpiderLayer.frame = CGRectMake(0, 0, _helper.size.width, _helper.size.height);

        for(inti =0; i <_helper.lineCount; i++) {

            CGFloatradius =  self.radiusLen - self.radiusLen/_helper.lineCount *i;

            NSArray *array = [self pointForBackRadar:self.backGroundSpiderLayer radiusLen:radius];

            [self.topPointArrayaddObject:array];

        }

        //添加背景

        [self drawBackWith:self.backGroundSpiderLayer];

    }

    #pragma mark - 绘制背景 背景 添加文字

    - (void)loadText{

        NSArray*topArray =nil;

        if (self.topPointArray.count >0) {

            topArray =self.topPointArray[0];

        }

        CGFloat  lineLength =_helper.size.width/2;

         lineLength =round(lineLength *100) /100;

        for(inti =0; i

            CGPointpoint = [topArray[i]CGPointValue];

            UILabel*label = [selfviewWithTag:RadarTextTag+i];

            if(!label) {

                label = [[UILabelalloc]init];

                label.tag=RadarTextTag+i;

                [labelsetFont:_helper.textFont];

                [labelsetTextColor:_helper.textColor];

                [labelsetBackgroundColor:[UIColor clearColor]];

                [labelsetTextAlignment:NSTextAlignmentCenter];

                [selfaddSubview:label];

            }

            if(self.valueArray.count>i)

            {

                NSDictionary*dic =self.valueArray[i];

                [labelsetText:[NSString stringWithFormat:@"%@",[dic valueForKey:@"title"]]];

            }

            CGFloatlenth = [label.textstringLengthWithFont:label.font];

            CGFloatx = point.x>lineLength?point.x+5:point.x- lenth -5;

            CGFloaty = point.y>lineLength?point.y+5:point.y-5-22;

            //这里本应该是= lineLength 由于计算会出现很多小数点所以加了做了范围判断

            if(point.x< lineLength +1&& point.x> lineLength -1) {

                x = point.x- lenth/2;

            }

            if(point.y< lineLength +1&& point.y> lineLength -1) {

                y = point.y-22/2;

            }

            [labelsetFrame:CGRectMake(x, y, lenth,22)];

        }

    }

    - (void)drawForwardsWith:(CAShapeLayer*)layer{

        self.valuePointArray = [self forwardsPointForLayer:layer];

        UIBezierPath*forwardsSpiderLayerPath = [UIBezierPathbezierPath];

        if (self.valuePointArray.count > 0) {

            [forwardsSpiderLayerPathmoveToPoint:[self.valuePointArray[0]CGPointValue]];

        }

        for(inti =0; i

            [forwardsSpiderLayerPathaddLineToPoint:[self.valuePointArray[i]CGPointValue]];

            if(i ==self.valuePointArray.count-1){

                [forwardsSpiderLayerPathaddLineToPoint:[self.valuePointArray[0]CGPointValue]];

            }

        }

        [forwardsSpiderLayerPathclosePath];

        layer.strokeColor =_helper.fillColor.CGColor;

        layer.fillColor =_helper.fillColor.CGColor;

        [layersetHidden:YES];

        layer.path= forwardsSpiderLayerPath.CGPath;

        layer.lineWidth=1;

        //渲染时先填充的黑色的低 所以要延时 达到看不到黑色底的效果

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            [layersetHidden:NO];

        });

    }

    - (void)drawBackWith:(CAShapeLayer*)layer {

        //绘制网状路径

        UIBezierPath*backGroundSpiderLayerPath = [UIBezierPathbezierPath];

        NSArray*topArray  =nil;

        if(self.topPointArray.count > 0){

            topArray =self.topPointArray[0];

        }

        CGPoint center = CGPointMake(_helper.size.width/2, _helper.size.height/2);

        [backGroundSpiderLayerPathmoveToPoint:center];

        //绘制最外层的线和到中点的线

        for(inti =0; i< topArray.count; i++){

          [backGroundSpiderLayerPathaddLineToPoint:[topArray[i]CGPointValue]];

          if(i+1< topArray.count) {

              [backGroundSpiderLayerPathaddLineToPoint:[topArray[i+1]CGPointValue]];

              [backGroundSpiderLayerPathaddLineToPoint:center];

          }else{

              [backGroundSpiderLayerPathaddLineToPoint:[topArray[0]CGPointValue]];

           }

        }

        //绘制内层的线

        for(inti =1; i

            NSArray*point =self.topPointArray[i];

            for(intj =0; j

                [backGroundSpiderLayerPathaddLineToPoint:[point[j]CGPointValue]];

                if(j == point.count-1){

                    [backGroundSpiderLayerPathaddLineToPoint:[point[0]CGPointValue]];

                }

            }

        }

        [backGroundSpiderLayerPathclosePath];

        [layersetHidden:YES];

        layer.fillColor = [UIColor clearColor].CGColor;

        layer.strokeColor = _helper.lineColor.CGColor;

        layer.path= backGroundSpiderLayerPath.CGPath;

        layer.lineWidth = _helper.lineWidth;

        //渲染时先填充的黑色的低 所以要延时 达到看不到黑色底的效果

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            [layersetHidden:NO];

        });

    }

    #pragma mark - 计算坐标点

    - (NSArray*)forwardsPointForLayer:(CAShapeLayer*)layer{

        NSMutableArray  *array = [NSMutableArray array];

        CGFloatradio =360/_helper.count;

        CGFloat  lineLength = layer.frame.size.width/2;

        for(inti =0; i<_helper.count; i++) {

            //取出值

            CGFloatvalue =0.0;

            if(self.valueArray.count>i) {

                NSDictionary*dic =self.valueArray[i];

                NSInteger  cou  =[[dicvalueForKey:@"rate"] integerValue];

                value = cou/100.00;

            }

            //计算值到中心点 的长度

            CGFloatradius = value*_radiusLen;

            CGFloatcurrentRadio = i*radio;

            CGFloat  x = lineLength + radius*sin([selfhuDuFromdu:currentRadio]);

            CGFloat  y = lineLength -  radius*cos([selfhuDuFromdu:currentRadio]);

            x =round(x *100) /100;

            y =round(y *100) /100;

            [arrayaddObject:[NSValue valueWithCGPoint:CGPointMake(x, y)]];

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

        }

        returnarray;

    }

    - (NSArray*)pointForBackRadar:(CAShapeLayer*)layer radiusLen:(CGFloat)radius{

        CGFloat  lineLength = layer.frame.size.width/2;

        NSMutableArray*pointArray =  [NSMutableArray array];

        //计算找出点

        CGPoint  topPoint0 =CGPointMake(lineLength,lineLength - radius);

        [pointArrayaddObject:[NSValue valueWithCGPoint:topPoint0]];

        CGFloatradio =360/_helper.count;

        for(inti =1; i<_helper.count; i++) {

            CGFloatcurrentRadio = i*radio;

            CGFloat  x = lineLength + radius*sin([selfhuDuFromdu:currentRadio]);

            CGFloat  y = lineLength -  radius*cos([selfhuDuFromdu:currentRadio]);

            x =round(x *100) /100;

            y =round(y *100) /100;

            [pointArrayaddObject:[NSValue valueWithCGPoint:CGPointMake(x, y)]];

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

        }

        returnpointArray;

    }

    -(float)huDuFromdu:(float)du

    {

        returnM_PI/(180/du);

    }

    相关文章

      网友评论

          本文标题:iOS自定义雷达图

          本文链接:https://www.haomeiwen.com/subject/kfdcxqtx.html