前言
今年大数据行业火爆异常,大数据的实用点之一在于数据的统计和加工实现数据的“增值”,方便人们从大量的数据统计中得出结论。
对于一个iOS开发程序猿来说不是专门搞大数据开发的,似乎没有多大关系,但后续iOS开发中,各类APP中必然会加入统计表格的形式展示数据,相对于传统的列表形式+各类查询显示,表格形式直观、简洁、通俗易懂,分析更透彻,必然会成为抢手货。
本文介绍一下简易的柱状图、折线图、扇形图三种统计图的制作,希望能帮助到大家
坐标系
利用CAShapeLayer和UIBezierPath绘制坐标系,坐标系中需要绘制的部分如下图所示:
需要绘制的部分有原点、x坐标轴、y坐标轴、坐标轴末尾的箭头和坐标轴上的标度。需要计算位置和长度,需要根据所在页面的大小计算坐标系的位置和大小。
这里给出代码如下:
CAShapeLayer *layer = [CAShapeLayer layer];
UIBezierPath *path = [UIBezierPath bezierPath];
//坐标轴原点
CGPoint rPoint = CGPointMake(
1.3
*margin, self.zzHeight-margin);
//画y轴
[path moveToPoint:rPoint];
[path addLineToPoint:CGPointMake(
1.3
*margin, margin)];
//画y轴的箭头
[path moveToPoint:CGPointMake(
1.3
*margin, margin)];
[path addLineToPoint:CGPointMake(
1.3
*margin-
5
, margin+
5
)];
[path moveToPoint:CGPointMake(
1.3
*margin, margin)];
[path addLineToPoint:CGPointMake(
1.3
*margin+
5
, margin+
5
)];
//画x轴
[path moveToPoint:rPoint];
[path addLineToPoint:CGPointMake(self.zzWidth-
0.8
*margin, self.zzHeight-margin)];
//画x轴的箭头
[path moveToPoint:CGPointMake(self.zzWidth-
0.8
*margin, self.zzHeight-margin)];
[path addLineToPoint:CGPointMake(self.zzWidth-
0.8
*margin-
5
, self.zzHeight-margin-
5
)];
[path moveToPoint:CGPointMake(self.zzWidth-
0.8
*margin, self.zzHeight-margin)];
[path addLineToPoint:CGPointMake(self.zzWidth-
0.8
*margin-
5
, self.zzHeight-margin+
5
)];
//画x轴上的标度
for
(
int
i=
0
; i<x_itemarr.count; i++) { [path movetopoint:cgpointmake(
1.3
*margin+(self.zzwidth-
2
*margin)=
""
(x_itemarr.count+
1
)*(i+
1
), self.zzheight-margin)];=
""
[path addlinetopoint:cgpointmake(
1.3
*margin+(self.zzwidth-
2
*margin)=
""
(x_itemarr.count+
1
)*(i+
1
), self.zzheight-margin-
3
)];=
""
} =
""
画y轴上的标度=
""
for
(
int
i=
"0; i<10; i++) {"
[path movetopoint:cgpointmake(
1.3
*margin, margin+(self.zzheight-
2
*margin)=
""
11
*(i+
1
))];=
""
[path addlinetopoint:cgpointmake(
1.3
*margin+
3
, margin+(self.zzheight-
2
*margin)=
""
}=
""
layer.path =
" path.CGPath;"
layer.fillcolor =
" [UIColor clearColor].CGColor;"
layer.strokecolor =
" [UIColor blackColor].CGColor;"
layer.linewidth =
" 2.0;"
[self.layer addsublayer:layer]; =
""
给y轴加标注=
""
lab.text =
" [NSString stringWithFormat:@"%d", 10*i];"
lab.textcolor =
" [UIColor blackColor];"
lab.font =
" [UIFont boldSystemFontOfSize:size];"
lab.textalignment =
" NSTextAlignmentCenter;"
[self addsubview:lab];=
""
}<=
""
pre=
""
><p><span style=
"font-size: 18px;"
><strong>柱状图</strong></span></p><p>在绘制坐标系的基础上,绘制柱状图的原理非常简单,根据x轴的坐标,计算每条柱的高度。</p><p>这里需要注意: </p><p>提供的数据需要转化为自己设定的y轴的刻度单位计算出的高度。另外,柱状图需要占用x轴的宽度,所以柱子的位置需要好好考虑一下放在x轴的什么位置。</p><p>代码如下:</p><pre
class
=
"brush:as3;toolbar:false"
>
//画柱状图
for
(
int
i=
0
; i<x_itemarr.count; i++) { uibezierpath *path =
" [UIBezierPath bezierPathWithRect:CGRectMake(1.3*margin+(self.zzWidth-2*margin)/(x_itemArr.count+1)*(i+0.7), self.zzHeight-margin-(self.zzHeight-2*margin)/11*[y_itemArr[i] floatValue]/10, 0.6*((self.zzWidth-2*margin)/(x_itemArr.count+1)), (self.zzHeight-2*margin)/11*[y_itemArr[i] floatValue]/10-1)];"
cashapelayer *layer =
" [CAShapeLayer layer];"
layer.path =
" path.CGPath;"
layer.fillcolor =
" zzRandomColor.CGColor;"
layer.strokecolor =
" [UIColor clearColor].CGColor;"
[self.layer addsublayer:layer];=
""
}=
""
=
""
给x轴加标注=
""
for
(
int
i=
"0; i<x_itemArr.count; i++) {"
cgfloat xlwidth =
" ((self.zzWidth-2*margin)/(x_itemArr.count+1)) <= 25 ? ((self.zzWidth-2*margin)/(x_itemArr.count+1)) : 25;"
uilabel *lab =
" [[UILabel alloc] initWithFrame:CGRectMake(1.3*margin+(self.zzWidth-2*margin)/(x_itemArr.count+1)*(i+1)-xLWidth/2, self.zzHeight-margin, xLWidth, 20)];"
lab.text =
" x_itemArr[i];"
lab.textcolor =
" [UIColor blackColor];"
lab.adjustsfontsizetofitwidth =
" YES;"
lab.textalignment =
" NSTextAlignmentCenter;"
[self addsubview:lab];=
""
}<=
""
pre=
""
><p>效果图如下:</p><p style=
"text-align: center;"
><img src=
"http://cc.cocimg.com/api/uploads//20171206/1512520726921727.png"
title=
"iOS后续开发 数据统计表"
_src=
"http://cc.cocimg.com/api/uploads//20171206/1512520726921727.png"
alt=
"iOS后续开发 数据统计表"
width=
"500"
height=
"495"
border=
"0"
vspace=
"0"
style=
"width: 500px; height: 495px;"
></p><p><span style=
"font-size: 18px;"
><strong>折线图</strong></span></p><p>在坐标系的基础上,计算绘制对应y轴上的点,然后从第一个点开始,依次连接到最后一个点,可以直线连接,或者用贝塞尔曲线绘制,具体看实际情况实现。</p><p>代码如下:</p><pre
class
=
"brush:as3;toolbar:false"
> //开始点
CGPoint startPoint = CGPointMake(
1.3
*margin+(self.zzWidth-
2
*margin)/(x_itemArr.count+
1
), self.zzHeight-margin-(self.zzHeight-
2
*margin)/
11
*[y_itemArr[
0
] floatValue]/
10
);
//结束点
CGPoint endPoint;
for
(
int
i=
0
; i<x_itemarr.count; i++) { endpoint =
" CGPointMake(1.3*margin+(self.zzWidth-2*margin)/(x_itemArr.count+1)*(i+1), self.zzHeight-margin-(self.zzHeight-2*margin)/11*[y_itemArr[i] floatValue]/10);"
uibezierpath *path =
" [UIBezierPath bezierPath];"
[path movetopoint:startpoint];=
""
[path addarcwithcenter:endpoint radius:
1.5
startangle:
0
endangle:
2
*m_pi clockwise:yes];=
""
[path addlinetopoint:endpoint]; =
""
绘制连线=
""
cashapelayer *layer =
" [CAShapeLayer layer];"
layer.path =
" path.CGPath;"
layer.strokecolor =
" [UIColor redColor].CGColor;"
layer.linewidth =
" 1.0;"
[self.layer addsublayer:layer]; =
""
绘制点=
""
cashapelayer *layer1 =
" [CAShapeLayer layer];"
layer1.frame =
" CGRectMake(endPoint.x-2, endPoint.y-2, 4, 4);"
layer1.backgroundcolor =
" [UIColor blackColor].CGColor;"
[self.layer addsublayer:layer1]; =
""
绘制虚线=
""
cashapelayer *shapelayer =
" [CAShapeLayer layer];"
[shapelayer setstrokecolor:[uicolor blackcolor].cgcolor];=
""
[shapelayer setlinewidth:
1
];=
""
[shapelayer setlinejoin:kcalinejoinround]; =
""
设置虚线的线宽及间距=
""
[shapelayer setlinedashpattern:[nsarray arraywithobjects:[nsnumber numberwithint:
2
], [nsnumber numberwithint:
3
], nil]]; =
""
创建虚线绘制路径=
""
cgmutablepathref path =
" CGPathCreateMutable(); //设置y轴方向的虚线"
cgpathmovetopoint(path,
null
, point.x, point.y);=
""
cgpathaddlinetopoint(path,
null
, point.x, self.zzheight-margin); =
""
设置x轴方向的虚线=
""
cgpathaddlinetopoint(path,
null
,
1.3
*margin, point.y); =
""
设置虚线绘制路径=
""
[shapelayer setpath:path];=
""
cgpathrelease(path);=
""
[self.layer addsublayer:shapelayer];=
""
startpoint =
" endPoint;"
} =
""
给x轴加标注=
""
for
(
int
i=
"0; i<x_itemArr.count; i++) { CGFloat xLWidth = ((self.zzWidth-2*margin)/(x_itemArr.count+1)) <= 25 ? ((self.zzWidth-2*margin)/(x_itemArr.count+1)) : 25; UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(1.3*margin+(self.zzWidth-2*margin)/(x_itemArr.count+1)*(i+1)-xLWidth/2, self.zzHeight-margin, xLWidth, 20)];"
lab.text =
" x_itemArr[i];"
lab.textcolor =
" [UIColor blackColor];"
lab.adjustsfontsizetofitwidth =
" YES;"
lab.textalignment =
" NSTextAlignmentCenter;"
[self addsubview:lab];=
""
}<=
""
pre=
""
><p>效果图如下: </p><p style=
"text-align: center;"
><img src=
"http://cc.cocimg.com/api/uploads//20171206/1512520769607184.png"
title=
"iOS后续开发 数据统计表"
_src=
"http://cc.cocimg.com/api/uploads//20171206/1512520769607184.png"
alt=
"iOS后续开发 数据统计表"
width=
"500"
height=
"486"
border=
"0"
vspace=
"0"
style=
"width: 500px; height: 486px;"
></p><p><span style=
"font-size: 18px;"
><strong>扇形图</strong></span></p><p>扇形图制作需要首先计算每一条数据占数据总和的百分比,然后以页面中心点为中心,指定半径,开始画扇形,每条数据对应一个扇形,起点半径每次都不一样,知道最后一条数据画完,可以正好得到一个整圆。</p><p>代码如下:</p><pre
class
=
"brush:as3;toolbar:false"
> CGPoint yPoint = CGPointMake(self.zzWidth/
2
, self.zzHeight/
2
); CGFloat startAngle =
0
; CGFloat endAngle; float r = self.zzHeight/
3
; //求和
float sum=
0
;
for
(NSString *str
in
y_itemArr) {
sum += [str floatValue];
}
for
(
int
i=
0
; i=
45
?
40
: self.zzHeight/
6
; CGFloat size = self.zzHeight/
6
+
5
>=
45
?
9
:
5
; CGFloat lab_x = yPoint.x + (r + bLWidth/
2
) * cos((startAngle + (endAngle - startAngle)/
2
)) - bLWidth/
2
; CGFloat lab_y = yPoint.y + (r + bLWidth*
3
/
8
) * sin((startAngle + (endAngle - startAngle)/
2
)) - bLWidth*
3
/
8
; UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(lab_x, lab_y, bLWidth, bLWidth*
3
/
4
)];
lab.text = [NSString stringWithFormat:@"%@
%.2f%@
",x_itemArr[i],zhanbi*100,@"
%"];
lab.textColor = [UIColor blackColor];
lab.numberOfLines =
0
;
lab.font = [UIFont boldSystemFontOfSize:size];
lab.textAlignment = NSTextAlignmentCenter;
[self addSubview:lab];
layer.path = path.CGPath;
layer.fillColor = zzRandomColor.CGColor;
layer.strokeColor = [UIColor clearColor].CGColor;
[self.layer addSublayer:layer];
startAngle = endAngle;
}</pre><p>效果图如下: </p><p style=
"text-align: center;"
><img src=
"http://cc.cocimg.com/api/uploads//20171206/1512520794943194.png"
title=
"iOS后续开发 数据统计表"
_src=
"http://cc.cocimg.com/api/uploads//20171206/1512520794943194.png"
alt=
"iOS后续开发 数据统计表"
width=
"500"
height=
"493"
border=
"0"
vspace=
"0"
style=
"width: 500px; height: 493px;"
></p><p><span style=
"font-size: 18px;"
><strong>尾声</strong></span></p><p>简易的三种画法,仅用于展示数据,封装类和Demo已经上传到了GitHub上,地址:<a href=
"https://github.com/fuzheng0301/DrawChart"
target=
"_blank"
_href=
"https://github.com/fuzheng0301/DrawChart"
>https://github.com/fuzheng0301/DrawChart</a>,感谢star,希望能给大家带来帮助,也希望能看到大神的更精彩的分享。</p>
</x_itemarr.count; i++) {></pre></x_itemarr.count; i++) {></pre></x_itemarr.count; i++) {>