前言
有时候我们在处理一些数据的时候,需要用到折线图来呈现数据,让用户能够对数据更加清晰明,本文主要给大家介绍了关于ios实现多条折线图的相关内容,下面话不多说,来看看详细的介绍吧。
效果图如下:
1、封装类
.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#define xyqcolor(r, g, b) [uicolor colorwithred:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
#define xyqrandomcolor xyqcolor(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256))
#define margin 30 // 坐标轴与画布间距
#define y_every_margin 20 // y轴每一个值的间隔数
#import <uikit/uikit.h>
// 线条类型
typedef ns_enum(nsinteger, linetype) {
linetype_straight, // 折线
linetype_curve // 曲线
};
@interface beziercurveview : uiview
//初始化画布
+(instancetype)initwithframe:(cgrect)frame;
//画多根折线图
-( void )drawmorelinechartviewwithx_value_names:(nsmutablearray *)x_names targetvalues:(nsmutablearray *)targetvalues linetype:(linetype) linetype;
@end
|
.m
1
2
3
4
5
6
7
|
#import "beziercurveview.h"
static cgrect myframe;
@interface beziercurveview ()
@end
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@implementation beziercurveview
//初始化画布
+(instancetype)initwithframe:(cgrect)frame{
beziercurveview *beziercurveview = [[beziercurveview alloc]init];
beziercurveview.frame = frame;
//背景视图
uiview *backview = [[uiview alloc] initwithframe:cgrectmake(0, 0, frame.size.width, frame.size.height)];
backview.backgroundcolor = [uicolor clearcolor];
[beziercurveview addsubview:backview];
myframe = frame;
return beziercurveview;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
/**
* 画坐标轴
*/
-( void )drawxyline:(nsmutablearray *)x_names{
uibezierpath *path = [uibezierpath bezierpath];
//1.y轴、x轴的直线
[path movetopoint:cgpointmake(margin, cgrectgetheight(myframe)-margin)];
[path addlinetopoint:cgpointmake(margin, margin)];
[path movetopoint:cgpointmake(margin, cgrectgetheight(myframe)-margin)];
[path addlinetopoint:cgpointmake(cgrectgetwidth(myframe), cgrectgetheight(myframe)-margin)];
// //2.添加箭头
// [path movetopoint:cgpointmake(margin, margin)];
// [path addlinetopoint:cgpointmake(margin-5, margin+5)];
// [path movetopoint:cgpointmake(margin, margin)];
// [path addlinetopoint:cgpointmake(margin+5, margin+5)];
//
// [path movetopoint:cgpointmake(cgrectgetwidth(myframe), cgrectgetheight(myframe)-margin)];
// [path addlinetopoint:cgpointmake(cgrectgetwidth(myframe)-5, cgrectgetheight(myframe)-margin-5)];
// [path movetopoint:cgpointmake(cgrectgetwidth(myframe), cgrectgetheight(myframe)-margin)];
// [path addlinetopoint:cgpointmake(cgrectgetwidth(myframe)-5, cgrectgetheight(myframe)-margin+5)];
//3.添加索引格
//x轴
for ( int i=0; i<x_names.count; i++) {
cgfloat x = margin + (cgrectgetwidth(myframe)-30)/x_names.count*(i+1)-(cgrectgetwidth(myframe)-30)/x_names.count/2.0;
cgpoint point = cgpointmake(x,cgrectgetheight(myframe)-margin);
[path movetopoint:point];
[path addlinetopoint:cgpointmake(point.x, point.y-3)];
}
//y轴(实际长度为200,此处比例缩小一倍使用)
for ( int i=0; i<11; i++) {
cgfloat y = cgrectgetheight(myframe)-margin-y_every_margin*i;
cgpoint point = cgpointmake(margin,y);
[path movetopoint:point];
[path addlinetopoint:cgpointmake(point.x+3, point.y)];
}
//4.添加索引格文字
//x轴
for ( int i=0; i<x_names.count; i++) {
cgfloat x = margin + (cgrectgetwidth(myframe)-30)/x_names.count/2.0 + (cgrectgetwidth(myframe)-30)/x_names.count*i-(cgrectgetwidth(myframe)-30)/x_names.count/2.0;
uilabel *textlabel = [[uilabel alloc] initwithframe:cgrectmake(x, cgrectgetheight(myframe)-margin, (cgrectgetwidth(myframe)-60)/x_names.count, 20)];
textlabel.text = x_names[i];
textlabel.font = [uifont systemfontofsize:10];
textlabel.textalignment = nstextalignmentcenter;
textlabel.textcolor = [uicolor bluecolor];
[self addsubview:textlabel];
}
//y轴
for ( int i=0; i<11; i++) {
cgfloat y = cgrectgetheight(myframe)-margin-y_every_margin*i;
uilabel *textlabel = [[uilabel alloc] initwithframe:cgrectmake(0, y-5, margin, 10)];
textlabel.text = [nsstring stringwithformat:@ "%d" ,10*i];
textlabel.font = [uifont systemfontofsize:10];
textlabel.textalignment = nstextalignmentcenter;
textlabel.textcolor = [uicolor redcolor];
[self addsubview:textlabel];
}
//5.渲染路径
cashapelayer *shapelayer = [cashapelayer layer];
shapelayer.path = path.cgpath;
shapelayer.strokecolor = [uicolor blackcolor].cgcolor;
shapelayer.fillcolor = [uicolor clearcolor].cgcolor;
shapelayer.borderwidth = 2.0;
[self.subviews[0].layer addsublayer:shapelayer];
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
/**
* 画多根折线图
*/
-( void )drawmorelinechartviewwithx_value_names:(nsmutablearray *)x_names targetvalues:(nsmutablearray *)targetvalues linetype:(linetype) linetype{
//1.画坐标轴
[self drawxyline:x_names];
for ( int j=0; j<targetvalues.count; j++) {
//2.获取目标值点坐标
nsmutablearray *allpoints = [nsmutablearray array];
for ( int i=0; i<[targetvalues[j] count]; i++) {
cgfloat doublevalue = 2*[targetvalues[j][i] floatvalue]; //目标值放大两倍
cgfloat x = margin + (cgrectgetwidth(myframe)-30)/x_names.count*(i+1)-(cgrectgetwidth(myframe)-30)/x_names.count/2.0;
cgfloat y = cgrectgetheight(myframe)-margin-doublevalue;
cgpoint point = cgpointmake(x,y);
uibezierpath *path = [uibezierpath bezierpathwithroundedrect:cgrectmake(point.x-1, point.y-1, 2.5, 2.5) cornerradius:2.5];
cashapelayer *layer = [cashapelayer layer];
layer.strokecolor = [uicolor purplecolor].cgcolor;
layer.fillcolor = [uicolor purplecolor].cgcolor;
layer.path = path.cgpath;
[self.subviews[0].layer addsublayer:layer];
[allpoints addobject:[nsvalue valuewithcgpoint:point]];
}
//3.坐标连线
uibezierpath *path = [uibezierpath bezierpath];
[path movetopoint:[allpoints[0] cgpointvalue]];
cgpoint preponit;
switch (linetype) {
case linetype_straight: //直线
for ( int i =1; i<allpoints.count; i++) {
cgpoint point = [allpoints[i] cgpointvalue];
[path addlinetopoint:point];
}
break ;
case linetype_curve: //曲线
for ( int i =0; i<allpoints.count; i++) {
if (i==0) {
preponit = [allpoints[0] cgpointvalue];
} else {
cgpoint nowpoint = [allpoints[i] cgpointvalue];
[path addcurvetopoint:nowpoint controlpoint1:cgpointmake((preponit.x+nowpoint.x)/2, preponit.y) controlpoint2:cgpointmake((preponit.x+nowpoint.x)/2, nowpoint.y)]; //三次曲线
preponit = nowpoint;
}
}
break ;
}
cashapelayer *shapelayer = [cashapelayer layer];
shapelayer.path = path.cgpath;
shapelayer.strokecolor = xyqrandomcolor.cgcolor;
shapelayer.fillcolor = [uicolor clearcolor].cgcolor;
shapelayer.borderwidth = 2.0;
[self.subviews[0].layer addsublayer:shapelayer];
}
}
|
2、调用
1
2
|
#define screen_w [uiscreen mainscreen].bounds.size.width
#define screen_h [uiscreen mainscreen].bounds.size.height
|
1
2
3
4
5
6
|
//1.初始化
_bezierview = [beziercurveview initwithframe:cgrectmake(30, 30, screen_w-60, 280)];
_bezierview.center = self.view.center;
[self.view addsubview:_bezierview];
// 多根折线图
[_bezierview drawmorelinechartviewwithx_value_names:(nsmutablearray *)@[@ "语文" ,@ "数学" ,@ "英语" ,@ "物理" ,@ "化学" ,@ "生物" ,@ "政治" ,@ "历史" ,@ "地理" ] targetvalues:(nsmutablearray *)@[@[@60,@20,@50,@30,@90,@30,@100,@70, @20],@[@20,@40,@20,@50,@30,@90,@30,@100,@70],@[@10,@30,@40,@70,@50,@30,@20,@10,@80]] linetype:linetype_straight];
|
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:http://www.jianshu.com/p/ec73329c50b0