美文网首页iOS 知识点
绘制K线图看我就对了

绘制K线图看我就对了

作者: 小沛2016 | 来源:发表于2017-07-03 14:25 被阅读948次

    在我们开发过程中有些时候要绘制折线图或条形图,要是做金融类的难免要接触到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里的最终结果是这样子的

    CC22E60E-79D1-4461-9583-DAC6326420AD.png

    折线图的.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
    

    代码

    相关文章

      网友评论

      本文标题:绘制K线图看我就对了

      本文链接:https://www.haomeiwen.com/subject/zsoacxtx.html