iOS 折線圖實現,虛線,漸層色填充,線條動畫

來源:互聯網
上載者:User
效果圖 Demo地址

Demo主要實現了一下幾點功能 1.折線圖 + stroke動畫 + 可左右滾動 2.虛線標註 3.漸層蒙層填充 4.小圓點展示 + 點擊放大動畫 如果以上效果有滿足您當前需要請往下看 拆分介面 調用樣本

- (NXLineChartView * )chartView{    if (!_chartView) {        _chartView = [[NXLineChartView alloc]init];        _chartView.backgroundColor = [UIColor whiteColor];        _chartView.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/2);        _chartView.bounds = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width-100, 200);        _chartView.lineChartXLabelArray = @[@"魅族",@"華為",@"中興",@"小米",@"蘋果",@"一加",@"樂視",@"音樂",@"電視",@"體育"];        _chartView.lineChartYLabelArray = @[];        _chartView.LineChartDataArray   = @[@100,@40,@60,@45,@100,@55,@33,@120,@40,@100];    }    return _chartView;}
#import <UIKit/UIKit.h>@interface NXLineChartView : UIView@property (nonatomic, strong) NSArray * lineChartYLabelArray;@property (nonatomic, strong) NSArray * lineChartXLabelArray; // X軸資料@property (nonatomic, strong) NSArray * LineChartDataArray; // 資料來源@end
1.畫折線,這裡通過UIBezierPath和CAShapeLayer結合繪圖 先建立可左右滾動的scrollView

//可滾動視圖- (UIScrollView *)mainScroll{    if (!_mainScroll) {        _mainScroll = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];        _mainScroll.showsVerticalScrollIndicator = NO;        _mainScroll.showsHorizontalScrollIndicator = NO;        [self addSubview:_mainScroll];    }    return _mainScroll;}
通過LineChartDataArray獲得的資料,進行繪製

// 設定折線圖- (void)setLineChartDataArray:(NSArray *)LineChartDataArray{    _LineChartDataArray = LineChartDataArray;    if (!_LineChartDataArray) return;   // [self drawGragient];    UIBezierPath * bezierPath = [self getPath];    CAShapeLayer * layers = [CAShapeLayer layer];    layers.path = bezierPath.CGPath;    layers.lineWidth = 2.0;    layers.strokeColor = [UIColor redColor].CGColor;    layers.fillColor = [UIColor clearColor].CGColor;    [self doAnimationWithLayer:layers];    [self.mainScroll.layer addSublayer:layers];   // self.gredientView.layer.mask = layers;    [self addTopPointButton]; // 小圓點    [self drawGredientLayer]; // 漸層}- (UIBezierPath *)getPath{    self.topPointArray = [[NSMutableArray alloc]init];    UIBezierPath * bezierPath = [UIBezierPath bezierPath];    for (int idx =0; idx<_LineChartDataArray.count; idx++) {        if (idx == 0) {            CGPoint startPoint = CGPointMake([_pointXArray[0] floatValue], self.frame.size.height-[_LineChartDataArray[0] floatValue]-bottomMarginScale);            [bezierPath moveToPoint:startPoint];            [self.topPointArray addObject:[NSValue valueWithCGPoint:startPoint]];        }else{            CGPoint point = CGPointMake([_pointXArray[idx] floatValue], self.frame.size.height-[_LineChartDataArray[idx] floatValue]-bottomMarginScale);            [bezierPath addLineToPoint:point];            [self.topPointArray addObject:[NSValue valueWithCGPoint:point]];        }    }    return bezierPath;}
線條動畫採用核心動畫strokeEnd這個效果實現,代碼如下
- (void)doAnimationWithLayer:(CAShapeLayer *)layer{    CABasicAnimation * baseAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];    baseAnimation.duration = 2;    baseAnimation.fromValue = @0.0;    baseAnimation.toValue = @1.0;    baseAnimation.repeatCount = 1;    [layer addAnimation:baseAnimation forKey:@"strokeAnimation"];}
2.虛線標註

- (void)drawRect:(CGRect)rect {    CGContextRef ctx = UIGraphicsGetCurrentContext();    CGFloat yAxisOffset =  10.f;    CGPoint point;    CGFloat yStepHeight = rect.size.height / self.LineChartDataArray.count;    CGContextSetStrokeColorWithColor(ctx, [UIColor lightGrayColor].CGColor);    CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);    for (NSUInteger i = 0; i < _LineChartDataArray.count; i++) {        point = CGPointMake(10 + yAxisOffset, (rect.size.height - i * yStepHeight + 10 / 2));        CGContextMoveToPoint(ctx, point.x, point.y);        // add dotted style grid        CGFloat dash[] = {6, 5};        // dot diameter is 20 points        CGContextSetLineWidth(ctx, 0.5);        CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);        CGContextSetLineCap(ctx, kCGLineCapRound);        CGContextSetLineDash(ctx, 0.0, dash, 2);        // 這裡是改變虛線的寬度        CGRect frame = CGRectMake(rect.origin.x, rect.origin.y, self.totalWidth, rect.size.height);        CGContextAddLineToPoint(ctx, CGRectGetWidth(frame) - 5 + 5, point.y);        CGContextStrokePath(ctx);    }}
3.漸層蒙層填充

/* @parameter 背景顏色填充 */- (void)drawGredientLayer{    CAGradientLayer *gradientLayer = [CAGradientLayer layer];    gradientLayer.frame = CGRectMake(0, 0, self.totalWidth, self.frame.size.height-bottomMarginScale);    gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:250/255.0 green:170/255.0 blue:10/255.0 alpha:0.8].CGColor,(__bridge id)[UIColor colorWithWhite:1 alpha:0.4].CGColor];    gradientLayer.locations=@[@0.0,@1.0];    gradientLayer.startPoint = CGPointMake(0.0,0.0);    gradientLayer.endPoint = CGPointMake(1,0);    UIBezierPath *gradientPath = [UIBezierPath bezierPath];    [gradientPath moveToPoint:CGPointMake([_pointXArray[0] floatValue], self.frame.size.height-bottomMarginScale)];    for (int i=0; i<_LineChartDataArray.count; i++) {        [gradientPath addLineToPoint:CGPointMake([_pointXArray[i] floatValue], self.frame.size.height-[_LineChartDataArray[i] floatValue]-bottomMarginScale)];    }    [gradientPath addLineToPoint:CGPointMake([_pointXArray[_pointXArray.count-1] floatValue], self.frame.size.height-bottomMarginScale)];    CAShapeLayer *arc = [CAShapeLayer layer];    arc.path = gradientPath.CGPath;    gradientLayer.mask = arc;    [self.mainScroll.layer addSublayer:gradientLayer];}
4.小圓點展示 + 點擊放大動畫 小圓點

// 添加小圓點- (void)addTopPointButton{    if (self.topPointArray.count ==0) return;    for (int idx =0; idx<self.topPointArray.count; idx++) {        CGPoint point = [self.topPointArray[idx] CGPointValue];        UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];        button.center = point;        button.bounds = CGRectMake(0, 0, 10, 10);        button.layer.cornerRadius = 5;        button.clipsToBounds = YES;        button.backgroundColor = [UIColor cyanColor];        button.tag = GAP+idx;        [button setTitle:[self.LineChartDataArray[idx] stringValue] forState:UIControlStateNormal];        [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];        button.titleLabel.font = [UIFont systemFontOfSize:5];        button.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);        [button addTarget:self action:@selector(didSelectButtonClick:) forControlEvents:UIControlEventTouchUpInside];        [self.mainScroll addSubview:button];    }}
小圓點點擊放大動畫採用核心動畫scale

- (void)didSelectButtonClick:(UIButton *)sender{    for (id emptyObj in self.mainScroll.subviews) {        if ([emptyObj isKindOfClass:[UIButton class]]) {            UIButton * btn = (UIButton *)emptyObj;          //  btn.bounds = CGRectMake(0, 0, 5, 5);          //  [btn setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];            [btn.layer removeAllAnimations];        }    }    [self doScaleAnimationWithView:sender];    NSLog(@"%@",[self.LineChartDataArray[sender.tag-GAP] stringValue]);    [sender setTitle:[self.LineChartDataArray[sender.tag-GAP] stringValue] forState:UIControlStateNormal];    [sender setTitleColor:[UIColor redColor] forState:UIControlStateNormal];    sender.titleLabel.font = [UIFont systemFontOfSize:5];}- (void)doScaleAnimationWithView:(UIView *)view{    CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];    animation.duration = 0.3;    animation.values = @[@2,@1.5,@0.8,@1,@2];    animation.repeatCount = 2;    animation.fillMode = kCAFillModeForwards;    animation.removedOnCompletion = NO;    [view.layer addAnimation:animation forKey:@"scaleAnimations"];}
底部X座標軸資料填充

// 底部X視圖- (void)setLineChartXLabelArray:(NSArray *)lineChartXLabelArray{    _lineChartXLabelArray = lineChartXLabelArray;    if (!_lineChartXLabelArray) return;    _pointXArray = [[NSMutableArray alloc]init];   // CGFloat labelWidthScale = (self.frame.size.width-leftXMarginScale-rightXMarginScale)/_lineChartXLabelArray.count;    self.totalWidth =0;    for (int idx = 0; idx < _lineChartXLabelArray.count; idx ++) {        CGFloat labelWidthScale = [self getLabelWidthWithText:_lineChartXLabelArray[idx]];        CGFloat x = self.totalWidth+marginScale;        CGFloat y = self.frame.size.height- lineChartXlabelHeight;        UILabel * label = [[UILabel alloc]init];        label.frame = CGRectMake(x, y, labelWidthScale, lineChartXlabelHeight);        label.text = _lineChartXLabelArray[idx];        label.textAlignment = NSTextAlignmentCenter;        label.textColor = [UIColor redColor];        label.font = [UIFont systemFontOfSize:fontSize];        [_pointXArray addObject:[NSString stringWithFormat:@"%.f",label.center.x]];        [self.mainScroll addSubview:label];        self.totalWidth = label.frame.origin.x+label.frame.size.width;        [self.mainScroll setContentSize:CGSizeMake(CGRectGetMaxX(label.frame), 0)];    }}
再看下調用樣本比較簡單
- (NXLineChartView * )chartView{    if (!_chartView) {        _chartView = [[NXLineChartView alloc]init];        _chartView.backgroundColor = [UIColor whiteColor];        _chartView.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/2);        _chartView.bounds = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width-100, 200);        _chartView.lineChartXLabelArray = @[@"魅族",@"華為",@"中興",@"小米",@"蘋果",@"一加",@"樂視",@"音樂",@"電視",@"體育"];        _chartView.lineChartYLabelArray = @[];        _chartView.LineChartDataArray   = @[@100,@40,@60,@45,@100,@55,@33,@120,@40,@100];    }    return _chartView;}

Demo地址

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.