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 框架。
-
解压后的文件夹里面的内容是这个样子的,如下图。
-
下载完成后,仔细看一下所需环境,很重要!如下图。
-
在自己的工程中使用的时候可以删掉框架中的 Demo 等文件,如下图。
-
-
2、新建工程,导入 Charts.xcodeproj 工程
-
新建工程,取名为 ChartsDemo。复制 Charts 整个文件到 ChartsDemo 工程中
-
将 Charts 文件夹中的 Charts.xcodeproj 工程文件导入到 ChartsDemo 工程中,注意导入的是 Charts.xcodeproj 工程,而不是 Charts 的文件夹,如下图。
-
-
3、编译导入的 Charts.xcodeproj 工程
-
选中 Charts.xcodeproj 工程,在 TARGETS => Build Setting => Architectures => Base SDK 中设置 SDKs 为 iOS 环境。
-
在编译选项中选中 Charts => Generic iOS Devices 进行编译,编译成功后可以看到 Charts.xcodeproj 工程的 Products 中 Charts.framework 由红色变为黑色。
-
-
4、添加 Charts.framework
-
在 ChartsDemo 工程的 TARGETS => General => Embedded Binaries 中,点击 + 号添加 iOS 的 Charts.framework,如下图。
-
-
5、建立 OC 和 Swift 的桥接文件
-
在 ChartsDemo 工程中新建一个 Swift 文件,名字随便取,这时候会提示是否建立桥接文件,直接选 Create Bridging Header 选项,如下图。
-
创建完成后删除刚才创建的 Swift 文件,然后在桥接头文件中添加 Charts 引入。
-
在使用 Charts 的文件中引入桥接头文件。引入完成之后,选择 iOS 模拟器编译一下,如果有错,Clean 一下再次编译,编译没有错误说明导入成功。
-
-
6、测试
-
在 ViewController.m 中进行测试,代码如下。
BarChartView *barChatView = [[BarChartView alloc] initWithFrame:CGRectMake(10, 100, 300, 300)]; barChatView.backgroundColor = [UIColor cyanColor]; [self.view addSubview:barChatView];
-
效果如下。由于没有给数据,所以显示的是 No chart date aviailable。至此,集成 Charts 完毕。
-
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 <IChartAxisValueFormatter> @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 <Foundation/Foundation.h> @import Charts; @interface XAxisValueFormatter : NSObject <IChartAxisValueFormatter> @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<id <IChartDataSet>> * _Nullable)dataSets
发现还需要一个装有 LineChartDataSet 的数组,LineChartDataSet 其实就是每一条折线,而绘制每一条折线又需要数据,所以我们先从数据开始一步一步创建。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 <IChartValueFormatter> - (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 <IChartAxisValueFormatter> @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 <IChartAxisValueFormatter> @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 <IChartValueFormatter> @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 <IChartValueFormatter> - (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 () <ChartViewDelegate> // 折线图 @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 <IChartAxisValueFormatter> @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 <IChartAxisValueFormatter> @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 <IChartValueFormatter> @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 <IChartValueFormatter> - (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 () <ChartViewDelegate> // 柱状图 @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 <IChartValueFormatter> @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 () <ChartViewDelegate> // 饼状图 @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 <IChartAxisValueFormatter> @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 <IChartValueFormatter> @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 () <ChartViewDelegate> // 雷达图 @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
-
效果
-