环形统计图是一种比较常见的统计图,今天写了一个比较简单的统计图,用起来也比较方便,可扩展行也比较强!
我们先看一下效果图!
其实环形图在所有的图形中算是比较简单的一种图形,只需要一个底圆,一个上层显示数据的圆就搞定了!下面说一下具体的过程!
首先是一些属性设置:
接下来就可以开始啦!
一些私有属性
- (instancetype)initWithFrame:(CGRect)frame withMaxValue:(CGFloat)maxValue value:(CGFloat)value{
self = [super initWithFrame:frame];
if (self) {
NSLog(@"%f---%f",maxValue,value);
if (maxValue < value) {
maxValue = value;
}
_value = value;
_maxValue = maxValue;
[self drawArc];
}
return self;
}
接下来开始画了
-(void)drawArc
{
///计算中心点
CGPoint center = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5);
///底层圆
CGFloat radius = self.frame.size.width * 0.5 - 15;
UIBezierPath* arcPath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:2 * M_PI clockwise:YES];
CAShapeLayer *shapelayer = [CAShapeLayer layer];
_insideShapelayer = shapelayer;
shapelayer.lineWidth = 20.0;
// shapelayer.strokeColor = [UIColor colorWithRed:51.0/255.0 green:55.0/255.0 blue:60.0/255.0 alpha:1].CGColor;
shapelayer.strokeColor = [UIColor groupTableViewBackgroundColor].CGColor;
shapelayer.fillColor = [UIColor clearColor].CGColor;
shapelayer.path = arcPath.CGPath;
[self.layer addSublayer:shapelayer];
///顶层圆
CGFloat outerRadius = radius;
NSLog(@"value:%f---maxValue:%f",_value,_maxValue);
UIBezierPath *outerArcPath = [UIBezierPath bezierPathWithArcCenter:center radius:outerRadius startAngle:-M_PI_2 endAngle:M_PI * 2 * (_value / _maxValue) - M_PI_2 clockwise:YES];
CAShapeLayer *outerShapelayer = [CAShapeLayer layer];
_outerShapelayer = outerShapelayer;
outerShapelayer.lineWidth = 20.0;
outerShapelayer.strokeColor = [UIColor clearColor].CGColor;
outerShapelayer.fillColor = [UIColor clearColor].CGColor;
outerShapelayer.path = outerArcPath.CGPath;
[self.layer addSublayer:outerShapelayer];
///标注
UILabel *valueLabel = [[UILabel alloc] init];
[self addSubview:valueLabel];
self.valueLabel = valueLabel;
valueLabel.frame = CGRectMake(center.x - 50, center.y - 40, 100, 20);
valueLabel.textColor = [UIColor whiteColor];
valueLabel.font = [UIFont systemFontOfSize:24 weight:2];
valueLabel.textAlignment = NSTextAlignmentCenter;
//大标题
UILabel *titleLabel = [[UILabel alloc] init];
[self addSubview:titleLabel];
self.titleLabel = titleLabel;
titleLabel.frame = CGRectMake(center.x - 100, center.y + 10, 200, 30);
titleLabel.textColor = [UIColor whiteColor];
titleLabel.font = [UIFont systemFontOfSize:28 weight:2];
titleLabel.textAlignment = NSTextAlignmentCenter;
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
_gradientLayer = gradientLayer;
gradientLayer.frame = self.bounds;
gradientLayer.backgroundColor = [UIColor clearColor].CGColor;
[self.layer addSublayer:gradientLayer];
CAGradientLayer *colorLayer = [CAGradientLayer layer];
self.colorLayer = colorLayer;
colorLayer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
colorLayer.locations = @[@0.1,@1.0];
colorLayer.startPoint = CGPointMake(0, 0);
colorLayer.endPoint = CGPointMake(1, 0);
[gradientLayer addSublayer:colorLayer];
CAShapeLayer *gressLayer = [CAShapeLayer layer];
gressLayer.lineWidth = 20.0;
gressLayer.strokeColor = [UIColor blueColor].CGColor;
gressLayer.fillColor = [UIColor clearColor].CGColor;
gressLayer.lineCap = kCALineCapRound;
gressLayer.path = outerArcPath.CGPath;
gradientLayer.mask = gressLayer;
CABasicAnimation *ani = [ CABasicAnimation animationWithKeyPath : NSStringFromSelector ( @selector (strokeEnd))];
ani.fromValue = @0;
ani.toValue = @1;
ani.duration = 1.0;
[gressLayer addAnimation:ani forKey:NSStringFromSelector(@selector(strokeEnd))];
}
到这就基本画完啦,还剩一些set方法
#pragma mark set
- (void)setValueTitle:(NSString *)valueTitle{
_valueLabel.text = valueTitle;
}
- (void)setValueFont:(UIFont *)valueFont{
_valueLabel.font = valueFont;
}
- (void)setValueColor:(UIColor *)valueColor{
_valueLabel.textColor = valueColor;
}
- (void)setTitle:(NSString *)title {
_titleLabel.text = title;
}
- (void)setTitleFont:(UIFont *)titleFont {
_titleLabel.font = titleFont;
}
-(void)setTitleColor:(UIColor *)titleColor {
_titleLabel.textColor = titleColor;
}
- (void)setInsideCircleColor:(UIColor *)insideCircleColor{
_insideShapelayer.strokeColor = insideCircleColor.CGColor;
}
- (void)setColorArray:(NSArray *)colorArray{
_colorArray = colorArray;
NSMutableArray *array = [NSMutableArray array];
for (UIColor *color in colorArray) {
[array addObject:(id)color.CGColor];
}
_colorLayer.colors = array.copy;
}
- (void)setLocations:(NSArray *)locations{
_colorLayer.locations = locations;
}
- (void)setSingleColor:(UIColor *)singleColor{
_outerShapelayer.strokeColor = singleColor.CGColor;
[_gradientLayer removeFromSuperlayer];
CABasicAnimation *ani = [ CABasicAnimation animationWithKeyPath : NSStringFromSelector ( @selector (strokeEnd))];
ani.fromValue = @0;
ani.toValue = @1;
ani.duration = 1.0;
[_outerShapelayer addAnimation:ani forKey:NSStringFromSelector(@selector(strokeEnd))];
}
这样就都搞定了!
调用
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setupUI];
}
#pragma mark - 设置界面
- (void)setupUI {
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
CGFloat chartWidth = self.view.frame.size.width * 0.7;
CGFloat x = (width - chartWidth) / 2;
CGFloat y = (height - chartWidth) / 2;
MXNCircleCharts *circle = [[MXNCircleCharts alloc] initWithFrame:CGRectMake(x, y, chartWidth, chartWidth) withMaxValue:100 value:85];
circle.valueTitle = @"85%";
circle.valueColor = [UIColor blackColor];
circle.title = @"我的掌握度";
circle.titleColor = [UIColor blackColor];
circle.colorArray = @[[self colorWithHexString:@"#00C7B5" alpha:1],[self colorWithHexString:@"#ff2366" alpha:1]];
circle.locations = @[@0.15,@0.85];
[self.view addSubview:circle];
}
#pragma mark 设置16进制颜色
- (UIColor *)colorWithHexString:(NSString *)color alpha:(CGFloat)alpha{
//删除字符串中的空格
NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
// String should be 6 or 8 characters
if ([cString length] < 6)
{
return [UIColor clearColor];
}
// strip 0X if it appears
//如果是0x开头的,那么截取字符串,字符串从索引为2的位置开始,一直到末尾
if ([cString hasPrefix:@"0X"])
{
cString = [cString substringFromIndex:2];
}
//如果是#开头的,那么截取字符串,字符串从索引为1的位置开始,一直到末尾
if ([cString hasPrefix:@"#"])
{
cString = [cString substringFromIndex:1];
}
if ([cString length] != 6)
{
return [UIColor clearColor];
}
// Separate into r, g, b substrings
NSRange range;
range.location = 0;
range.length = 2;
//r
NSString *rString = [cString substringWithRange:range];
//g
range.location = 2;
NSString *gString = [cString substringWithRange:range];
//b
range.location = 4;
NSString *bString = [cString substringWithRange:range];
// Scan values
unsigned int r, g, b;
[[NSScanner scannerWithString:rString] scanHexInt:&r];
[[NSScanner scannerWithString:gString] scanHexInt:&g];
[[NSScanner scannerWithString:bString] scanHexInt:&b];
return [UIColor colorWithRed:((float)r / 255.0f) green:((float)g / 255.0f) blue:((float)b / 255.0f) alpha:alpha];
}
OK,画完收工!
传送门:https://github.com/Clark-new/MXNCircleCharts