在我们开发过程中有些时候要绘制折线图或条形图,要是做金融类的难免要接触到K线图今天我就来谈谈我的经验首先我们先花2分钟来看看这一幅图
在初中我们就知道 点动成线 线动成面 在这里我们把每一个点称之为实体(Entry) 而相应的每个实体有对应的下标和值
我们把实体的集合称之为数据集(Dataset) 而其又有2个属性 一个是实体的图例 另外一个是存放实体的数组而数据集的集合名为图表数据(Data) 其2个属性分别为 x标签数组 与 存放数据集的数组最后我们把图表数据发在图表(chart)里就大功告成了
首先我们可以定义一个类 这个类里你只需输入自己想要画的表的类型和数据的个数
调用代码如下
JPChart * myChart = [JPChart chartWithCount:16 chartType:LineChartType];
myChart.frame = CGRectMake(0, 100, self.view.frame.size.width-20, 300);
[self.view addSubview:myChart];
实现代码如下
.h
typedef NS_ENUM(NSUInteger, JPChartType) {
LineChartType, // 折线图类型
BarChartType, // 柱形图类型
CandleChartType // 烛噬图类型
};
/**
根据类型和实体数量创建一个图表
@param count 实体的个数
@param type 图表的类型
@return 图表对象
*/
+ (JPChart *)chartWithCount:(NSInteger)count chartType:(JPChartType)type;
.m
/**
根据类型和实体数量创建一个图表
@param count 实体的个数
@param type 图表的类型
@return 图表对象
*/
+ (JPChart *)chartWithCount:(NSInteger)count chartType:(JPChartType)type{
JPChart * chart = [JPChart new];
switch (type) {
case LineChartType:
{
// 折线图
JPLineChart * lineChart = [JPLineChart lineChartWithNumber:count];
[chart addSubview:lineChart];
[lineChart mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.bottom.mas_offset(0);
}];
}
break;
case BarChartType:
{
// 柱状图
JPBarChart * barChart = [JPBarChart barChartWithNumber:count];
[chart addSubview:barChart];
[barChart mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.bottom.mas_offset(0);
}];
}
break;
case CandleChartType:
{
JPCandleChart * candleChar = [JPCandleChart candleChartWithNumber:count];
[chart addSubview:candleChar];
[candleChar mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.bottom.mas_offset(0);
}];
}
break;
default:
break;
}
return chart;
}
1.先说一下折线图
如果没对数据集和表进行UI的设置 那么出来就是这样子的
我们可以根据自己的需求来设置 我demo里的最终结果是这样子的
折线图的.h
/**
创建一个lineChart对象
@return 对象
*/
+ (JPLineChart *)lineChart;
/**
根据参数的个数返回带N点的折线图
@param count 点的个数
@return 对象
*/
+ (JPLineChart *)lineChartWithNumber:(NSInteger)count;
.m
#import#import
#import "SYBaseLineView.h
"#import "JPBubbleView.h"
@interface JPLineChart ()
/** 折线图表 **/
@property (nonatomic, strong) LineChartView * lineChart;
/** 折线数据集 **/
@property (nonatomic, strong) LineChartDataSet * dataSet;
/** 折线数据 **/
@property (nonatomic, strong) LineChartData * data;
@end@implementation JPLineChart
#pragma mark - =============生命周期================
-(instancetype)init{
if (self = [super init]) {
NSLog(@"init");
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
NSLog(@"init frame");
[self initUI];
}
return self;
}
#pragma mark - =============代理方法=================
#pragma mark - IChartAxisValueFormatter
-(NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis{
if(_lineChart.leftAxis == axis){
return [NSString stringWithFormat:@"左%.0f个",value];
}
if(_lineChart.rightAxis == axis){
return [NSString stringWithFormat:@"右%.0f个",value];
}
if (_lineChart.xAxis == axis) {
return [NSString stringWithFormat:@"第%.0f天",value];
}
return @"";
}
#pragma mark - IChartFillFormatter
-(CGFloat)getFillLinePositionWithDataSet:(id)dataSet dataProvider:(id)dataProvider{
return 5;
}
#pragma mark - IChartValueFormatter
-(NSString *)stringForValue:(double)value entry:(ChartDataEntry *)entry dataSetIndex:(NSInteger)dataSetIndex viewPortHandler:(ChartViewPortHandler *)viewPortHandler{
return [NSString stringWithFormat:@"*%.0f",value];
}
#pragma mark - =============事件处理=================
#pragma mark - =============网络数据处理==============
#pragma mark - =============声明的成员方法和类方法======
/**
创建一个lineChart对象
@return 对象
*/
+ (JPLineChart *)lineChart{
JPLineChart * chart = [JPLineChart new];
return chart;
}
/**
根据参数的个数返回带N点的折线图
@param count 点的个数
@return 对象
*/
+ (JPLineChart *)lineChartWithNumber:(NSInteger)count{
JPLineChart * chart = [JPLineChart new];
[chart creatDataWithNumber:count];
return chart;
}
#pragma mark - =============私有方法=================
/**
初始化UI
*/
- (void)initUI{
//------ 创建一个图表 ------//
[self addSubview:self.lineChart];
[_lineChart mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.centerY.mas_offset(0);
make.left.right.mas_offset(0);
make.height.mas_equalTo(300);
}];
//------ 添加背景虚线 ------//
SYBaseLineView *chartBaseView = [[SYBaseLineView alloc] initWithFrame:_lineChart.frame backColor:[UIColor clearColor] lineColor:[UIColor colorWithWhite:0.600 alpha:1.000] horizonLines:3 viticalLines:3];
chartBaseView.backgroundColor = [UIColor whiteColor];
[self addSubview:chartBaseView];
[self bringSubviewToFront:_lineChart];
[chartBaseView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.left.right.mas_equalTo(_lineChart);
}];
}
/**
创建数据
@param number 点的个数
*/
- (void)creatDataWithNumber:(NSInteger)number{
//------ 初始化数组 ------//
NSMutableArray *entryArray = [NSMutableArray new];
// 实例化实体
for (int i = 0 ; i < number; i++) {
ChartDataEntry * entry = [[ChartDataEntry alloc] initWithX:i y:arc4random()%10];
[entryArray addObject:entry];
}
// 生成一个数据集
_dataSet = [[LineChartDataSet alloc] initWithValues:entryArray label:@"折线"];
[self dataSetSetting];
// 生成一个赋值给图表的数据
_data = [[LineChartData alloc] initWithDataSet:self.dataSet];
// 赋值给图表
_lineChart.data = self.data;
}
/**
数据集设置
*/
- (void)dataSetSetting{
// 画圆设置
_dataSet.drawCircleHoleEnabled = NO;
_dataSet.drawCirclesEnabled = NO;
// 要上面为yes才有效果
_dataSet.circleColors = @[[UIColor redColor],[UIColor greenColor],[UIColor blueColor]];
_dataSet.circleHoleColor = [UIColor blueColor];
// 线的设置
// _dataSet.fillColor = [UIColor lightGrayColor];
// _dataSet.fillFormatter = self; // ->IChartFillFormatter
_dataSet.drawFilledEnabled = YES;
_dataSet.colors = @[[UIColor blackColor]];
_dataSet.lineWidth = 2;
_dataSet.drawCubicEnabled = YES; // 圆滑处理
//------ 填充渐变色 ------//
NSArray *gradientColors = @[
(id)[UIColor colorWithRed:1.000 green:0.886 blue:0.520 alpha:1].CGColor,
(id)[UIColor colorWithRed:1.000 green:0.286 blue:0.020 alpha:1.000].CGColor
];
CGGradientRef gradient = CGGradientCreateWithColors(nil, (CFArrayRef)gradientColors, nil);
_dataSet.fillAlpha = 0.5f;
_dataSet.fill = [ChartFill fillWithLinearGradient:gradient angle:90.f];
_dataSet.drawFilledEnabled = YES;
//------ 值的格式化 ------//
// _dataSet.valueFormatter = self;
_dataSet.drawValuesEnabled = NO;
//------ 高亮线的设置 ------//
_dataSet.highlightColor = [UIColor redColor];
_dataSet.highlightLineWidth = 2;
_dataSet.drawHorizontalHighlightIndicatorEnabled = NO; //开启了就是 + 的效果
}
#pragma mark - =============访问器方法===============
- (LineChartView *)lineChart{
if (!_lineChart) {
_lineChart = [LineChartView new];
// 这里写图表的设置
_lineChart.backgroundColor = [UIColor clearColor];
// X轴显示与否
_lineChart.xAxis.drawLabelsEnabled = YES;
// _lineChart.xAxis.enabled = NO;
_lineChart.xAxis.valueFormatter = self;
// Y轴不显示值
_lineChart.leftAxis.enabled = YES;
_lineChart.rightAxis.enabled = NO;
_lineChart.leftAxis.drawLabelsEnabled = YES;
_lineChart.rightAxis.drawLabelsEnabled = NO;
_lineChart.leftAxis.valueFormatter = self;
_lineChart.rightAxis.valueFormatter = self;
// 显示X轴在下面
_lineChart.xAxis.labelPosition = XAxisLabelPositionBottom;
// 网格设置
_lineChart.xAxis.drawGridLinesEnabled = NO;
_lineChart.leftAxis.gridLineDashLengths = @[@5,@10];
_lineChart.rightAxis.drawGridLinesEnabled = NO;
_lineChart.leftAxis.drawGridLinesEnabled = NO;
// 标签说明
ChartDescription * des = [[ChartDescription alloc] init];
des.text = @"JP图表";
des.textAlign = NSTextAlignmentCenter;
des.textColor = [UIColor redColor];
_lineChart.chartDescription = des;
// 图例样式
_lineChart.legend.form = ChartLegendFormEmpty;
//------ 小气泡 ------//
JPBubbleView * bView = [JPBubbleView bubbleViewWithTarget:_lineChart];
_lineChart.marker = bView;
/*
BalloonMarker *marker = [[BalloonMarker alloc]
initWithColor: [UIColor colorWithWhite:180/255. alpha:1.0]
font: [UIFont systemFontOfSize:12.0]
textColor: UIColor.whiteColor
insets: UIEdgeInsetsMake(8.0, 8.0, 20.0, 8.0)];
marker.chartView = _chartView;
marker.minimumSize = CGSizeMake(80.f, 40.f);
_chartView.marker = marker;
*/
}
return _lineChart;
}
//为什么x只有一个 y有2个? 因为y有些时候是显示两种不同的内容
其中JPBubbleView的代码如下
.h
#import#import
@interface JPBubbleView : UIView
+ (id)bubbleViewWithTarget:(ChartViewBase *)target;
//- (void)setValue:(NSString *)value;
@end
.m
#import "JPBubbleView.h"#import@interface JPBubbleView()
/** 标签 **/
@property (nonatomic, strong) UILabel * label;
/** 父视图 **/
@property (nonatomic, strong) ChartViewBase * superChart;
@end
@implementation JPBubbleView
-(CGPoint)offset{
return CGPointZero;
}
- (CGPoint)offsetForDrawingAtPoint:(CGPoint)atPoint{
NSLog(@"offsetForDrawingAtPoint");
return atPoint;
}
- (void)refreshContentWithEntry:(ChartDataEntry * _Nonnull)entry highlight:(ChartHighlight * _Nonnull)highlight{
[self setValue:[NSString stringWithFormat:@"%.0f",entry.y]];
NSLog(@"refreshContentWithEntry");
}
- (void)drawWithContext:(CGContextRef _Nonnull)context point:(CGPoint)point{
self.frame = CGRectMake(point.x, point.y, 80, 50);
[_superChart addSubview:self];
NSLog(@"drawWithContext");
}
+ (id)bubbleViewWithTarget:(ChartViewBase *)target{
JPBubbleView * bview = [JPBubbleView new];
bview.superChart = target;
[bview setUI];
return bview;
}
- (void)setUI{
[self addSubview:self.label];
[_label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.bottom.mas_offset(0);
}];
}
- (void)setValue:(NSString *)value{
// _label.text = value;
NSMutableAttributedString * attrStr1 = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@" %@",value]];
[attrStr1 addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, attrStr1.string.length)];
// 创建一个文字附件对象
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:@"ll.png"]; //设置图片源
textAttachment.bounds = CGRectMake(0, - 7, 27, 27); //设置图片位置和大小
// 将文字附件转换成属性字符串
NSAttributedString *attachmentAttrStr = [NSAttributedString attributedStringWithAttachment:textAttachment];
// 将转换成属性字符串插入到目标字符串
[attrStr1 insertAttributedString:attachmentAttrStr atIndex:0];
_label.attributedText = attrStr1;
}
-(UILabel *)label{
if (!_label) {
_label = [UILabel new];
}
return _label;
}
柱状图
柱状图和折线图差不多的 一般情况下只是把表名改一下就可以了
烛噬图
烛噬图的代码因为时间原因 没做多少准备 但不少设置是和折线图一样的
烛噬图的代码如下
.h
/**
创建一个JPCandleChart对象
@return 对象
*/
+ (JPCandleChart *)candleChart;
/**
根据参数的个数返回带N点的折线图
@param count 点的个数
@return 对象
*/
+ (JPCandleChart *)candleChartWithNumber:(NSInteger)count;
.m
#import "JPCandleChart.h"#import#import@interface JPCandleChart()
/** 图表 **/
@property (nonatomic, strong) CandleStickChartView * barChart;
/** 数据集 **/
@property (nonatomic, strong) CandleChartDataSet * dataSet;
/** 数据 **/
@property (nonatomic, strong) CandleChartData * data;
@end
@implementation JPCandleChart
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
NSLog(@"init frame");
[self initUI];
}
return self;
}
/**
创建一个Chart对象
@return 对象
*/
+ (JPCandleChart *)barChart{
JPCandleChart * chart = [JPCandleChart new];
return chart;
}
/**
根据参数的个数返回带N点的折线图
@param count 点的个数
@return 对象
*/
+ (JPCandleChart *)candleChartWithNumber:(NSInteger)count{
JPCandleChart * chart = [JPCandleChart new];
[chart creatDataWithNumber:count];
return chart;
}
/**
初始化UI
*/
- (void)initUI{
//------ 创建一个图表 ------//
[self addSubview:self.barChart];
[_barChart mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.centerY.mas_offset(0);
make.left.right.mas_offset(0);
make.height.mas_equalTo(300);
}];
}
/**
创建数据
@param number 点的个数
*/
- (void)creatDataWithNumber:(NSInteger)number{
//------ 初始化数组 ------//
NSMutableArray *entryArray = [NSMutableArray new];
// 实例化实体
for (int i = 0 ; i < number; i++) {
CandleChartDataEntry * entry = [[CandleChartDataEntry alloc]initWithX:i shadowH:i+1 shadowL:-6 open:i close:2];
//h最高 l最低 开盘 关盘(收盘)
[entryArray addObject:entry];
}
// 生成一个数据集
_dataSet = [[CandleChartDataSet alloc] initWithValues:entryArray label:@"烛噬"];
_dataSet.shadowColor = [UIColor blackColor]; //中心线的颜色
// _dataSet.valueColors = @[[UIColor redColor],[UIColor greenColor]];
// _dataSet.neutralColor = [UIColor greenColor];
// _dataSet.highlightColor = [UIColor redColor];
_dataSet.decreasingColor = [UIColor redColor];
_dataSet.increasingColor = [UIColor greenColor];
// 生成一个赋值给图表的数据
_data = [[CandleChartData alloc] initWithDataSet:self.dataSet];
// 赋值给图表
_barChart.data = self.data;
}
#pragma mark - 访问器
-(CandleStickChartView *)barChart{
if (!_barChart) {
_barChart = [CandleStickChartView new];
}
return _barChart;
}
@end