四维雷达图

简介: 四维雷达图

四维雷达图,A,B,C分级。

demo下载地址

BGRadarChartView.h

#import <UIKit/UIKit.h>

@interface BGRadarChartView : UIView

@property (nonatomic, strong) NSMutableArray *scoresArray;

-(instancetype)initWithFrame:(CGRect)frame scoresArray:(NSMutableArray *)scoresArray;
@end

BGRadarChartView.m

#import "BGRadarChartView.h"
#import "UIColor+custom.h"
#import "UIBezierPath+Pentagon.h"

//#define kRScrollAlertViewWidth 590/2.0
#define kLabWidth 74
#define kMinLength 23
#define kInterval 7

@interface BGRadarChartView ()
@property (nonatomic, assign) CGPoint picCenter;
@end

@implementation BGRadarChartView


-(instancetype)initWithFrame:(CGRect)frame scoresArray:(NSMutableArray *)scoresArray {

    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor colorWithHex:0xFFFFFF];
        _scoresArray = [NSMutableArray array];
        [self drawBgPentagon];
        self.scoresArray = scoresArray;
    }

    return  self;

}

- (void)setScoresArray:(NSMutableArray *)scoresArray
{
    [_scoresArray removeAllObjects];
    if(!scoresArray || ![scoresArray isKindOfClass:[NSArray class]] || scoresArray.count == 0)
    {
        return;
    }
    NSUInteger count = scoresArray.count;
    for(int i = 0; i < 4; i++)
    {
        if(i >= count)
        {
            [_scoresArray addObject:@"C"];
        }
        else
        {
            NSString *str = scoresArray[i];
            if(!isRadarEmptyString(str))
            {
                if([str isEqualToString:@"A"] || [str isEqualToString:@"B"] || [str isEqualToString:@"C"])
                {
                    [_scoresArray addObject:str];
                }
                else
                {
                    [_scoresArray addObject:@"C"];
                }
            }
            else
            {
                [_scoresArray addObject:@"C"];
            }
        }
    }
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.backgroundColor = [UIColor clearColor].CGColor;
    shapeLayer.strokeColor = [UIColor  colorWithHex:0x75C995 alpha:1.0].CGColor;
    UIColor *fillColor = [UIColor  colorWithHex:0x75C995 alpha:1.0];
    shapeLayer.fillColor = fillColor.CGColor;
    shapeLayer.path = [UIBezierPath drawRadarChartWithCenter:self.picCenter minLength:kMinLength/sqrt(2) scoresArray:_scoresArray];
    [self.layer addSublayer:shapeLayer];
}

#pragma mark - 描绘背景五边行  按等比放大

- (void)drawBgPentagon
{
    NSArray *radiusArr = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%d", kMinLength], [NSString stringWithFormat:@"%d", kMinLength*2], [NSString stringWithFormat:@"%d", kMinLength*3],nil];
    
    
    self.picCenter = CGPointMake(self.center.x-self.frame.origin.x,self.center.y-self.frame.origin.y);
    for (int i = 0; i < radiusArr.count; i++) {
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.backgroundColor = [UIColor clearColor].CGColor;
        shapeLayer.strokeColor = [UIColor  colorWithHex:0x75C995 alpha:1.0].CGColor;
        shapeLayer.lineWidth = 1;
//        UIColor *fillColor = [colors objectAtIndex:i];
        shapeLayer.fillColor = [UIColor  colorWithHex:0xCEF9DE alpha:0.2].CGColor;
        shapeLayer.path = [UIBezierPath drawPentagonWithCenter:self.picCenter Length:[radiusArr[i] doubleValue]];
        [self.layer addSublayer:shapeLayer];
    }
    
//    CGPoint picCenter = CGPointMake(kRScrollAlertViewWidth / 2.0, 100.0);
    NSArray *titleArray = [NSArray arrayWithObjects:@"语言交流",@"个人情感发展",@"身体运动",@"探索与操作", nil];
    NSArray *centerArray = [NSArray arrayWithObjects:
                            [NSValue valueWithCGPoint:CGPointMake(self.picCenter.x - kLabWidth/2 - kMinLength*3* cos(M_PI / 4.0)-kInterval,self.picCenter.y)],
                            [NSValue valueWithCGPoint:CGPointMake(self.picCenter.x ,self.picCenter.y - kMinLength*3 * sin(M_PI / 4.0)-kInterval -6)],
                            [NSValue valueWithCGPoint:CGPointMake(self.picCenter.x + kMinLength*3 * cos(M_PI / 4.0) +kInterval+kLabWidth/2,self.picCenter.y)],
                            [NSValue valueWithCGPoint:CGPointMake(self.picCenter.x,self.picCenter.y +kMinLength*3 * sin(M_PI / 4.0) +kInterval+6)],nil];
    for (int i = 0; i < [titleArray count]; i++) {
        UILabel *lab = [self createLab];
        lab.center = [[centerArray objectAtIndex:i] CGPointValue];
        lab.text = titleArray[i];
        if(0 == i)
        {
            lab.textAlignment = NSTextAlignmentRight;
        }
        else if(2 == i)
        {
            lab.textAlignment = NSTextAlignmentLeft;
        }
        [self addSubview:lab];
    }
}

- (void)drawRect:(CGRect)rect
{
    [self drawLineWithCenter:self.picCenter endPoint:CGPointMake(self.picCenter.x - kMinLength*3* cos(M_PI / 4.0),self.picCenter.y)];
    [self drawLineWithCenter:self.picCenter endPoint:CGPointMake(self.picCenter.x ,self.picCenter.y - kMinLength*3 * sin(M_PI / 4.0))];
    [self drawLineWithCenter:self.picCenter endPoint:CGPointMake(self.picCenter.x + kMinLength*3 * cos(M_PI / 4.0),self.picCenter.y)];
    [self drawLineWithCenter:self.picCenter endPoint:CGPointMake(self.picCenter.x,self.picCenter.y +kMinLength*3 * sin(M_PI / 4.0))];
}

- (void)drawLineWithCenter:(CGPoint)picCenter
                  endPoint:(CGPoint)endPoint
{
    //1 获取当前的绘制图形上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    //2 创建并且设置路径  可变路径
    CGMutablePathRef path = CGPathCreateMutable();
    //设置路径上的点
    //路径的起始点
    //path 需要添加起始点的可变路径
    //transform 坐标系变化
    CGPathMoveToPoint(path, NULL, picCenter.x, picCenter.y);
    
    //向路径中添加点
    CGPathAddLineToPoint(path, NULL, endPoint.x, endPoint.y);
    
    //封闭路径 将路径的终点和起始点链接
    CGPathCloseSubpath(path);

    //3 设置绘制属性 (线条颜色,线条粗细)
    //设置线段颜色
    CGContextSetStrokeColorWithColor(context, [UIColor  colorWithHex:0x75C995 alpha:1.0].CGColor);
    
    //设置图形的填充颜色
    CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
    
    //设置线条宽度
    CGContextSetLineWidth(context, 1);
    
    //设置线段连接点的样式
    CGContextSetLineJoin(context, kCGLineJoinRound);
    
    //4 绘制路径
    //将创建好的路径 添加到上下文中
    CGContextAddPath(context, path);
    //在图形上下文中绘制已添加路径
    //mode 绘制模式
    CGContextDrawPath(context, kCGPathFillStroke);
    

    //在CG框架中 所有使用到了create函数创建的变量,都需要手动销毁
    CGPathRelease(path);
    
}

-(UILabel *)createLab
{
    UILabel *label = [[UILabel alloc] init];
    label.textColor = [UIColor colorWithHex:0x333333];
    label.textAlignment = NSTextAlignmentCenter;
    label.bounds = CGRectMake(0, 0, kLabWidth , 12);
//    label.picCenter = [[centerArray objectAtIndex:i] CGPointValue];
    label.font = [UIFont systemFontOfSize:12];
//    label.text = [titleArray objectAtIndex:i];
    return label;
}

UIBezierPath+Pentagon.h

#import <UIKit/UIKit.h>

//判断字符串是否为空
#define isRadarEmptyString(str) ([str isKindOfClass:[NSNull class]] || str == nil || ![str isKindOfClass:[NSString class]] || [str length] < 1)
//判断数组是否为空
#define isRadarEmptyArray(array) (array == nil || [array isKindOfClass:[NSNull class]] || array.count == 0)


@interface UIBezierPath (Pentagon)

+ (CGPathRef)drawPentagonWithCenter:(CGPoint)center LengthArray:(NSArray *)lengths;

+ (CGPathRef)drawPentagonWithCenter:(CGPoint)center Length:(double)length;

+ (NSArray *)converCoordinateFromLength:(NSArray *)lengthArray Center:(CGPoint)center;

+ (CGPathRef)drawRadarChartWithCenter:(CGPoint)center minLength:(double)minLength scoresArray:(NSMutableArray *)scoresArray;

@end

UIBezierPath+Pentagon.m

#import "UIBezierPath+Pentagon.h"

@implementation UIBezierPath (Pentagon)

+ (CGPathRef)drawRadarChartWithCenter:(CGPoint)center minLength:(double)minLength scoresArray:(NSMutableArray *)scoresArray
{
    if(minLength <= 0 || isRadarEmptyArray(scoresArray) || scoresArray.count != 4)
    {
        return nil;
    }
//    NSMutableArray *lengthArray = [NSArray arrayWithObjects:@(length),@(length),@(length),@(length), nil];
    NSMutableArray *coordinateArray = [NSMutableArray array];
    NSString *score1 = scoresArray[0];
    NSString *score2 = scoresArray[1];
    NSString *score3 = scoresArray[2];
    NSString *score4 = scoresArray[3];
    CGFloat cx1 =  center.x - ([score1 isEqualToString:@"A"] ?  3*minLength : ([score1 isEqualToString:@"B"] ?  2*minLength : minLength));
    CGFloat cy1 = center.y;
    CGPoint point1 = CGPointMake(cx1,cy1);
    [coordinateArray addObject:[NSValue valueWithCGPoint:point1]];
    
    CGFloat cx2 =  center.x;
    CGFloat cy2 = center.y - ([score2 isEqualToString:@"A"] ?  3*minLength : ([score2 isEqualToString:@"B"] ?  2*minLength : minLength));
    CGPoint point2 = CGPointMake(cx2, (cy2));
    [coordinateArray addObject:[NSValue valueWithCGPoint:point2]];
    
    CGFloat cx3 =  center.x + ([score3 isEqualToString:@"A"] ?  3*minLength : ([score3 isEqualToString:@"B"] ?  2*minLength : minLength));
    CGFloat cy3 = center.y;
    CGPoint point3 = CGPointMake(cx3,cy3);
    [coordinateArray addObject:[NSValue valueWithCGPoint:point3]];
    
    CGFloat cx4 =  center.x;
    CGFloat cy4 = center.y + ([score4 isEqualToString:@"A"] ?  3*minLength : ([score4 isEqualToString:@"B"] ?  2*minLength : minLength));
    CGPoint point4 = CGPointMake(cx4, (cy4));
    [coordinateArray addObject:[NSValue valueWithCGPoint:point4]];
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    for (int i = 0; i < [coordinateArray count]; i++) {
        CGPoint point = [[coordinateArray objectAtIndex:i] CGPointValue];
        if (i == 0) {
            [bezierPath moveToPoint:point];
        } else {
            [bezierPath addLineToPoint:point];
        }
    }
    [bezierPath closePath];
    
    return bezierPath.CGPath;
}

+ (CGPathRef)drawPentagonWithCenter:(CGPoint)center Length:(double)length
{
    NSArray *lengths = [NSArray arrayWithObjects:@(length),@(length),@(length),@(length), nil];
    return [self drawPentagonWithCenter:center LengthArray:lengths];
}

+ (CGPathRef)drawPentagonWithCenter:(CGPoint)center LengthArray:(NSArray *)lengths
{
    NSArray *coordinates = [self converCoordinateFromLength:lengths Center:center];
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    for (int i = 0; i < [coordinates count]; i++) {
        CGPoint point = [[coordinates objectAtIndex:i] CGPointValue];
        if (i == 0) {
            [bezierPath moveToPoint:point];
        } else {
            [bezierPath addLineToPoint:point];
        }
    }
    [bezierPath closePath];
    
    return bezierPath.CGPath;
}

+ (NSArray *)converCoordinateFromLength:(NSArray *)lengthArray Center:(CGPoint)center
{
    NSMutableArray *coordinateArray = [NSMutableArray array];
    for (int i = 0; i < [lengthArray count] ; i++) {
        double length = [[lengthArray objectAtIndex:i] doubleValue];
        CGPoint point = CGPointZero;
        if (i == 0) {
            point =  CGPointMake(center.x - length * cos(M_PI / 4.0),
                                 center.y);
        } else if (i == 1) {
            point = CGPointMake(center.x,
                                center.y - length * sin(M_PI / 4.0));
        } else if (i == 2) {
            point = CGPointMake(center.x + length * cos(M_PI / 4.0),
                                center.y);
        } else if (i == 3) {
            point = CGPointMake(center.x,
                                center.y +length * sin(M_PI / 4.0));
        } else {
            point = CGPointMake(center.x - length * cos(M_PI / 10.0),
                                center.y + length * sin(M_PI / 10.0));
        }
        
        [coordinateArray addObject:[NSValue valueWithCGPoint:point]];
    }
    return coordinateArray;
}

@end

调用代码

#import "ViewController.h"
#import "BGRadarChartView.h"
#import "math.h"

@interface ViewController ()

@property (nonatomic, strong) BGRadarChartView *chartV;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    self.chartV.center = self.view.center;
    [self.view addSubview:self.chartV];
}


-(BGRadarChartView *)chartV
{
    if (!_chartV) {
        _chartV = [[BGRadarChartView alloc] initWithFrame:CGRectMake(15, 100, 230, 320- 30) scoresArray:[NSMutableArray arrayWithObjects:@"A",@"C",@"C",@"C", nil]];
    }
    return _chartV;
}

@end

UIColor+custom.h

#import <UIKit/UIKit.h>

@interface UIColor (custom)

+ (UIColor *)colorWithHex:(int)hex;

+ (UIColor *)colorWithHex:(int)hex alpha:(CGFloat)alpha;

@end

UIColor+custom.m

#import "UIColor+custom.h"

@implementation UIColor (custom)


+ (UIColor *)colorWithHex:(int)hex
{
    return [UIColor colorWithHex:hex alpha:1.0f];
}

+ (UIColor *)colorWithHex:(int)hex alpha:(CGFloat)alpha
{
    return [UIColor colorWithRed:((float)((hex & 0xFF0000) >> 16))/255.0
                           green:((float)((hex & 0xFF00) >> 8))/255.0
                            blue:((float)(hex & 0xFF))/255.0 alpha:alpha];
}

目录
相关文章
|
7月前
|
算法 计算机视觉
基于表面法线法的二维人脸图构建三维人脸模型matlab仿真
该内容概述了一个使用MATLAB2022a的二维人脸图像三维重建算法。首先,通过人脸检测和对齐,然后运用深度信息估计技术(如Shape from Shading)获取表面法线。接着,结合预训练的三维人脸模型库和二维关键点,通过迭代优化和全局优化构建三维模型。核心程序涉及图像处理、光源方向转换、反射率和表面法线计算,最终重构高度图并显示结果。该方法依赖多视角图像,单幅图像重建可能存在挑战。
|
数据可视化
RNAseq|构建预后模型后你还需要这些图,森林图,诺莫图,校准曲线,DCA决策曲线
RNAseq|构建预后模型后你还需要这些图,森林图,诺莫图,校准曲线,DCA决策曲线
374 0
|
7月前
|
文件存储
AvaSpec-ULS2048光谱仪测定地物高光谱曲线的方法
AvaSpec-ULS2048光谱仪测定地物高光谱曲线的方法
|
数据挖掘 数据处理
这图怎么画| 还是热图(免疫治疗反应预测)
这图怎么画| 还是热图(免疫治疗反应预测)
89 0
|
机器学习/深度学习 传感器 安全
【天线】基于matlab绘制天线方向图绘制
【天线】基于matlab绘制天线方向图绘制
|
机器学习/深度学习 传感器 人工智能
基于MATLAB进行荧光光谱数据处理包括三维荧光光谱图、等高线图、激发光谱图、发射光谱图
基于MATLAB进行荧光光谱数据处理包括三维荧光光谱图、等高线图、激发光谱图、发射光谱图
|
算法
用于二维和三维声学设计灵敏度分析的奇异边界法(Matlab代码实现)
用于二维和三维声学设计灵敏度分析的奇异边界法(Matlab代码实现)
【基于矢量射线的衍射积分 (VRBDI)】基于矢量射线的衍射积分 (VRBDI) 和仿真工具(Matlab代码实现)
【基于矢量射线的衍射积分 (VRBDI)】基于矢量射线的衍射积分 (VRBDI) 和仿真工具(Matlab代码实现)
|
数据可视化 数据挖掘
热图的基础绘制(Matlab代码实现)
热图的基础绘制(Matlab代码实现)
270 0
|
传感器 机器学习/深度学习 编解码
单一传感器图像多光谱多分辨率研究附matlab代码
单一传感器图像多光谱多分辨率研究附matlab代码