在我們開發(fā)過程中有些時候要繪制折線圖或條形圖,要是做金融類的難免要接觸到K線圖今天我就來談談我的經驗首先我們先花2分鐘來看看這一幅圖

在初中我們就知道 點動成線 線動成面 在這里我們把每一個點稱之為實體(Entry) 而相應的每個實體有對應的下標和值
我們把實體的集合稱之為數據集(Dataset) 而其又有2個屬性 一個是實體的圖例 另外一個是存放實體的數組而數據集的集合名為圖表數據(Data) 其2個屬性分別為 x標簽數組 與 存放數據集的數組最后我們把圖表數據發(fā)在圖表(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 // 燭噬圖類型
};
/**
根據類型和實體數量創(chuàng)建一個圖表
@param count 實體的個數
@param type 圖表的類型
@return 圖表對象
*/
+ (JPChart *)chartWithCount:(NSInteger)count chartType:(JPChartType)type;
.m
/**
根據類型和實體數量創(chuàng)建一個圖表
@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里的最終結果是這樣子的

CC22E60E-79D1-4461-9583-DAC6326420AD.png
折線圖的.h
/**
創(chuàng)建一個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 - =============聲明的成員方法和類方法======
/**
創(chuàng)建一個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{
//------ 創(chuàng)建一個圖表 ------//
[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);
}];
}
/**
創(chuàng)建數據
@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)];
// 創(chuàng)建一個文字附件對象
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
/**
創(chuàng)建一個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;
}
/**
創(chuàng)建一個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{
//------ 創(chuàng)建一個圖表 ------//
[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);
}];
}
/**
創(chuàng)建數據
@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