项目需求,今天研究了一下关于折线图的一些东西,属于Quartz2D的范畴
一个好用的第三方库PNChart
Quartz2D简介
- Quartz2D:二维的绘图引擎
- 可以跨平台开发(Mac和iPhone)
- 常用的是截屏/剪裁/自定义UI控件
想要绘图,就必须重写drawRect:方法,因为只有这个方法里才能获取上下文
绘制步骤
- 获取图形上下文
- 描述路径(起点和终点)
- 把路径添加到上下文
- 渲染上下文
如果你发现你的图形不对或者出不来就检查4步,缺一不可
系统原生方法
- (void)drawLine
{
// 1,获取图形上下文
// 目前我们所有的上下文都是以UIGraphics
// CGContexRef Ref:引用 CG:目前所用到的类型和函数,一般都是CG开头 CoreGraphics
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2,描述路径
// 创建路径
CGMutablePathRef path = CGPathCreateMutable();
// 设置起点
// path:给哪个路径设置起点
CGPathMoveToPoint(path, NULL, 50, 50);
// 添加一条线到某一点
CGPathAddLineToPoint(path, NULL, 200, 200);
// 3.把路径添加到上下文
CGContextAddPath(ctx, path);
// 4.渲染上下文
CGContextStrokePath(ctx);
}
系统第一层封装
- (void)drawLine1
{
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 这个方法系统会自动给你生成路径,自动给你添加到上下文,但是底层还是封装的drawLine里写的方法
// 描述路径
// 设置起点
CGContextMoveToPoint(ctx, 50, 50);
// 终点
CGContextAddLineToPoint(ctx, 200, 200);
// 渲染上下文
CGContextStrokePath(ctx);
}
贝瑟尔曲线方法
- (void)drawLine2
{
// 创建路径
UIBezierPath *path = [UIBezierPath bezierPath];
// 设置起点
[path moveToPoint:CGPointMake(50, 50)];
// 添加一根线到某个点上
[path addLineToPoint:CGPointMake(200, 200)];
// 绘制路径
[path stroke];
}
系统方法实现两条线
- (void)drawCtxState
{
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 描述路径
// 起点
CGContextMoveToPoint(ctx, 50, 50);
CGContextAddLineToPoint(ctx, 100, 50);
// 设置起点
// CGContextMoveToPoint(ctx, 80, 60);
// 默认下一根线的起点就是上一根线终点
CGContextAddLineToPoint(ctx, 100, 200);
CGContextAddLineToPoint(ctx, 200, 60);
CGContextAddLineToPoint(ctx, 50, 50);
// 设置绘图状态,一定要渲染之前
// 这个只渲染线的颜色
// [[UIColor redColor] setStroke];
// 线的颜色和填充物的颜色都渲染
[[UIColor redColor] set];
// 线宽
CGContextSetLineWidth(ctx, 15);
// 设置连接样式
CGContextSetLineJoin(ctx, kCGLineJoinBevel);
// 设置顶角样式
CGContextSetLineCap(ctx, kCGLineCapRound);
//渲染上下文
CGContextStrokePath(ctx);
// 填充满图
// CGContextFillPath(ctx);
}
贝瑟尔方法实现两线
- (void)drawUIBezierPathState
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(50, 50)];
[path addLineToPoint:CGPointMake(200, 200)];
[path addLineToPoint:CGPointMake(40, 100)];
[path setLineWidth:5];
[[UIColor greenColor] set];
[path stroke];
// 两条不搭嘎的线,用两条路径
UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 moveToPoint:CGPointMake(70, 60)];
[path1 addLineToPoint:CGPointMake(160, 180)];
// 如果想实现两条线颜色不同等方法,分别写两次渲染即可
path1.lineWidth = 13;
[[UIColor blueColor] set];
[path1 stroke];
}
图形上下文状态栈方法更改第二条曲线状态
- drawSaveGStateLine
{
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.描述路径
// 第一根
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, 125)];
[path addLineToPoint:CGPointMake(240, 125)];
// 把路径添加到上下文
// .CGPath 可以UIkit的路径转换成CoreGraphics路径
CGContextAddPath(ctx, path.CGPath);
// 必须先添加上下文,保存现有状态
// 保存一份上下文的状态
CGContextSaveGState(ctx);
// 设置上下文状态
CGContextSetLineWidth(ctx, 10);
// path.lineWidth = 200;
[[UIColor redColor] set];
// 渲染上下文
CGContextStrokePath(ctx);
// [path stroke];
// 第二根
// 2.描述路径
// 第一根
path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(125, 10)];
[path addLineToPoint:CGPointMake(125, 240)];
// 把路径添加到上下文
// .CGPath 可以UIkit的路径转换成CoreGraphics路径
CGContextAddPath(ctx, path.CGPath);
// 还原状态
CGContextRestoreGState(ctx);
// // 设置上下文状态
// CGContextSetLineWidth(ctx, 1);
//
// [[UIColor blackColor] set];
// 渲染上下文
CGContextStrokePath(ctx);
}
好了,这是现在系统收录的用语做直线的方法
然后介绍一下一个好用的,做折线图的第三方框架
这个第三方的Demo其实已经写的很简单了,这里面有几个样式,我们今天只讲一下折线图
下面是我直接粘的Demo的代码,进行简单注释
调用的时候写入如下代码即可,数据自己换一下
self.titleLabel.text = @"Line Chart";
// 放折线图的框框
self.lineChart = [[PNLineChart alloc] initWithFrame:CGRectMake(0, 135.0, SCREEN_WIDTH, 200.0)];
// 设计X轴
self.lineChart.yLabelFormat = @"%1.1f";
// 设置X轴颜色
self.lineChart.backgroundColor = [UIColor clearColor];
// 设置X轴显示的内容
[self.lineChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5",@"SEP 6",@"SEP 7"]];
// 是否显示轴,默认为NO
self.lineChart.showCoordinateAxis = YES;
//Use yFixedValueMax and yFixedValueMin to Fix the Max and Min Y Value
//Only if you needed
// Y轴设置
self.lineChart.yFixedValueMax = 300.0;
self.lineChart.yFixedValueMin = 0.0;
[self.lineChart setYLabels:@[
@"0 min",
@"50 min",
@"100 min",
@"150 min",
@"200 min",
@"250 min",
@"300 min",
]
];
// Line Chart #1
// 第一组数据
NSArray * data01Array = @[@60.1, @160.1, @126.4, @0.0, @186.2, @127.2, @176.2];
// 相应参数
PNLineChartData *data01 = [PNLineChartData new];
data01.dataTitle = @"Alpha";
data01.color = PNFreshGreen;
data01.alpha = 0.3f;
data01.itemCount = data01Array.count;
data01.inflexionPointStyle = PNLineChartPointStyleTriangle;
data01.getData = ^(NSUInteger index) {
CGFloat yValue = [data01Array[index] floatValue];
return [PNLineChartDataItem dataItemWithY:yValue];
};
// Line Chart #2
// 第二组数据
NSArray * data02Array = @[@0.0, @180.1, @26.4, @202.2, @126.2, @167.2, @276.2];
PNLineChartData *data02 = [PNLineChartData new];
data02.dataTitle = @"Beta";
data02.color = PNTwitterColor;
data02.alpha = 0.5f;
data02.itemCount = data02Array.count;
data02.inflexionPointStyle = PNLineChartPointStyleCircle;
data02.getData = ^(NSUInteger index) {
CGFloat yValue = [data02Array[index] floatValue];
return [PNLineChartDataItem dataItemWithY:yValue];
};
// 加入数据源
self.lineChart.chartData = @[data01, data02];
// 渲染出来
[self.lineChart strokeChart];
self.lineChart.delegate = self;
[self.view addSubview:self.lineChart];
self.lineChart.legendStyle = PNLegendItemStyleStacked;
self.lineChart.legendFont = [UIFont boldSystemFontOfSize:12.0f];
self.lineChart.legendFontColor = [UIColor redColor];
// 放标注的框框
UIView *legend = [self.lineChart getLegendWithMaxWidth:100];
[legend setFrame:CGRectMake(30, 340, legend.frame.size.width, legend.frame.size.width)];
[self.view addSubview:legend];
哦了,就这么简单
附带github上网址
https://github.com/kevinzhow/PNChart