1.如何添加Charts到自己的项目;
2.初始化时直接选中其中某一个;
3.选中饼状图时输出标号,区分是哪一块;
4.选中饼状图时改变中间的文字;
5.去掉饼状图间隙;
6.去掉饼状图空心处的一圈淡色块遮罩;
前言:饼状图在数据统计方面尤为重要,但直接绘制并不是一个很好的办法,需要使用到Core Animation中被塞尔曲线,CAAnimation,CAShapLayer的相关知识,很多时候还要计算角度等等,自己去写会很费事耗时,好在有一个框架叫做Charts可以帮助我们简化这一步骤,只需要简单的集成就可以画出漂亮的饼状图,但是在使用这个框架时还是会存在诸多问题,因为Charts是Swift版本的,需要进行桥接,它的属性繁多,不了解的人很难快速的完成自己需要的属性,下面 博主就针对开发中遇到的问题对PieChartView的使用来进行说明。
1.如何添加Charts到自己的项目;
将Charts导入自己的项目分有两种方法,一种是通过pod导入,一种是直接引入工程文件。
目前3.0.4版本pod引入为:
pod 'Charts'
不会用pod可以去博主分类中寻找安装方法。
通过导入工程文件也不难,直接导入Charts的工程文件,蓝色的那个哦,因为是Swift,要设置Swift支持,目前是4.0,还需要在general-Linked FreameWorks and Libraries中引入Chart的frmework,具体做法自行百度,网上太多了,为了简化篇幅不一一列出,望各位海涵。
差点忘了桥接文件,最简单的方法就是直接在oc中创建Swift文件,会提示你创建桥街文件,然后在桥街文件中引入:
@import Charts;
如果没有提示你创建桥接文件,可以在博主Swift分类中寻找,不在复述。
2.初始化时直接选中其中某一个;
我们希望在进入这个界面时,饼状图就已经有一块为高亮(突出一块),再说这个问题之前,需要对饼状图进行初始化,推荐网上一篇博文,写的很好,注释也很清楚:PieCharView初始化和详细注释。
看完这篇博文之后,我们继续来看怎么设置高亮状态:
//这句代码的意思是设置第0个为高亮状态,并且不取消代理,那个X你可以直接忽略了,y代表你那一块饼状图的具体给的值,为什么要忽略X,因为打印出来都是0,老实说博主也没搞清楚这个X作用在哪,总之它不会影响整个程序,有知道的,可以在下方回复出来,谢谢。另外,这段代码写在Chart初始化完成后面,一般会有一个动画,这个根据自己需要来设置,完全可控。 [_chartView highlightValueWithX:maxIndex dataSetIndex:0]; //如上,是你看到的有效方法,博主和Charts团队成员沟通,确定他们没 有写PIeChart选中的公开方法,所以就自己看了看源代码,结果发现上面 那样写可以实现,也是很神奇。有兴趣的可以看看我们聊的记录: https://github.com/danielgindi/Charts/issues/3110 maxIndex是哪一块,对应加入数组的顺序。之前写的是下面的方法,发现 这个方法不对,理解不正确,目前可以用上面的吧方法实现默认选中,强调 下,PieChart目前没有公开的默认选中方法,作者提供的思路就是要自己 去实现,但是上面的方法博主亲测可行。
[self.chartView highlightValueWithX:0.0f y:762140.00 dataSetIndex:0 callDelegate:NO];
关于上面的index标号哪来的我下面会作说明,继续往下。
3.选中饼状图时输出标号,区分是哪一块;
chartView有四个代理方法,我们用到的有两个,一个选中,一个不选中:
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight - (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView
在选中时输出当前标号:
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight { NSLog(@"chartValueSelected"); //当前选中饼状图的值 NSLog(@"---chartValueSelected---value: %g", entry.y); //当前选中饼状图的index NSLog(@"---chartValueSelected---value: %@", entry.data); } /*不要高兴太早,这里存在俩问题,你要来思考: 1.输出了饼状图的值不就可以判断是哪个么,所以下面的index是不是不需要了?万一有几个饼状图的值也就是百分比一摸一样呢?无法判断,这是博主后来放弃这种方法来判断第几个的原因; 2.如果什么都不错就来输出entry.data,那么你会失望的,它并不会输出你需要的东西,在做这个操作前,你还需要做另一个操作,看下面代码; */
设置饼状图的“index”
//在data中给你的饼状图一个值,假装这就是tag,放心,最后博主会给出一个完整的初始化方法,现在不要慌。 [values addObject:[[PieChartDataEntry alloc] initWithValue:762140.00 label:nil data:@"0"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:786600.00 label:nil data:@"1"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:160000.00 label:nil data:@"2"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:786600.00 label:nil data:@"3"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:786600.00 label:nil data:@"4"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:786600.00 label:nil data:@"5"]];
到这里,区分是哪一块已经完成,拿到了哪一块,你就可以在选中这一块时改变中央的文字,或者做其他的操作,看下面的
4.选中饼状图时改变中间的文字;
首先来看选中的代理方法:
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight { NSLog(@"chartValueSelected"); NSArray *titleArray = @[@"x",@"xx",@"xxx"]; NSArray *tmpArray; if (_circlePartArray) { tmpArray = _circlePartArray; } else { tmpArray = @[@762140.00,@786600.00,@11134.00]; } NSLog(@"---chartValueSelected---value: %g", entry.y); NSLog(@"---chartValueSelected---value: %@", entry.data); //下面的方法用来设置饼状图中中央的文字,恰好还用到了富文本,就当学习下吧,还是比较常用的 NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail; paragraphStyle.alignment = NSTextAlignmentCenter; NSString *contentStr = [NSString stringWithFormat:@"%@\n%.2f",titleArray[[entry.data intValue]],[tmpArray[[entry.data intValue]] floatValue]]; NSMutableAttributedString *centerText = [[NSMutableAttributedString alloc] initWithString:contentStr]; [centerText setAttributes:@{ NSFontAttributeName: [UIFont PFSCRegularFontWithSize:12.f], NSParagraphStyleAttributeName: paragraphStyle } range:NSMakeRange(0, centerText.length)]; [centerText addAttributes:@{ NSFontAttributeName: [UIFont PFSCRegularFontWithSize:12.f], NSForegroundColorAttributeName: UIColor.gray9 } range:NSMakeRange(0, [titleArray[[entry.data intValue]] length])]; [centerText addAttributes:@{ NSFontAttributeName: [UIFont AsapMeidumFontWithSize:14.f], NSForegroundColorAttributeName: [UIColor gray3] } range:NSMakeRange([titleArray[[entry.data intValue]] length], centerText.length - [titleArray[[entry.data intValue]] length])]; _chartView.centerAttributedText = centerText; }
以上顺理成章,应该没有什么异议,因为拿到了当前index,所以改变其值完全不在话下,那博主久继续说下去了⬇️
5.去掉饼状图间隙;
一开始初始化饼状图,可以看到饼状图之间是有几像素的间距的,因为chartView属性众多,还是需要耐心去找的,这里博主直接给出,大家可以去试试:
dataSet.sliceSpace = 0;
这是PieChartDataSet的属性哦。
6.去掉饼状图空心处的一圈淡色块遮罩;
我们看到的饼状图中间有一个洞,有一层遮罩,导致你的饼状图不是纯色的,如果产品,测试提了这个问题,或者设计稿本身就是纯色的,就要去掉,那么怎么去掉呢?,一个个属性去找,如果不熟悉Swift,可能很不好找哦,看下面代码:
//以下几句代码是关键,根据注释可以清晰明了的知道该怎么做,应该不用博主再废话了吧,自己来设置试试看。 _pieChartView.drawHoleEnabled = YES;//饼状图是否是空心 _pieChartView.holeRadiusPercent = 0.5;//空心半径占比 _pieChartView.holeColor = [UIColor clearColor];//空心颜色 _pieChartView.transparentCircleRadiusPercent = 0.52;//半透明空心半径占比 _pieChartView.transparentCircleColor = [UIColor colorWithRed:210/255.0 green:145/255.0 blue:165/255.0 alpha:0.3];//半透明空心的颜色
以上是博主在使用Charts中的饼状图时遇到的问题,有一些可能网上根本找不到答案,也是博主自己摸索出来的,欢迎大家补充,最后,放一份博主自己的代码,有点长,需要的可以看看:
//想要看效果的话就集成一下试试看吧,去掉博主里的数据,加一个属性就可以直接运行 #import "LCCircleView.h" @implementation LCCircleView { NSArray *parties; NSArray *circlePercentArray; } - (instancetype)init { self = [super init]; if (self) { [self creatCircleView]; } return self; } - (void)creatCircleView { _chartView = [[PieChartView alloc]init]; [self addSubview:_chartView]; [self setupPieChartView:_chartView]; _chartView.layout.x(0).y(0).rightValue(0).base(0); _chartView.transparentCircleColor = [UIColor clearColor]; _chartView.delegate = self; //图示 ChartLegend *l = _chartView.legend; l.horizontalAlignment = ChartLegendHorizontalAlignmentRight; l.verticalAlignment = ChartLegendVerticalAlignmentTop; l.orientation = ChartLegendOrientationVertical; l.drawInside = NO; l.xEntrySpace = 0.0; l.yEntrySpace = 0.0; l.yOffset = 0.0; l.formSize = 0; // entry label styling _chartView.entryLabelColor = UIColor.whiteColor; _chartView.entryLabelFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:12.f]; [self setDataCount:4 range:100.f]; [self.chartView highlightValueWithX:0.0f y:762140.00 dataSetIndex:0 callDelegate:NO]; [_chartView animateWithXAxisDuration:1.4 easingOption:ChartEasingOptionEaseOutBack]; } - (void)setCirclePartArray:(NSArray *)circlePartArray { _circlePartArray = circlePartArray; [self setDataCount:4 range:100.f]; [_chartView animateWithXAxisDuration:1.4 easingOption:ChartEasingOptionEaseOutBack]; if ([_circlePartArray[0] floatValue] > 0) { //这里已经修改了选中的方法 [_chartView highlightValueWithX:maxIndex dataSetIndex:0]; } } - (void)setDataCount:(int)count range:(double)range { NSMutableArray *values = [[NSMutableArray alloc] init]; PieChartDataSet *dataSet; if (_circlePartArray) { for (int i = 0; i < _circlePartArray.count; i++) { [values addObject:[[PieChartDataEntry alloc] initWithValue:[_circlePartArray[i] floatValue] label:nil data:[NSString stringWithFormat:@"%d",i]]]; } dataSet = [[PieChartDataSet alloc] initWithValues:values label:nil]; // dataSet.drawIconsEnabled = NO; dataSet.sliceSpace = 0.0; dataSet.iconsOffset = CGPointMake(0, 40); // add a lot of colors NSArray *pointColors = @[[UIColor colorWithRGB:@"#FD615E"], [UIColor colorWithRGB:@"#43BF97"], [UIColor colorWithRGB:@"#FFB92F"], [UIColor colorWithRGB:@"#4D7DFE"], [UIColor colorWithRGB:@"#BC99FF"], [UIColor colorWithRGB:@"#8180FF"]]; dataSet.colors = pointColors; [self setupPieChartView:_chartView]; } else { [values addObject:[[PieChartDataEntry alloc] initWithValue:762140.00 label:nil data:@"0"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:786600.00 label:nil data:@"1"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:160000.00 label:nil data:@"2"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:786600.00 label:nil data:@"3"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:786600.00 label:nil data:@"4"]]; [values addObject:[[PieChartDataEntry alloc] initWithValue:786600.00 label:nil data:@"5"]]; dataSet = [[PieChartDataSet alloc] initWithValues:values label:nil]; dataSet.drawIconsEnabled = NO; dataSet.sliceSpace = 0.0; dataSet.iconsOffset = CGPointMake(0, 40); // add a lot of colors NSArray *pointColors = @[[UIColor colorWithRGB:@"#FD615E"], [UIColor colorWithRGB:@"#43BF97"], [UIColor colorWithRGB:@"#FFB92F"], [UIColor colorWithRGB:@"#4D7DFE"], [UIColor colorWithRGB:@"#BC99FF"], [UIColor colorWithRGB:@"#8180FF"]]; dataSet.colors = pointColors; } PieChartData *data = [[PieChartData alloc] initWithDataSet:dataSet]; NSNumberFormatter *pFormatter = [[NSNumberFormatter alloc] init]; pFormatter.numberStyle = NSNumberFormatterPercentStyle; pFormatter.maximumFractionDigits = 1; pFormatter.multiplier = @1.f; pFormatter.percentSymbol = @" %"; [data setValueFormatter:[[ChartDefaultValueFormatter alloc] initWithFormatter:pFormatter]]; [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:11.f]]; [data setValueTextColor:UIColor.clearColor]; _chartView.data = data; } - (void)optionTapped:(NSString *)key { if ([key isEqualToString:@"toggleXValues"]) { _chartView.drawSliceTextEnabled = !_chartView.isDrawSliceTextEnabled; [_chartView setNeedsDisplay]; return; } if ([key isEqualToString:@"togglePercent"]) { _chartView.usePercentValuesEnabled = !_chartView.isUsePercentValuesEnabled; [_chartView setNeedsDisplay]; return; } if ([key isEqualToString:@"toggleHole"]) { _chartView.drawHoleEnabled = !_chartView.isDrawHoleEnabled; [_chartView setNeedsDisplay]; return; } if ([key isEqualToString:@"drawCenter"]) { _chartView.drawCenterTextEnabled = !_chartView.isDrawCenterTextEnabled; [_chartView setNeedsDisplay]; return; } if ([key isEqualToString:@"animateX"]) { [_chartView animateWithXAxisDuration:1.4]; return; } if ([key isEqualToString:@"animateY"]) { [_chartView animateWithYAxisDuration:1.4]; return; } if ([key isEqualToString:@"animateXY"]) { [_chartView animateWithXAxisDuration:1.4 yAxisDuration:1.4]; return; } if ([key isEqualToString:@"spin"]) { [_chartView spinWithDuration:2.0 fromAngle:_chartView.rotationAngle toAngle:_chartView.rotationAngle + 360.f easingOption:ChartEasingOptionEaseInCubic]; return; } // [super handleOption:key forChartView:_chartView]; } #pragma mark - ChartViewDelegate - (void)chartValueSelected:(ChartViewBase * __nonnull)chartView entry:(ChartDataEntry * __nonnull)entry highlight:(ChartHighlight * __nonnull)highlight { NSLog(@"chartValueSelected"); NSArray *titleArray = @[@"1",@"2",@"3",@"4",@"5",@"6"]; NSArray *tmpArray; if (_circlePartArray) { tmpArray = _circlePartArray; } else { tmpArray = @[@762140.00,@786600.00,@160000.00,@786600.00,@786600.00,@786600.00]; } NSLog(@"---chartValueSelected---value: %g", entry.y); NSLog(@"---chartValueSelected---value: %@", entry.data); NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail; paragraphStyle.alignment = NSTextAlignmentCenter; NSString *contentStr = [NSString stringWithFormat:@"%@\n%.2f",titleArray[[entry.data intValue]],[tmpArray[[entry.data intValue]] floatValue]]; NSMutableAttributedString *centerText = [[NSMutableAttributedString alloc] initWithString:contentStr]; [centerText setAttributes:@{ NSFontAttributeName: [UIFont PFSCRegularFontWithSize:12.f], NSParagraphStyleAttributeName: paragraphStyle } range:NSMakeRange(0, centerText.length)]; [centerText addAttributes:@{ NSFontAttributeName: [UIFont PFSCRegularFontWithSize:12.f], NSForegroundColorAttributeName: UIColor.gray9 } range:NSMakeRange(0, [titleArray[[entry.data intValue]] length])]; [centerText addAttributes:@{ NSFontAttributeName: [UIFont AsapMeidumFontWithSize:14.f], NSForegroundColorAttributeName: [UIColor gray3] } range:NSMakeRange([titleArray[[entry.data intValue]] length], centerText.length - [titleArray[[entry.data intValue]] length])]; _chartView.centerAttributedText = centerText; } - (void)chartValueNothingSelected:(ChartViewBase * __nonnull)chartView { NSLog(@"chartValueNothingSelected"); } - (void)setupPieChartView:(PieChartView *)chartView { chartView.usePercentValuesEnabled = NO; chartView.drawSlicesUnderHoleEnabled = NO; chartView.holeRadiusPercent = 0.58; chartView.transparentCircleRadiusPercent = 0.61; chartView.chartDescription.enabled = NO; [chartView setExtraOffsetsWithLeft:5.f top:10.f right:5.f bottom:5.f]; chartView.drawCenterTextEnabled = YES; NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail; paragraphStyle.alignment = NSTextAlignmentCenter; NSMutableAttributedString *centerText; if (!_circlePartArray) { centerText = [[NSMutableAttributedString alloc] initWithString:@"xxxx\n762140.00"]; } else { NSString *contentStr = [NSString stringWithFormat:@"xxxx\n%.2f",[_circlePartArray[0] floatValue]]; centerText = [[NSMutableAttributedString alloc] initWithString:contentStr]; } [centerText setAttributes:@{ NSFontAttributeName: [UIFont PFSCRegularFontWithSize:12.f], NSParagraphStyleAttributeName: paragraphStyle } range:NSMakeRange(0, centerText.length)]; [centerText addAttributes:@{ NSFontAttributeName: [UIFont PFSCRegularFontWithSize:12.f], NSForegroundColorAttributeName: UIColor.gray9 } range:NSMakeRange(0, 4)]; [centerText addAttributes:@{ NSFontAttributeName: [UIFont AsapMeidumFontWithSize:14.f], NSForegroundColorAttributeName: [UIColor gray3] } range:NSMakeRange(4, centerText.length - 4)]; chartView.centerAttributedText = centerText; chartView.drawHoleEnabled = YES; chartView.rotationAngle = 0.0; chartView.rotationEnabled = YES; chartView.highlightPerTapEnabled = YES; ChartLegend *l = chartView.legend; l.horizontalAlignment = ChartLegendHorizontalAlignmentRight; l.verticalAlignment = ChartLegendVerticalAlignmentTop; l.orientation = ChartLegendOrientationVertical; l.drawInside = NO; l.xEntrySpace = 7.0; l.yEntrySpace = 0.0; l.yOffset = 0.0; } @end