折线图-带阴影

折线图-带阴影_第1张图片
lineGraphSingle.png

折线图-带阴影_第2张图片
LineGraph.png

源码 参考


在iOS开发的各种app中,会有项目要求我们去做折线去展示我们最近数据,下面跟大家介绍下如何根据数据在IOS 端进行绘制折线图


下面开始介绍如何绘制折线图,达到以上的效果。


第一步:数据传递,这里很简单 Y 坐标的数据,线的颜色值得数组.

  • (void)LineGraphViewY_datasArray:(NSArray *)y_datasArray andColoreLines:(NSArray *)coloreLines;



第二步:绘制X 轴 坐标,Y轴坐标

  • (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
    self.backgroundColor = [UIColor blackColor];
    for (int i= 0; i < YData; i++) {
    CGFloat lineX = SpacingToLeft;
    CGFloat lineY = i * SpacingHeight + SpacingToTop;
    CGFloat lineW = self.frame.size.width - 2 * lineX;
    CGFloat lineH = 0.5;

          UILabel \*line = [[UILabel alloc] initWithFrame:CGRectMake(lineX, lineY, lineW, lineH)];
          
          line.backgroundColor = [UIColor whiteColor];
          if (i != 0) line.alpha = 0.3;
          [self addSubview:line];
          
          
          CGFloat y_datasX = 0;
          CGFloat y_datasY = lineY - 5;
          CGFloat y_datasW = SpacingToLeft;
          CGFloat y_datasH = 10;
          
          UILabel \*y_datas = [[UILabel alloc] initWithFrame:CGRectMake(y_datasX, y_datasY, y_datasW, y_datasH)];
          y_datas.tag = 100 + i;
          y_datas.textAlignment = NSTextAlignmentCenter;
          y_datas.textColor = [UIColor whiteColor];
          y_datas.text = [NSString stringWithFormat:@"%d",i];
          y_datas.font = [UIFont systemFontOfSize:9];
          [self addSubview:y_datas];
          
      }
      // 下面的月份
      NSArray \*arr = @[@"一月",@"二月",@"三月",@"四月",@"五月",@"六月",@"七月"];
      for (int i = 0; i < arr.count; i++) {
          
          CGFloat x_datasW = (self.frame.size.width - 2 \* SpacingToLeft)/arr.count;
          CGFloat x_datasX = SpacingToLeft + i \* x_datasW;
          CGFloat x_datasY = LineGraphHeight;
          CGFloat x_datasH = 10;
          UILabel \*x_datas = [[UILabel alloc] initWithFrame:CGRectMake(x_datasX, x_datasY, x_datasW, x_datasH)];
          x_datas.textColor = [UIColor whiteColor];
          x_datas.font = [UIFont systemFontOfSize:9];
          x_datas.textAlignment = NSTextAlignmentLeft;
          x_datas.text = arr[i];
          [self addSubview:x_datas];
      }
    

    }
    return self;
    }


  • 计算最大值,最小值 坐标,及数据


    /**
    设置label
    @param points 最大值 最小值的坐标
    */

    • (void)setTitleLabel:(NSArray *)points andMaxMin:(NSArray *)maxMin{

      CGFloat labelW = 100;
      CGFloat labelH = 9;
      for (int i = 0; i < points.count; i++) {
      CGPoint point = [points[i] CGPointValue];
      UILabel * label = [[UILabel alloc] init];
      label.font = [UIFont systemFontOfSize:9];
      label.textColor = [UIColor whiteColor];
      label.frame = CGRectMake(point.x+5, point.y+5, labelW, labelH);
      label.text = [NSString stringWithFormat:@"%@",maxMin[i]];
      [self addSubview:label];
      }

    }
    /**
    得到每组数据的最大值坐标

    @param points 每组数据
    */

    • (CGPoint )getEachGroupMax:(NSArray *)points{
      CGFloat max = 0;
      CGPoint POINT = CGPointZero;
      for (int i = 0 ; i < points.count; i++) {
      CGPoint point = [[points objectAtIndex:i] CGPointValue];
      CGFloat pointY = point.y - 12;
      if (max < pointY) {
      max = pointY;
      POINT = CGPointMake(start * i + SpacingToLeft, max - 10);
      }
      }
      return POINT;
      }

    /**
    得到每组数据的最大值
    传进来的数组
    */

    • (void)getEachGroupDatasMax:(NSArray *)arr{

      for (int i = 0; i < arr.count; i++) {
      NSArray *points = arr[i];
      CGFloat max = 0;
      NSString *maxString = nil;
      for (int y = 0 ; y < points.count; y++) {
      CGFloat pointY = [[points objectAtIndex:y] floatValue];
      if (max < pointY) {
      max = pointY;
      maxString = points[y];
      }
      }
      [self.maxDatas addObject:maxString];

      }
      }

    /**

    得到每组数据的最小值
    @param arr 传进来的数据

    */

    • (void)getEachGroupDatasMin:(NSArray *)arr{

      for (int i = 0; i < arr.count; i++) {
      NSArray *points = arr[i];

        CGFloat min = 999999999;
        NSString \*minString = nil;
        
        for (int y = 0 ; y < points.count; y++) {
            CGFloat pointY = [[points objectAtIndex:y] floatValue];
            
            if (min > pointY) {
                min = pointY;
                minString = points[y];
            }
        }
        [self.minDatas addObject:minString];
      

      }
      }
      /**
      得到每组数据的最小值

    @param points 每组数组

    @return 最小值
    */

    • (CGPoint)getEachGroupMin:(NSArray *)points{
      CGFloat min = 999999999;
      CGPoint POINT = CGPointZero;

      for (int i = 0 ; i < points.count; i++) {
      CGPoint point = [[points objectAtIndex:i] CGPointValue];
      CGFloat pointY = point.y - 12;

        if (min > pointY) {
            min = pointY;
            POINT = CGPointMake(start \* i + SpacingToLeft + 2, min);
        }
      

      }
      return POINT;
      }



    中间有较多计算坐标的代码,在这里就不多说了,开头有github 下载地址 可以去参考.


    第三步:绘制折线


    /**
    绘制折线
    */

    • (void)drawBrokenLine:(NSArray *)points andLineColor:(UIColor *)lineColor{

      UIBezierPath *linePath = [UIBezierPath bezierPath];

      [linePath setLineCapStyle:kCGLineCapRound];
      [linePath setLineJoinStyle:kCGLineJoinRound];
      // 起点

      [linePath moveToPoint:CGPointMake(SpacingToLeft, [[points objectAtIndex:0] floatValue]+ _dotH * 0.5)];
      // 其他点

      for (int i = 1; i < points.count; i++) {
      CGFloat xPosition = start * i + SpacingToLeft;
      CGFloat yPosition = [[points objectAtIndex:i] floatValue] + _dotH * 0.5;

        [linePath addLineToPoint:CGPointMake(xPosition, yPosition)];
      

      }

      CAShapeLayer *lineLayer = [CAShapeLayer layer];

      // 设置虚线
      lineLayer.lineDashPattern = [NSArray arrayWithObjects:@4,@2, nil];
      lineLayer.lineWidth = 1;
      lineLayer.strokeColor = lineColor.CGColor;
      lineLayer.path = linePath.CGPath;
      lineLayer.fillColor = [UIColor clearColor].CGColor; // 默认为blackColor

      [self.layer addSublayer:lineLayer];

    CABasicAnimation \*pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = 2.0;
    pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
    pathAnimation.autoreverses = NO;
    [lineLayer addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
    

    }


    第四部:绘制阴影


    // 绘制阴影

    • (void)drawRect:(CGRect)rect {

      for (int i = 0; i < self.datas.count; i++) {

        NSArray \* arr = self.datas[i];
        
        if (!arr || [arr count]<=0) return;
        
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSaveGState(context);
        {
            //先画出要裁剪的区域
            CGPoint firstPoint = [[arr objectAtIndex:0] CGPointValue];
            CGContextMoveToPoint(context, firstPoint.x, self.frame.size.height);
            CGContextSetLineWidth(context, 2);
            for (int i=0; i<[arr count]; i++) {
                //画中间的区域
                CGPoint point = [[arr objectAtIndex:i] CGPointValue];
                CGContextAddLineToPoint(context, point.x, point.y);
            }
            CGPoint lastPoint = [[arr objectAtIndex:([arr count]-1)] CGPointValue];
            {
                //画边框
                CGContextAddLineToPoint(context, lastPoint.x, self.frame.size.height);
                
                CGContextAddLineToPoint(context, self.frame.size.width, self.frame.size.height);
                CGContextAddLineToPoint(context, self.frame.size.width, 0);
                CGContextAddLineToPoint(context, 0, 0);
                CGContextAddLineToPoint(context, 0, self.frame.size.height);
            }
            
            CGContextClosePath(context);
            CGContextAddRect(context, CGContextGetClipBoundingBox(context));
            CGContextEOClip(context);
            //裁剪
            CGContextMoveToPoint(context, firstPoint.x, 0);
            CGContextAddLineToPoint(context, firstPoint.x, LineGraphHeight);
            CGContextSetLineWidth(context,self.frame.size.width\*2);
            CGContextReplacePathWithStrokedPath(context);
            CGContextClip(context);
            //填充渐变
            CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
            if (i == 0) {
                CGFloat colors[] = {
                    68/255.0,192/255.0,254/255.0,0.6,
                    68/255.0,192/255.0,254/255.0,0.0,
                    68/255.0,192/255.0,254/255.0,0.0
                };
                CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, colors, NULL, 2);
                CGContextDrawLinearGradient(context, gradient, CGPointMake(firstPoint.x, 0), CGPointMake(firstPoint.x, self.frame.size.height), 0);
                CGGradientRelease(gradient);
            }
            else
            {
                CGFloat colors[] = {
                    239/255.0,0/255.0,180/255.0,0.6,
                    239/255.0,0/255.0,180/255.0,0.0,
                    239/255.0,0/255.0,180/255.0,0.0
                };
                CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, colors, NULL, 2);
                CGContextDrawLinearGradient(context, gradient, CGPointMake(firstPoint.x, 0), CGPointMake(firstPoint.x, self.frame.size.height), 0);
                CGGradientRelease(gradient);
            }
        }
        CGContextRestoreGState(context);
      

      }
      }


    使用方法


    LineGraphView *lineGraph = [[LineGraphView alloc] initWithFrame:CGRectMake(0, 0, lineGraphW, lineGraphH)];
    [self.view addSubview:lineGraph];
    [lineGraph LineGraphViewY_datasArray:@[@[@"222",@"50",@"100",@"70",@"260",@"10",@"150"]] andColoreLines:@[[UIColor redColor]]];


    LineGraphView *lineGraph = [[LineGraphView alloc] initWithFrame:CGRectMake(0, 0, lineGraphW, lineGraphH)];
    [self.view addSubview:lineGraph];
    [lineGraph LineGraphViewY_datasArray:@[@[@"250",@"180",@"55",@"200",@"70",@"1000",@"88"],@[@"222",@"50",@"100",@"70",@"260",@"10",@"150"]] andColoreLines:@[[UIColor redColor],[UIColor yellowColor],[UIColor cyanColor]]];



    欢迎大家提出问题.

    你可能感兴趣的:(折线图-带阴影)