1、Charts 简介
使用第三方框架 Charts 绘制 iOS 图表。GitHub 源码 Charts
Charts 是一款用于绘制图表的框架,可以绘制柱状图、折线图、K线图、饼状图等。Charts 只有 Swift 版本。
LineChart (with legend, simple design)
LineChart (with legend, simple design)
LineChart (cubic lines)
LineChart (gradient fill)
Combined-Chart (bar- and linechart in this case)
BarChart (with legend, simple design)
BarChart (grouped DataSets)
Horizontal-BarChart
PieChart (with selection, ...)
ScatterChart (with squares, triangles, circles, ... and more)
CandleStickChart (for financial data)
BubbleChart (area covered by bubbles indicates the value)
RadarChart (spider web chart)
2、在项目中集成 Charts
2.1 在 OC 项目中手动导入 Charts 框架
1、下载 Charts 框架。
2、新建工程,导入 Charts.xcodeproj 工程
3、编译导入的 Charts.xcodeproj 工程
4、添加 Charts.framework
5、建立 OC 和 Swift 的桥接文件
6、测试
3、绘制折线图
3.1 LineChart 设置
1、属性设置
在控制器中我们首先需要创建一个 LineChartView 的对象,在 Charts 框架中折线图用到的类是 LineChartView。
self.lineChartView = [[LineChartView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width - 10, 400)]; self.lineChartView.center = self.view.center; [self.view addSubview:self.lineChartView]; // 设置基本样式 self.lineChartView.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1]; self.lineChartView.delegate = self; // 设置代理,需遵守 ChartViewDelegate 协议 self.lineChartView.noDataText = @"暂无数据"; // 设置交互样式 self.lineChartView.scaleYEnabled = NO; // 取消 Y 轴缩放 self.lineChartView.doubleTapToZoomEnabled = NO; // 取消双击缩放 self.lineChartView.dragEnabled = YES; // 启用拖拽图标 self.lineChartView.dragDecelerationEnabled = YES; // 拖拽后是否有惯性效果 self.lineChartView.dragDecelerationFrictionCoef = 0.9; // 拖拽后惯性效果的摩擦系数(0~1),数值越小,惯性越不明显
在 LineChartView 中有两个属性 rightAxis 和 leftAxis 属于 ChartYAxis 类,是分别用来设置左边 Y 轴和右边 Y 轴的,可以根据自己的需求去设置。
self.lineChartView.rightAxis.enabled = NO; // 不绘制右边轴 ChartYAxis *leftAxis = self.lineChartView.leftAxis; // 获取左边 Y 轴 leftAxis.inverted = NO; // 是否将 Y 轴进行上下翻转 leftAxis.axisMinValue = 0; // 设置 Y 轴的最小值 leftAxis.axisMaxValue = 105; // 设置 Y 轴的最大值 leftAxis.axisLineWidth = 1.0 / [UIScreen mainScreen].scale; // 设置 Y 轴线宽 leftAxis.axisLineColor = [UIColor blackColor]; // 设置 Y 轴颜色 leftAxis.labelPosition = YAxisLabelPositionOutsideChart; // label 文字位置 leftAxis.valueFormatter = [[YAxisValueFormatter alloc] init]; // label 文字样式,自定义格式,默认时不显示特殊符号 leftAxis.labelTextColor = [self colorWithHexString:@"#057748"]; // label 文字颜色 leftAxis.labelFont = [UIFont systemFontOfSize:10.0f]; // label 文字字体 leftAxis.labelCount = 5; // label 数量,数值不一定, // 如果 forceLabelsEnabled 等于 YES, // 则强制绘制制定数量的 label, 但是可能不平均 leftAxis.forceLabelsEnabled = NO; // 不强制绘制指定数量的 label leftAxis.gridLineDashLengths = @[@3.0f, @3.0f]; // 设置虚线样式的网格线 leftAxis.gridColor = [UIColor colorWithRed:200/255.0f green:200/255.0f blue:200/255.0f alpha:1]; // 网格线颜色 leftAxis.gridAntialiasEnabled = YES; // 网格线开启抗锯齿
在这里要注意的是,一般情况下 y 轴的数据是 double 类型的并且是没有特殊符号的,如果想要做到像图中的那样的百分数类型是要去设置的,然后我们发现 ChartYAxis 类中有一个属性 valueFormatter,这个属性就是用来设置数据格式的,但比较麻烦的是这个属性必须遵循 IChartAxisValueFormatter 的协议,所以我们需要去自定义一个 YAxisValueFormatter 类来完成。
@import Charts; @interface YAxisValueFormatter : NSObject
@end @implementation YAxisValueFormatter /// 实现协议方法,返回 y 轴的数据 - (NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis { // value 为 y 轴的值 return [NSString stringWithFormat:@"%ld%%",(NSInteger)value]; } @end y 轴设置完了,现在我们来设置 x 轴,在 LineChartView 中也有个属性 xAxis 使用来设置 x 轴的样式的,它属于 ChartXAxis 类,现在我们来创建它。
ChartXAxis *xAxis = self.lineChartView.xAxis; xAxis.labelPosition = XAxisLabelPositionBottom; // 设置 X 轴的显示位置,默认是显示在上面的 xAxis.axisLineWidth = 1.0 / [UIScreen mainScreen].scale; // 设置 X 轴线宽 xAxis.axisLineColor = [UIColor blackColor]; // 设置 X 轴颜色 xAxis.granularityEnabled = YES; // 设置重复的值不显示 xAxis.valueFormatter = [[XAxisValueFormatter alloc] init]; // label 文字样式,自定义格式,默认时不显示特殊符号 xAxis.labelTextColor = [self colorWithHexString:@"#057748"]; // label 文字颜色 xAxis.drawGridLinesEnabled = NO; // 不绘制网格线 xAxis.gridColor = [UIColor clearColor]; // 网格线颜色
同样的一般情况下 x 轴的数据也是 double 类型的并且是没有特殊符号的,所以我们需要去自定义一个 XAxisValueFormatter 类来完成。
#import
@import Charts; @interface XAxisValueFormatter : NSObject @end @implementation XAxisValueFormatter /// 实现协议方法,返回 x 轴的数据 - (NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis { // value 为 x 轴的值 return [NSString stringWithFormat:@"%ld天", (NSInteger)value]; } @end 到这里我们 lineChartView 的 x 轴和 y 轴都设置好了,但是还少了一个选中数据滑动的时候值会变化的标签, LineChartView 中有个 marker 属性就是我们要找的,marker 属性遵循 IChartMarker 协议,是 id 类型,ChartMarkerView 和 ChartMarkerImage 都有遵循 IChartMarker 协议,都是可以用的,可以根据自己的需求自己选择。
ChartMarkerView *markerY = [[ChartMarkerView alloc] init]; markerY.offset = CGPointMake(-999, -8); markerY.chartView = self.lineChartView; [markerY addSubview:self.markYLabel]; self.lineChartView.marker = markerY; - (UILabel *)markYLabel { if (!_markYLabel) { _markYLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, -5, 35, 25)]; _markYLabel.font = [UIFont systemFontOfSize:15.0]; _markYLabel.textAlignment = NSTextAlignmentCenter; _markYLabel.text = @""; _markYLabel.textColor = [UIColor whiteColor]; _markYLabel.backgroundColor = [UIColor grayColor]; } return _markYLabel; }
2、数据设置
折线图的数据 data 属性是属于 LineChartData 类,所以 setData 方法需要返回一个 LineChartData 的对象,但是在 LineChartData 的对象的初始化方法中
- (nonnull instancetype)initWithDataSets:(NSArray
发现还需要一个装有 LineChartDataSet 的数组,LineChartDataSet 其实就是每一条折线,而绘制每一条折线又需要数据,所以我们先从数据开始一步一步创建。> * _Nullable)dataSets NSMutableArray *chartVals1 = [[NSMutableArray alloc] init]; for (int i = 0; i < vals_count; i++) { double xValue = i + 1; double yValue = arc4random() % 100; // 设置表格数据,x 轴和 y 轴的值 ChartDataEntry *entry = [[ChartDataEntry alloc] initWithX:xValue y:yValue]; [chartVals1 addObject:entry]; }
数据完成后,我们就要来创建折线了,创建 LineChartDataSet 对象,如果要只显示数据的最高点,需要设置 valueFormatter 和前面的一样,自定义一个 ChartMaxDataValueFormatter 类来完成。
@import Charts; @interface ChartMaxDataValueFormatter : NSObject
- (instancetype)initWithYDataVals:(NSArray *)yVals; @end @interface ChartMaxDataValueFormatter () @property (nonatomic, strong) NSArray *yDataValueArray; @property (nonatomic, assign) double maxDataSetIndex; @end @implementation ChartMaxDataValueFormatter - (instancetype)initWithYDataVals:(NSArray *)yVals { if (self = [super init]) { self.yDataValueArray = yVals; NSMutableArray *muArr = [NSMutableArray arrayWithArray:yVals]; [muArr sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { ChartDataEntry *entry1 =(ChartDataEntry *)obj1; ChartDataEntry *entry2 =(ChartDataEntry *)obj2; if (entry1.y >= entry2.y){ return NSOrderedAscending; } else { return NSOrderedDescending; } }]; self.maxDataSetIndex =((ChartDataEntry * )muArr[0]).x; } return self; } /// 实现协议方法,只显示折线上数据的最大值 - (NSString * _Nonnull)stringForValue:(double)value entry:(ChartDataEntry * _Nonnull)entry dataSetIndex:(NSInteger)dataSetIndex viewPortHandler:(ChartViewPortHandler * _Nullable)viewPortHandler { if (entry.x == self.maxDataSetIndex) { return [NSString stringWithFormat:@"%ld%%", (NSInteger)entry.y]; } else { return @""; } } @end 最后还有个 ChartView 的选中数据代理方法,主要用来显示选中折线数据的时候 label 值的变化。
- (void)chartValueSelected:(ChartViewBase * _Nonnull)chartView entry:(ChartDataEntry * _Nonnull)entry highlight:(ChartHighlight * _Nonnull)highlight { // 设置滑动时 Y 值标签 self.markYLabel.text = [NSString stringWithFormat:@"%ld%%", (NSInteger)entry.y]; // 将点击的数据滑动到中间 [self.lineChartView centerViewToAnimatedWithXValue:entry.x yValue:entry.y axis:[self.lineChartView.data getDataSetByIndex:highlight.dataSetIndex].axisDependency duration:1.0]; }
3.2 LineChart 绘制
XAxisValueFormatter.h
/// 设置 X 轴 数据格式 @import Charts; @interface XAxisValueFormatter : NSObject
@end XAxisValueFormatter.m
@implementation XAxisValueFormatter /// 实现协议方法,返回 x 轴的数据 - (NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis { // value 为 x 轴的值 return [NSString stringWithFormat:@"%ld天", (NSInteger)value]; } @end
YAxisValueFormatter.h
/// 设置 Y 轴 数据格式 @import Charts; @interface YAxisValueFormatter : NSObject
@end YAxisValueFormatter.m
@implementation YAxisValueFormatter /// 实现协议方法,返回 y 轴的数据 - (NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis { // value 为 y 轴的值 return [NSString stringWithFormat:@"%ld%%",(NSInteger)value]; } @end
ChartDataValueFormatter.h
/// 设置 折线显示的 数据格式 @import Charts; @interface ChartDataValueFormatter : NSObject
@end ChartDataValueFormatter.m
@implementation ChartDataValueFormatter /// 实现协议方法,返回折线拐点上显示的数据格式 - (NSString * _Nonnull)stringForValue:(double)value entry:(ChartDataEntry * _Nonnull)entry dataSetIndex:(NSInteger)dataSetIndex viewPortHandler:(ChartViewPortHandler * _Nullable)viewPortHandler { return [NSString stringWithFormat:@"%.1f", entry.y]; } @end
ChartMaxDataValueFormatter.h
/// 设置 折线显示的 数据格式,只显示最大值 @import Charts; @interface ChartMaxDataValueFormatter : NSObject
- (instancetype)initWithYDataVals:(NSArray *)yVals; @end ChartMaxDataValueFormatter.m
@interface ChartMaxDataValueFormatter () @property (nonatomic, strong) NSArray *yDataValueArray; @property (nonatomic, assign) double maxDataSetIndex; @end @implementation ChartMaxDataValueFormatter - (instancetype)initWithYDataVals:(NSArray *)yVals { if (self = [super init]) { self.yDataValueArray = yVals; NSMutableArray *muArr = [NSMutableArray arrayWithArray:yVals]; [muArr sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { ChartDataEntry *entry1 =(ChartDataEntry *)obj1; ChartDataEntry *entry2 =(ChartDataEntry *)obj2; if (entry1.y >= entry2.y){ return NSOrderedAscending; } else { return NSOrderedDescending; } }]; self.maxDataSetIndex =((ChartDataEntry * )muArr[0]).x; } return self; } /// 实现协议方法,只显示折线上数据的最大值 - (NSString * _Nonnull)stringForValue:(double)value entry:(ChartDataEntry * _Nonnull)entry dataSetIndex:(NSInteger)dataSetIndex viewPortHandler:(ChartViewPortHandler * _Nullable)viewPortHandler { if (entry.x == self.maxDataSetIndex) { return [NSString stringWithFormat:@"%ld%%", (NSInteger)entry.y]; } else { return @""; } } @end
ViewController.m
#import "ChartsDemo-Bridging-Header.h" // 自定义数据格式 #import "YAxisValueFormatter.h" #import "XAxisValueFormatter.h" #import "ChartDataValueFormatter.h" #import "ChartMaxDataValueFormatter.h" // 遵守协议 @interface ViewController ()
// 折线图 @property (nonatomic, strong) LineChartView *lineChartView; // 滑动时 Y 值标签 @property (nonatomic,strong) UILabel *markYLabel; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1]; // 创建折线图 [self createdLineView]; // 设置折线图的数据 self.lineChartView.data = [self setData]; } // 创建折线图 - (void)createdLineView { // 初始化折线图对象 self.lineChartView = [[LineChartView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width - 10, 400)]; self.lineChartView.center = self.view.center; [self.view addSubview:self.lineChartView]; // 设置基本样式 self.lineChartView.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1]; self.lineChartView.delegate = self; // 设置代理,需遵守 ChartViewDelegate 协议 self.lineChartView.noDataText = @"暂无数据"; // 设置交互样式 self.lineChartView.scaleYEnabled = NO; // 取消 Y 轴缩放 self.lineChartView.doubleTapToZoomEnabled = NO; // 取消双击缩放 self.lineChartView.dragEnabled = YES; // 启用拖拽图标 self.lineChartView.dragDecelerationEnabled = YES; // 拖拽后是否有惯性效果 self.lineChartView.dragDecelerationFrictionCoef = 0.9; // 拖拽后惯性效果的摩擦系数(0~1),数值越小,惯性越不明显 // 设置滑动时 Y 值标签 ChartMarkerView *markerY = [[ChartMarkerView alloc] init]; markerY.offset = CGPointMake(-999, -8); markerY.chartView = self.lineChartView; [markerY addSubview:self.markYLabel]; self.lineChartView.marker = markerY; // 设置 X 轴样式 ChartXAxis *xAxis = self.lineChartView.xAxis; xAxis.labelPosition = XAxisLabelPositionBottom; // 设置 X 轴的显示位置,默认是显示在上面的 xAxis.axisLineWidth = 1.0 / [UIScreen mainScreen].scale; // 设置 X 轴线宽 xAxis.axisLineColor = [UIColor blackColor]; // 设置 X 轴颜色 xAxis.granularityEnabled = YES; // 设置重复的值不显示 xAxis.valueFormatter = [[XAxisValueFormatter alloc] init]; // label 文字样式,自定义格式,默认时不显示特殊符号 xAxis.labelTextColor = [self colorWithHexString:@"#057748"]; // label 文字颜色 xAxis.drawGridLinesEnabled = NO; // 不绘制网格线 xAxis.gridColor = [UIColor clearColor]; // 网格线颜色 // 设置 Y 轴样式 self.lineChartView.rightAxis.enabled = NO; // 不绘制右边轴 ChartYAxis *leftAxis = self.lineChartView.leftAxis; // 获取左边 Y 轴 leftAxis.inverted = NO; // 是否将 Y 轴进行上下翻转 leftAxis.axisMinValue = 0; // 设置 Y 轴的最小值 leftAxis.axisMaxValue = 105; // 设置 Y 轴的最大值 leftAxis.axisLineWidth = 1.0 / [UIScreen mainScreen].scale; // 设置 Y 轴线宽 leftAxis.axisLineColor = [UIColor blackColor]; // 设置 Y 轴颜色 leftAxis.labelPosition = YAxisLabelPositionOutsideChart; // label 文字位置 leftAxis.valueFormatter = [[YAxisValueFormatter alloc] init]; // label 文字样式,自定义格式,默认时不显示特殊符号 leftAxis.labelTextColor = [self colorWithHexString:@"#057748"]; // label 文字颜色 leftAxis.labelFont = [UIFont systemFontOfSize:10.0f]; // label 文字字体 leftAxis.labelCount = 5; // label 数量,数值不一定, // 如果 forceLabelsEnabled 等于 YES, // 则强制绘制制定数量的 label, 但是可能不平均 leftAxis.forceLabelsEnabled = NO; // 不强制绘制指定数量的 label leftAxis.gridLineDashLengths = @[@3.0f, @3.0f]; // 设置虚线样式的网格线 leftAxis.gridColor = [UIColor colorWithRed:200/255.0f green:200/255.0f blue:200/255.0f alpha:1]; // 网格线颜色 leftAxis.gridAntialiasEnabled = YES; // 网格线开启抗锯齿 // 添加限制线 ChartLimitLine *limitLine = [[ChartLimitLine alloc] initWithLimit:80 label:@"限制线"]; // 设置限制值和标题 limitLine.lineWidth = 2; // 限制线的宽度 limitLine.lineColor = [UIColor greenColor]; // 限制线的颜色 limitLine.lineDashLengths = @[@5.0f, @5.0f]; // 虚线样式 limitLine.labelPosition = ChartLimitLabelPositionRightTop; // label 位置 limitLine.valueTextColor = [self colorWithHexString:@"#057748"]; // label 文字颜色 limitLine.valueFont = [UIFont systemFontOfSize:12]; // label 字体 [leftAxis addLimitLine:limitLine]; // 添加到 Y 轴上 leftAxis.drawLimitLinesBehindDataEnabled = YES; // 设置限制线绘制在折线图的下面 // 设置折线图描述 self.lineChartView.chartDescription.enabled = YES; // 显示折线图描述,默认 YES 显示 self.lineChartView.descriptionText = @"折线图"; // 折线图描述 self.lineChartView.descriptionFont = [UIFont systemFontOfSize:15]; // 折线图描述字体 self.lineChartView.descriptionTextColor = [UIColor darkGrayColor]; // 折线图描述颜色 // 设置折线图图例 self.lineChartView.legend.enabled = YES; // 显示图例,默认 YES 显示 self.lineChartView.legend.form = ChartLegendFormLine; // 图例的样式 self.lineChartView.legend.formSize = 30; // 图例中线条的长度 self.lineChartView.legend.textColor = [UIColor darkGrayColor]; // 图例文字颜色 // 设置动画效果,可以设置 X 轴和 Y 轴的动画效果 [self.lineChartView animateWithXAxisDuration:1.0f]; } // 设置折线图数据 - (LineChartData *)setData{ int vals_count = 50; // 要显示多少条数据 // 设置表格数据,包含 x 值和 y 值 NSMutableArray *chartVals1 = [[NSMutableArray alloc] init]; for (int i = 0; i < vals_count; i++) { double xValue = i + 1; double yValue = arc4random() % 100; // 设置表格数据,x 轴和 y 轴的值 ChartDataEntry *entry = [[ChartDataEntry alloc] initWithX:xValue y:yValue]; [chartVals1 addObject:entry]; } // 绘制折线图 LineChartDataSet *set1 = nil; if (self.lineChartView.data.dataSetCount > 0) { LineChartData *data = (LineChartData *)self.lineChartView.data; set1 = (LineChartDataSet *)data.dataSets[0]; set1.values = chartVals1; // set1.valueFormatter = [[ChartMaxDataValueFormatter alloc] initWithYDataVals:chartVals1]; // 设置数据显示的格式,只显示最大值 return data; } else { // 创建 LineChartDataSet 对象 set1 = [[LineChartDataSet alloc] initWithValues:chartVals1 label:@"lineName 1"]; // label 折线图图例名称 // 设置折线的样式 set1.lineWidth = 1.0 / [UIScreen mainScreen].scale; // 折线宽度 [set1 setColor:[self colorWithHexString:@"#007FFF"]]; // 折线颜色 set1.drawValuesEnabled = YES; // 是否在拐点处显示数据,默认 YES set1.valueColors = @[[UIColor brownColor]]; // 折线拐点处显示数据的颜色 set1.drawSteppedEnabled = NO; // 是否开启绘制阶梯样式的折线图,默认 NO // set1.valueFormatter = [[ChartMaxDataValueFormatter alloc] initWithYDataVals:chartVals1]; // 设置数据显示的格式,只显示最大值 // 折线拐点样式 set1.drawCirclesEnabled = YES; // 是否绘制拐点,默认 YES set1.circleRadius = 4.0f; // 拐点半径 set1.circleColors = @[[UIColor redColor], [UIColor greenColor]]; // 拐点颜色 // 拐点中间的空心样式 set1.drawCircleHoleEnabled = YES; // 是否绘制中间的空心,默认 YES set1.circleHoleRadius = 2.0f; // 空心的半径 set1.circleHoleColor = [UIColor blackColor]; // 空心的颜色 // 折线的颜色填充样式 // 第一种填充样式:单色填充 // set1.drawFilledEnabled = YES; // 是否填充颜色,默认 NO // set1.fillColor = [UIColor redColor]; // 填充颜色 // set1.fillAlpha = 0.3; // 填充颜色的透明度 // 第二种填充样式:渐变填充 set1.drawFilledEnabled = YES; // 是否填充颜色,默认 NO NSArray *gradientColors = @[(id)[ChartColorTemplates colorFromString:@"#FFFFFFFF"].CGColor, (id)[ChartColorTemplates colorFromString:@"#FF007FFF"].CGColor]; CGGradientRef gradientRef = CGGradientCreateWithColors(nil, (CFArrayRef)gradientColors, nil); set1.fill = [ChartFill fillWithLinearGradient:gradientRef angle:90.0f]; // 赋值填充颜色对象 CGGradientRelease(gradientRef); // 释放 gradientRef set1.fillAlpha = 0.3f; // 透明度 // 点击选中拐点的交互样式 set1.highlightEnabled = YES; // 选中拐点,是否开启高亮效果(显示十字线),默认 YES set1.highlightColor = [self colorWithHexString:@"#c83c23"]; // 点击选中拐点的十字线的颜色 set1.highlightLineWidth = 1.0 / [UIScreen mainScreen].scale; // 十字线宽度 set1.highlightLineDashLengths = @[@5, @5]; // 十字线的虚线样式 // 将 LineChartDataSet 对象放入数组中 NSMutableArray *dataSets = [[NSMutableArray alloc] init]; [dataSets addObject:set1]; // 添加第二个 LineChartDataSet 对象 LineChartDataSet *set2 = [set1 copy]; set2.label = @"lineName 2"; NSMutableArray *chartVals2 = [[NSMutableArray alloc] init]; for (int i = 0; i < vals_count; i++) { double xValue = i + 1; double yValue = arc4random() % 100; ChartDataEntry *entry = [[ChartDataEntry alloc] initWithX:xValue y:yValue]; [chartVals2 addObject:entry]; } set2.values = chartVals2; [set2 setColor:[UIColor redColor]]; set2.drawFilledEnabled = YES; set2.fillColor = [UIColor redColor]; set2.fillAlpha = 0.1; [dataSets addObject:set2]; // 创建 LineChartData 对象, 此对象就是 lineChartView 需要最终数据对象 LineChartData *data = [[LineChartData alloc] initWithDataSets:dataSets]; [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:8.f]]; // 文字字体 [data setValueTextColor:[UIColor grayColor]]; // 文字颜色 // 自定义数据显示格式 ChartDataValueFormatter *formatter = [[ChartDataValueFormatter alloc] init]; // 统一设置数据显示的格式 [data setValueFormatter:formatter]; return data; } } #pragma mark - ChartViewDelegate // 点击选中折线拐点时回调 - (void)chartValueSelected:(ChartViewBase * _Nonnull)chartView entry:(ChartDataEntry * _Nonnull)entry highlight:(ChartHighlight * _Nonnull)highlight { // 设置滑动时 Y 值标签 self.markYLabel.text = [NSString stringWithFormat:@"%ld%%", (NSInteger)entry.y]; // 将点击的数据滑动到中间 [self.lineChartView centerViewToAnimatedWithXValue:entry.x yValue:entry.y axis:[self.lineChartView.data getDataSetByIndex:highlight.dataSetIndex].axisDependency duration:1.0]; } // 没有选中折线拐点时回调 - (void)chartValueNothingSelected:(ChartViewBase * _Nonnull)chartView { } // 放大折线图时回调 - (void)chartScaled:(ChartViewBase * _Nonnull)chartView scaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY { } // 拖拽折线图时回调 - (void)chartTranslated:(ChartViewBase * _Nonnull)chartView dX:(CGFloat)dX dY:(CGFloat)dY { } // 懒加载滑动时 Y 值标签 - (UILabel *)markYLabel { if (!_markYLabel) { _markYLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, -5, 35, 25)]; _markYLabel.font = [UIFont systemFontOfSize:15.0]; _markYLabel.textAlignment = NSTextAlignmentCenter; _markYLabel.text = @""; _markYLabel.textColor = [UIColor whiteColor]; _markYLabel.backgroundColor = [UIColor grayColor]; } return _markYLabel; } // 由十六进制创建颜色 - (UIColor *)colorWithHexString:(NSString *)color { NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; // String should be 6 or 8 characters if ([cString length] < 6) { return [UIColor clearColor]; } // strip "0X" or "#" if it appears if ([cString hasPrefix:@"0X"]) cString = [cString substringFromIndex:2]; 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:1.0f]; } @end 如果绘制光滑的曲线图,可以设置 set 的 mode 值为 LineChartModeCubicBezier,不设置 drawValuesEnabled 的值。
// 绘制光滑曲线 set1.mode = LineChartModeCubicBezier; set1.cubicIntensity = 0.2; // 是否开启绘制阶梯样式的折线图,默认 NO // set1.drawSteppedEnabled = NO;
4、绘制柱状图
XAxisValueFormatter.h
/// 设置 X 轴 数据格式 @import Charts; @interface XAxisValueFormatter : NSObject
@end XAxisValueFormatter.m
@implementation XAxisValueFormatter /// 实现协议方法,返回 x 轴的数据 - (NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis { // value 为 x 轴的值 return [NSString stringWithFormat:@"%ld天", (NSInteger)value]; } @end
YAxisValueFormatter.h
/// 设置 Y 轴 数据格式 @import Charts; @interface YAxisValueFormatter : NSObject
@end YAxisValueFormatter.m
@implementation YAxisValueFormatter /// 实现协议方法,返回 y 轴的数据 - (NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis { // value 为 y 轴的值 return [NSString stringWithFormat:@"%ld%%",(NSInteger)value]; } @end
ChartDataValueFormatter.h
/// 设置 柱形上显示的 数据格式 @import Charts; @interface ChartDataValueFormatter : NSObject
@end ChartDataValueFormatter.m
@implementation ChartDataValueFormatter /// 实现协议方法,返回柱形上显示的数据格式 - (NSString * _Nonnull)stringForValue:(double)value entry:(ChartDataEntry * _Nonnull)entry dataSetIndex:(NSInteger)dataSetIndex viewPortHandler:(ChartViewPortHandler * _Nullable)viewPortHandler { return [NSString stringWithFormat:@"%.1f", entry.y]; } @end
ChartMaxDataValueFormatter.h
/// 设置 柱形上显示的 数据格式,只显示最大值 @import Charts; @interface ChartMaxDataValueFormatter : NSObject
- (instancetype)initWithYDataVals:(NSArray *)yVals; @end ChartMaxDataValueFormatter.m
@interface ChartMaxDataValueFormatter () @property (nonatomic, strong) NSArray *yDataValueArray; @property (nonatomic, assign) double maxDataSetIndex; @end @implementation ChartMaxDataValueFormatter - (instancetype)initWithYDataVals:(NSArray *)yVals { if (self = [super init]) { self.yDataValueArray = yVals; NSMutableArray *muArr = [NSMutableArray arrayWithArray:yVals]; [muArr sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { ChartDataEntry *entry1 =(ChartDataEntry *)obj1; ChartDataEntry *entry2 =(ChartDataEntry *)obj2; if (entry1.y >= entry2.y){ return NSOrderedAscending; } else { return NSOrderedDescending; } }]; self.maxDataSetIndex =((ChartDataEntry * )muArr[0]).x; } return self; } /// 实现协议方法,只显示柱形上数据的最大值 - (NSString * _Nonnull)stringForValue:(double)value entry:(ChartDataEntry * _Nonnull)entry dataSetIndex:(NSInteger)dataSetIndex viewPortHandler:(ChartViewPortHandler * _Nullable)viewPortHandler { if (entry.x == self.maxDataSetIndex) { return [NSString stringWithFormat:@"%ld%%", (NSInteger)entry.y]; } else { return @""; } } @end
ViewController.m
#import "ChartsDemo-Bridging-Header.h" // 自定义数据格式 #import "YAxisValueFormatter.h" #import "XAxisValueFormatter.h" #import "ChartDataValueFormatter.h" #import "ChartMaxDataValueFormatter.h" // 遵守协议 @interface ViewController ()
// 柱状图 @property (nonatomic, strong) BarChartView *barChartView; // 滑动时 Y 值标签 @property (nonatomic,strong) UILabel *markYLabel; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1]; // 创建柱状图 [self createdBarView]; // 设置柱状图的数据 self.barChartView.data = [self setData]; } // 创建柱状图 - (void)createdBarView { // 初始化柱状图对象 self.barChartView = [[BarChartView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width - 10, 400)]; self.barChartView.center = self.view.center; [self.view addSubview:self.barChartView]; // 设置基本样式 self.barChartView.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1]; self.barChartView.delegate = self; // 设置代理,需遵守 ChartViewDelegate 协议 self.barChartView.noDataText = @"暂无数据"; // 没有数据时的文字提示 self.barChartView.drawValueAboveBarEnabled = YES; // 数值显示在柱形的上面还是下面 self.barChartView.drawBarShadowEnabled = NO; // 是否绘制柱形的阴影背景 // 设置交互样式 self.barChartView.scaleYEnabled = NO; // 取消 Y 轴缩放 self.barChartView.doubleTapToZoomEnabled = NO; // 取消双击缩放 self.barChartView.dragEnabled = YES; // 启用拖拽图标 self.barChartView.dragDecelerationEnabled = YES; // 拖拽后是否有惯性效果 self.barChartView.dragDecelerationFrictionCoef = 0.9; // 拖拽后惯性效果的摩擦系数(0~1),数值越小,惯性越不明显 // 设置滑动时 Y 值标签 ChartMarkerView *markerY = [[ChartMarkerView alloc] init]; markerY.offset = CGPointMake(-17, -25); // 设置显示位置 markerY.chartView = self.barChartView; [markerY addSubview:self.markYLabel]; self.barChartView.marker = markerY; // 设置 X 轴样式 ChartXAxis *xAxis = self.barChartView.xAxis; xAxis.labelPosition = XAxisLabelPositionBottom; // 设置 X 轴的显示位置,默认是显示在上面的 xAxis.axisLineWidth = 1.0 / [UIScreen mainScreen].scale; // 设置 X 轴线宽 xAxis.axisLineColor = [UIColor blackColor]; // 设置 X 轴颜色 xAxis.valueFormatter = [[XAxisValueFormatter alloc] init]; // label 文字样式,自定义格式,默认时不显示特殊符号 xAxis.labelTextColor = [UIColor brownColor]; // label 文字颜色 xAxis.drawGridLinesEnabled = NO; // 不绘制网格线 xAxis.gridColor = [UIColor clearColor]; // 网格线颜色 // 设置 Y 轴样式 self.barChartView.rightAxis.enabled = NO; // 不绘制右边轴 ChartYAxis *leftAxis = self.barChartView.leftAxis; // 获取左边 Y 轴 leftAxis.inverted = NO; // 是否将 Y 轴进行上下翻转 leftAxis.axisMinValue = 0; // 设置 Y 轴的最小值 leftAxis.axisMaxValue = 105; // 设置 Y 轴的最大值 leftAxis.axisLineWidth = 1.0 / [UIScreen mainScreen].scale; // 设置 Y 轴线宽 leftAxis.axisLineColor = [UIColor blackColor]; // 设置 Y 轴颜色 leftAxis.labelPosition = YAxisLabelPositionOutsideChart; // label 文字位置 leftAxis.valueFormatter = [[YAxisValueFormatter alloc] init]; // label 文字样式,自定义格式,默认时不显示特殊符号 leftAxis.labelTextColor = [UIColor brownColor]; // label 文字颜色 leftAxis.labelFont = [UIFont systemFontOfSize:10.0f]; // label 文字字体 leftAxis.labelCount = 5; // label 数量,数值不一定, // 如果 forceLabelsEnabled 等于 YES, // 则强制绘制制定数量的 label, 但是可能不平均 leftAxis.forceLabelsEnabled = NO; // 不强制绘制指定数量的 label leftAxis.gridLineDashLengths = @[@3.0f, @3.0f]; // 设置虚线样式的网格线 leftAxis.gridColor = [UIColor colorWithRed:200/255.0f green:200/255.0f blue:200/255.0f alpha:1]; // 网格线颜色 leftAxis.gridAntialiasEnabled = YES; // 网格线开启抗锯齿 // 添加限制线 ChartLimitLine *limitLine = [[ChartLimitLine alloc] initWithLimit:80 label:@"限制线"]; // 设置限制值和标题 limitLine.lineWidth = 2; // 限制线的宽度 limitLine.lineColor = [UIColor greenColor]; // 限制线的颜色 limitLine.lineDashLengths = @[@5.0f, @5.0f]; // 虚线样式 limitLine.labelPosition = ChartLimitLabelPositionRightTop; // label 位置 limitLine.valueTextColor = [UIColor grayColor]; // label 文字颜色 limitLine.valueFont = [UIFont systemFontOfSize:12]; // label 字体 [leftAxis addLimitLine:limitLine]; // 添加到 Y 轴上 leftAxis.drawLimitLinesBehindDataEnabled = YES; // 设置限制线绘制在柱状图的下面 // 设置柱状图描述 self.barChartView.chartDescription.enabled = YES; // 显示柱状图描述,默认 YES 显示 self.barChartView.descriptionText = @"柱状图"; // 柱状图描述 self.barChartView.descriptionFont = [UIFont systemFontOfSize:15]; // 柱状图描述字体 self.barChartView.descriptionTextColor = [UIColor darkGrayColor]; // 柱状图描述颜色 // 设置柱状图图例 self.barChartView.legend.enabled = NO; // 显示图例,默认 YES 显示 // 设置动画效果,可以设置 X 轴和 Y 轴的动画效果 [self.barChartView animateWithYAxisDuration:1.0f]; } // 设置柱状图数据 - (BarChartData *)setData { int vals_count = 50; // 要显示多少条数据 // 设置表格数据,包含 x 值和 y 值 NSMutableArray *chartVals1 = [[NSMutableArray alloc] init]; for (int i = 0; i < vals_count; i++) { double xValue = i + 1; double yValue = arc4random() % 100; // 设置表格数据,x 轴和 y 轴的值 BarChartDataEntry *entry = [[BarChartDataEntry alloc] initWithX:xValue y:yValue]; [chartVals1 addObject:entry]; } // 绘制柱状图 // 创建 BarChartDataSet 对象 BarChartDataSet *set1 = [[BarChartDataSet alloc] initWithValues:chartVals1 label:nil]; // 设置柱形的样式 [set1 setColors:ChartColorTemplates.material]; // 设置柱形图颜色 set1.drawValuesEnabled = YES; // 是否显示数据,默认 YES set1.valueColors = @[[UIColor brownColor]]; // 显示数据的颜色 set1.highlightEnabled = YES; // 点击选中柱形图是否有高亮效果,(双击空白处取消选中) // set1.valueFormatter = [[ChartMaxDataValueFormatter alloc] initWithYDataVals:chartVals1]; // 设置数据显示的格式,只显示最大值 // 将 BarChartDataSet 对象放入数组中 NSMutableArray *dataSets = [[NSMutableArray alloc] init]; [dataSets addObject:set1]; // 创建 BarChartData 对象, 此对象就是 BarChartData 需要最终数据对象 BarChartData *data = [[BarChartData alloc] initWithDataSets:dataSets]; [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:8.f]]; // 文字字体 [data setValueTextColor:[UIColor grayColor]]; // 文字颜色 // 自定义数据显示格式 ChartDataValueFormatter *formatter = [[ChartDataValueFormatter alloc] init];// 统一设置数据显示的格式 [data setValueFormatter:formatter]; return data; } #pragma mark - ChartViewDelegate // 点击选中柱形图时的代理方法 - (void)chartValueSelected:(ChartViewBase * _Nonnull)chartView entry:(ChartDataEntry * _Nonnull)entry highlight:(ChartHighlight * _Nonnull)highlight { // 设置滑动时 Y 值标签 self.markYLabel.text = [NSString stringWithFormat:@"%ld%%", (NSInteger)entry.y]; // 将点击的数据滑动到中间 [self.barChartView centerViewToAnimatedWithXValue:entry.x yValue:entry.y axis:[self.barChartView.data getDataSetByIndex:highlight.dataSetIndex].axisDependency duration:1.0]; } // 没有选中柱形图时的代理方法,当选中一个柱形图后,在空白处双击,就可以取消选择,此时会回调此方法 - (void)chartValueNothingSelected:(ChartViewBase * _Nonnull)chartView { } // 捏合放大或缩小柱形图时的代理方法 - (void)chartScaled:(ChartViewBase * _Nonnull)chartView scaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY { } // 拖拽图表时的代理方法 - (void)chartTranslated:(ChartViewBase * _Nonnull)chartView dX:(CGFloat)dX dY:(CGFloat)dY { } // 懒加载滑动时 Y 值标签 - (UILabel *)markYLabel { if (!_markYLabel) { _markYLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, -5, 35, 25)]; _markYLabel.font = [UIFont systemFontOfSize:15.0]; _markYLabel.textAlignment = NSTextAlignmentCenter; _markYLabel.text = @""; _markYLabel.textColor = [UIColor whiteColor]; _markYLabel.backgroundColor = [UIColor grayColor]; } return _markYLabel; } @end 如果要显示水平柱状图,只需要把 BarChartView 换成 HorizontalBarChartView 即可。
// 声明柱状图 @property (nonatomic, strong) HorizontalBarChartView *barChartView; // 初始化柱状图对象 self.barChartView = [[HorizontalBarChartView alloc] initWithFrame:frame];
5、绘制饼图
ChartDataValueFormatter.h
/// 设置 折线显示的 数据格式 @import Charts; @interface ChartDataValueFormatter : NSObject
@end ChartDataValueFormatter.m
@implementation ChartDataValueFormatter /// 实现协议方法,返回折线拐点上显示的数据格式 - (NSString * _Nonnull)stringForValue:(double)value entry:(ChartDataEntry * _Nonnull)entry dataSetIndex:(NSInteger)dataSetIndex viewPortHandler:(ChartViewPortHandler * _Nullable)viewPortHandler { return [NSString stringWithFormat:@"%.0f%%", entry.y]; } @end
ViewController.m
#import "ChartsDemo-Bridging-Header.h" // 自定义数据格式 #import "ChartDataValueFormatter.h" // 遵守协议 @interface ViewController ()
// 饼状图 @property (nonatomic, strong) PieChartView *pieChartView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1]; // 创建饼状图 [self createdPieView]; // 设置饼状图的数据 self.pieChartView.data = [self setData]; } // 创建饼状图 - (void)createdPieView { // 初始化饼状图对象 self.pieChartView = [[PieChartView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width - 10, 400)]; self.pieChartView.center = self.view.center; [self.view addSubview:self.pieChartView]; // 设置基本样式 self.pieChartView.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1]; self.pieChartView.delegate = self; // 设置代理,需遵守 ChartViewDelegate 协议 self.pieChartView.noDataText = @"暂无数据"; // 没有数据时的文字提示 [self.pieChartView setExtraOffsetsWithLeft:30 top:0 right:30 bottom:0]; // 饼状图距离边缘的间隙 self.pieChartView.usePercentValuesEnabled = YES; // 是否根据所提供的数据, 将显示数据转换为百分比格式 self.pieChartView.drawSliceTextEnabled = YES; // 是否显示区块文本 // 设置交互样式 self.pieChartView.dragDecelerationEnabled = YES; // 拖拽后是否有惯性效果 self.pieChartView.dragDecelerationFrictionCoef = 0.9; // 拖拽后惯性效果的摩擦系数(0~1),数值越小,惯性越不明显 // 设置饼状图中间的空心样式 // 空心有两个圆组成, 一个是 hole, 一个是 transparentCircle, transparentCircle 里面是 hole self.pieChartView.drawHoleEnabled = YES; // 饼状图是否是空心 self.pieChartView.holeColor = [UIColor clearColor]; // 空心颜色 self.pieChartView.holeRadiusPercent = 0.5; // 空心半径占比 self.pieChartView.transparentCircleRadiusPercent = 0.52; // 半透明空心半径占比 self.pieChartView.transparentCircleColor = [UIColor colorWithRed:210/255.0 green:145/255.0 blue:165/255.0 alpha:0.3]; // 半透明空心的颜色 // 设置饼状图中心的文本 if (self.pieChartView.isDrawHoleEnabled == YES) { self.pieChartView.drawCenterTextEnabled = YES; // 是否显示中间文字 // 普通文本 // self.pieChartView.centerText = @"饼状图"; // 中间文字 // 富文本 NSMutableAttributedString *centerText = [[NSMutableAttributedString alloc] initWithString:@"饼状图"]; [centerText setAttributes:@{NSFontAttributeName: [UIFont boldSystemFontOfSize:16], NSForegroundColorAttributeName: [UIColor orangeColor]} range:NSMakeRange(0, centerText.length)]; self.pieChartView.centerAttributedText = centerText; } // 设置饼状图描述 self.pieChartView.chartDescription.enabled = YES; // 显示饼状图描述,默认 YES 显示 self.pieChartView.descriptionText = @"饼状图"; self.pieChartView.descriptionFont = [UIFont systemFontOfSize:15]; self.pieChartView.descriptionTextColor = [UIColor grayColor]; // 设置饼状图图例 self.pieChartView.legend.enabled = YES; // 显示图例,默认 YES 显示 self.pieChartView.legend.form = ChartLegendFormCircle; // 图示样式: 方形、线条、圆形 self.pieChartView.legend.formSize = 12; // 图示大小 self.pieChartView.legend.position = ChartLegendPositionBelowChartCenter; // 图例在饼状图中的位置 self.pieChartView.legend.maxSizePercent = 1; // 图例在饼状图中的大小占比, 这会影响图例的宽高 self.pieChartView.legend.formToTextSpace = 5; // 文本间隔 self.pieChartView.legend.font = [UIFont systemFontOfSize:10]; // 字体大小 self.pieChartView.legend.textColor = [UIColor grayColor]; // 字体颜色 // 设置动画效果,可以设置 X 轴和 Y 轴的动画效果 [self.pieChartView animateWithYAxisDuration:1.0f]; } // 设置饼状图数据 - (PieChartData *)setData { int vals_count = 5; // 饼状图总共有几块组成 // 每个区块的数据,包含 区块名称 和 区块数据 NSMutableArray *chartVals1 = [[NSMutableArray alloc] init]; for (int i = 0; i < vals_count; i++) { NSString *partLabel = [NSString stringWithFormat:@"part%d", i]; // 设置区块名称 double partValue = arc4random() % 100; // 设置区块值 PieChartDataEntry *entry = [[PieChartDataEntry alloc] initWithValue:partValue label:partLabel]; [chartVals1 addObject:entry]; } // 绘制饼状图 // 创建 PieChartDataSet 对象 PieChartDataSet *set1 = [[PieChartDataSet alloc] initWithValues:chartVals1 label:nil]; // 设置区块 NSMutableArray *colors = [[NSMutableArray alloc] init]; [colors addObjectsFromArray:ChartColorTemplates.vordiplom]; [colors addObjectsFromArray:ChartColorTemplates.joyful]; [colors addObjectsFromArray:ChartColorTemplates.colorful]; [colors addObjectsFromArray:ChartColorTemplates.liberty]; [colors addObjectsFromArray:ChartColorTemplates.pastel]; [colors addObject:[UIColor colorWithRed:51/255.f green:181/255.f blue:229/255.f alpha:1.f]]; set1.colors = colors; // 设置区块颜色 set1.sliceSpace = 0; // 相邻区块之间的间距 set1.selectionShift = 8; // 选中区块时, 放大的半径 // 设置区块名称 set1.xValuePosition = PieChartValuePositionInsideSlice; // 区块名称位置 set1.entryLabelColor = [UIColor redColor]; // 区块名称颜色 set1.entryLabelFont = [UIFont systemFontOfSize:15]; // 区块名称字体 // 设置区块数据 set1.drawValuesEnabled = YES; // 是否绘制显示数据 set1.yValuePosition = PieChartValuePositionOutsideSlice; // 区块数据位置 // 数据与区块之间的用于指示的折线样式 set1.valueLinePart1OffsetPercentage = 0.85; // 折线中第一段起始位置相对于区块的偏移量, 数值越大, 折线距离区块越远 set1.valueLinePart1Length = 0.5; // 折线中第一段长度占比 set1.valueLinePart2Length = 0.4; // 折线中第二段长度最大占比 set1.valueLineWidth = 1; // 折线的粗细 set1.valueLineColor = [UIColor brownColor]; // 折线颜色 // 将 PieChartDataSet 对象放入数组中 NSMutableArray *dataSets = [[NSMutableArray alloc] init]; [dataSets addObject:set1]; // 创建 PieChartData 对象, 此对象就是 PieChartData 需要最终数据对象 PieChartData *data = [[PieChartData alloc] initWithDataSets:dataSets]; [data setValueFont:[UIFont systemFontOfSize:10]]; [data setValueTextColor:[UIColor brownColor]]; // 自定义数据显示格式 ChartDataValueFormatter *formatter = [[ChartDataValueFormatter alloc] init];// 统一设置数据显示的格式 [data setValueFormatter:formatter]; return data; } #pragma mark - ChartViewDelegate // 点击选中柱形图时的代理方法 - (void)chartValueSelected:(ChartViewBase * _Nonnull)chartView entry:(ChartDataEntry * _Nonnull)entry highlight:(ChartHighlight * _Nonnull)highlight { } // 没有选中柱形图时的代理方法,当选中一个柱形图后,在空白处双击,就可以取消选择,此时会回调此方法 - (void)chartValueNothingSelected:(ChartViewBase * _Nonnull)chartView { } // 捏合放大或缩小柱形图时的代理方法 - (void)chartScaled:(ChartViewBase * _Nonnull)chartView scaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY { } // 拖拽图表时的代理方法 - (void)chartTranslated:(ChartViewBase * _Nonnull)chartView dX:(CGFloat)dX dY:(CGFloat)dY { } @end 如果不需要空心样式的饼状图, 可以将饼状图的 drawHoleEnabled 赋值为 NO, 将中间的文本去掉即可。
// 饼状图是否是空心 self.pieChartView.drawHoleEnabled = NO;
每个区块之间如果需要间距, 可以通过 dataSet 对象的 sliceSpace 属性设置,
// 相邻区块之间的间距 set1.sliceSpace = 4;
6、绘制雷达图
XAxisValueFormatter.h
/// 设置 X 轴 数据格式 @import Charts; @interface XAxisValueFormatter : NSObject
@end XAxisValueFormatter.m
@implementation XAxisValueFormatter /// 实现协议方法,返回 x 轴的数据 - (NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis { // value 为 x 轴的值 return [NSString stringWithFormat:@"%ld 月", (NSInteger)value + 1]; } @end
ChartDataValueFormatter.h
/// 设置 折线显示的 数据格式 @import Charts; @interface ChartDataValueFormatter : NSObject
@end ChartDataValueFormatter.m
@implementation ChartDataValueFormatter /// 实现协议方法,返回辐射线拐点上显示的数据格式 - (NSString * _Nonnull)stringForValue:(double)value entry:(ChartDataEntry * _Nonnull)entry dataSetIndex:(NSInteger)dataSetIndex viewPortHandler:(ChartViewPortHandler * _Nullable)viewPortHandler { return [NSString stringWithFormat:@"%.0f%%", entry.y]; } @end
ViewController.m
#import "ChartsDemo-Bridging-Header.h" // 自定义数据格式 #import "XAxisValueFormatter.h" #import "ChartDataValueFormatter.h" // 遵守协议 @interface ViewController ()
// 雷达图 @property (nonatomic, strong) RadarChartView *radarChartView; // 滑动时 Y 值标签 @property (nonatomic,strong) UILabel *markYLabel; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1]; // 创建雷达图 [self createdPieView]; // 设置雷达图的数据 self.radarChartView.data = [self setData]; } // 创建雷达图 - (void)createdPieView { // 初始化雷达图对象 self.radarChartView = [[RadarChartView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width - 20, 400)]; self.radarChartView.center = self.view.center; [self.view addSubview:self.radarChartView]; // 设置基本样式 self.radarChartView.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1]; self.radarChartView.delegate = self; // 设置代理,需遵守 ChartViewDelegate 协议 self.radarChartView.noDataText = @"暂无数据"; // 没有数据时的文字提示 // 设置交互样式 self.radarChartView.rotationEnabled = YES; // 是否允许转动 self.radarChartView.highlightPerTapEnabled = YES; // 是否能被选中 // 设置雷达图线条样式 self.radarChartView.webLineWidth = 1.0; // 主干线线宽,辐射线 self.radarChartView.webColor = [UIColor lightGrayColor]; // 主干线颜色 self.radarChartView.innerWebLineWidth = 1.0; // 边线宽度,圆形线 self.radarChartView.innerWebColor = [UIColor lightGrayColor]; // 边线颜色 self.radarChartView.webAlpha = 0.5; // 雷达图线的透明度 // 设置滑动时 Y 值标签 ChartMarkerView *markerY = [[ChartMarkerView alloc] init]; markerY.offset = CGPointMake(-17, -25); // 设置显示位置 markerY.chartView = self.radarChartView; [markerY addSubview:self.markYLabel]; self.radarChartView.marker = markerY; // 设置 X 轴 label 样式,由中心向外延伸的线 ChartXAxis *xAxis = self.radarChartView.xAxis; xAxis.valueFormatter = [[XAxisValueFormatter alloc] init]; // label 文字样式,自定义格式,默认时不显示特殊符号 xAxis.labelFont = [UIFont systemFontOfSize:15]; // 字体 xAxis.labelTextColor = [UIColor colorWithRed:5/255.0f green:119/255.0f blue:72/255.0f alpha:1]; // 颜色 // 设置 Y 轴 label 样式,圆形的线 ChartYAxis *yAxis = self.radarChartView.yAxis; yAxis.axisMinValue = 0.0; // 最小值,中心的值 yAxis.axisMaxValue = 100.0; // 最大值,最外边的值 yAxis.drawLabelsEnabled = YES; // 是否显示 label 值 yAxis.labelCount = 5; // label 个数 yAxis.labelFont = [UIFont systemFontOfSize:9]; // label 字体 yAxis.labelTextColor = [UIColor lightGrayColor]; // label 颜色 // 设置雷达图描述 self.radarChartView.chartDescription.enabled = YES; // 显示雷达图描述,默认 YES 显示 self.radarChartView.descriptionText = @"雷达图"; self.radarChartView.descriptionFont = [UIFont systemFontOfSize:15]; self.radarChartView.descriptionTextColor = [UIColor grayColor]; // 设置雷达图图例 self.radarChartView.legend.enabled = YES; // 显示图例,默认 YES 显示 self.radarChartView.legend.form = ChartLegendFormCircle; // 图示样式: 方形、线条、圆形 self.radarChartView.legend.formSize = 12; // 图示大小 self.radarChartView.legend.position = ChartLegendPositionBelowChartCenter; // 图例在雷达图中的位置 self.radarChartView.legend.maxSizePercent = 1; // 图例在雷达图中的大小占比, 这会影响图例的宽高 self.radarChartView.legend.formToTextSpace = 5; // 文本间隔 self.radarChartView.legend.font = [UIFont systemFontOfSize:10]; // 字体大小 self.radarChartView.legend.textColor = [UIColor grayColor]; // 字体颜色 // 设置动画效果,可以设置 X 轴和 Y 轴的动画效果 [self.radarChartView animateWithXAxisDuration:1.4 yAxisDuration:1.4 easingOption:ChartEasingOptionEaseOutBack]; } // 设置雷达图数据 - (RadarChartData *)setData { int vals_count = 12; // 维度的个数 // 每个维度的名称或描述 NSMutableArray *chartVals1 = [[NSMutableArray alloc] init]; for (int i = 0; i < vals_count; i++) { double partValue = arc4random() % 70 + 30; // 设置区块值 RadarChartDataEntry *entry = [[RadarChartDataEntry alloc] initWithValue:partValue]; [chartVals1 addObject:entry]; } // 绘制雷达图 // 创建 RadarChartDataSet 对象 RadarChartDataSet *set1 = [[RadarChartDataSet alloc] initWithValues:chartVals1 label:@"RadarName 1"]; // 设置数据块 set1.lineWidth = 0.5; // 数据折线线宽 [set1 setColor:[UIColor redColor]]; // 数据折线颜色 set1.drawFilledEnabled = YES; // 是否填充颜色 set1.fillColor = [UIColor orangeColor]; // 填充颜色 set1.fillAlpha = 0.5; // 填充透明度 // 设置数据块折点样式 set1.drawHighlightCircleEnabled = NO; // 是否绘制选中的拐点处的圆形 set1.highlightCircleStrokeColor = [UIColor greenColor]; // 拐点处的圆形颜色 [set1 setDrawHighlightIndicators:NO]; // 是否绘制选中拐点处的十字线 // 设置显示数据 set1.drawValuesEnabled = YES; // 是否绘制显示数据 set1.valueFont = [UIFont systemFontOfSize:9]; // 字体 set1.valueTextColor = [UIColor grayColor]; // 颜色 // 创建 RadarChartData 对象, 此对象就是 PieChartData 需要最终数据对象 RadarChartData *data = [[RadarChartData alloc] initWithDataSets:@[set1]]; [data setValueFont:[UIFont systemFontOfSize:15]]; [data setValueTextColor:[UIColor brownColor]]; // 自定义数据显示格式 ChartDataValueFormatter *formatter = [[ChartDataValueFormatter alloc] init];// 统一设置数据显示的格式 [data setValueFormatter:formatter]; return data; } #pragma mark - ChartViewDelegate // 点击选中柱形图时的代理方法 - (void)chartValueSelected:(ChartViewBase * _Nonnull)chartView entry:(ChartDataEntry * _Nonnull)entry highlight:(ChartHighlight * _Nonnull)highlight { // 设置滑动时 Y 值标签 self.markYLabel.text = [NSString stringWithFormat:@"%ld%%", (NSInteger)entry.y]; } // 没有选中柱形图时的代理方法,当选中一个柱形图后,在空白处双击,就可以取消选择,此时会回调此方法 - (void)chartValueNothingSelected:(ChartViewBase * _Nonnull)chartView { } // 捏合放大或缩小柱形图时的代理方法 - (void)chartScaled:(ChartViewBase * _Nonnull)chartView scaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY { } // 拖拽图表时的代理方法 - (void)chartTranslated:(ChartViewBase * _Nonnull)chartView dX:(CGFloat)dX dY:(CGFloat)dY { } // 懒加载滑动时 Y 值标签 - (UILabel *)markYLabel { if (!_markYLabel) { _markYLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, -5, 35, 25)]; _markYLabel.font = [UIFont systemFontOfSize:15.0]; _markYLabel.textAlignment = NSTextAlignmentCenter; _markYLabel.text = @""; _markYLabel.textColor = [UIColor whiteColor]; _markYLabel.backgroundColor = [UIColor grayColor]; } return _markYLabel; } @end