四维雷达图,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];
}