前言
能力分布圖是一個統(tǒng)計類經(jīng)常需要的一個需求专缠,需要一定的幾何計算,實(shí)現(xiàn)難度適中淑仆,在平時也很適合拿來用作iOS繪圖練手涝婉。
這里寫了一個具有一定可復(fù)用行比較高的多邊形能力分布圖,有需要的同學(xué)可以拿去用糯景,也可以當(dāng)做自己的練手Demo嘁圈。相關(guān)代碼我都放在我的Github-AWPolygonView上蟀淮,后續(xù)會有優(yōu)化更新最住,有什么問題歡迎大家提出想法,互相學(xué)習(xí)進(jìn)步怠惶。
正文
一涨缚、計算各個點(diǎn)的坐標(biāo)
畫圖一個核心步驟是計算需要的點(diǎn)的坐標(biāo)。需要的點(diǎn)的類型為:中心點(diǎn)、邊上的角脓魏、能力值的各個點(diǎn)兰吟。接下來開始計算各個點(diǎn)的坐標(biāo)。
1茂翔、中心的點(diǎn)
x坐標(biāo)就是View的寬度的一半
y坐標(biāo)就是View的高度的一半
_centerX = self.bounds.size.width/2;
_centerY = self.bounds.size.height/2;
2混蔼、邊上的角度
根據(jù)需要是幾邊形,通過在一個以View的中心點(diǎn)為圓心珊燎,view的寬度為直徑的圓上取點(diǎn)惭嚣。
然后通過角度和半徑 進(jìn)行計算獲得各個點(diǎn)的坐標(biāo)
cos
和sin
方法參數(shù)需要為弧度,將其轉(zhuǎn)換成傳入?yún)?shù)為角度的ANGLE_COS
方法
公式為:
1弧度=180/π度
1度=π/180弧度
代碼就是:
#define ANGLE_COS(Angle) cos(M_PI / 180 * (Angle))
#define ANGLE_SIN(Angle) sin(M_PI / 180 * (Angle))
接著通過一個循環(huán)計算每個點(diǎn)的坐標(biāo)悔政。
點(diǎn)的坐標(biāo)計算代碼如下:
//self.radius 為半徑
//self.sideNum為總共多少個邊
//i為逆時針第i個點(diǎn)
CGPoint cornerPoint = CGPointMake(
_centerX - ANGLE_COS(90.0 - 360.0 /self.sideNum * i) * self.radius,
_centerY - ANGLE_SIN(90.0 - 360.0 /self.sideNum * i) * self.radius);
3晚吞、能力值點(diǎn)的坐標(biāo)
能力值的點(diǎn)不想邊上的點(diǎn)那么有規(guī)律,半徑長短不一谋国,但是角度跟邊上的點(diǎn)的角度是一樣的槽地,所以只要在邊上的點(diǎn)的基礎(chǔ)上乘上半徑長短比例就可以了。
代碼如下:
//Values
for (int i = 0; i < self.sideNum; i++) {
if (self.values.count > i) {
CGFloat valueRadius = [self.values[i] floatValue] * self.radius;
CGPoint valuePoint = CGPointMake(_centerX - ANGLE_COS(90.0 - 360.0 /self.sideNum * i) * valueRadius,
_centerY - ANGLE_SIN(90.0 - 360.0 /self.sideNum * i) * valueRadius);
[tempValuePoints addObject:[NSValue valueWithCGPoint:valuePoint]];
}
}
二芦瘾、進(jìn)行連線
1捌蚊、采用CoreGraphics方法
各個點(diǎn)的坐標(biāo)確定好了,接下來就是連線了旅急,可以采用CoreGraphics中的context繪制直線方法:
CGContextMoveToPoint(CGContextRef _Nullable c, CGFloat x, CGFloat y)
CGContextAddLineToPoint(CGContextRef _Nullable c, CGFloat x, CGFloat y)
這樣可以直接劃線比較簡單逢勾,但是只滿足不需要動畫的需求。如果需要進(jìn)行類似Stroke
動畫變需要使用貝塞爾曲線
2藐吮、使用貝塞爾曲線與CAShaperLayer結(jié)合
初始化一個UIBezierPath
- (UIBezierPath *)bezierPath {
if (!_bezierPath) {
_bezierPath = [UIBezierPath bezierPath];
}
return _bezierPath;
}
通過這個bezierPath
進(jìn)行畫路徑
[_bezierPath moveToPoint:firstPoint];
[_bezierPath addLineToPoint:point];
將貝塞爾曲線路徑賦值給CAShapeLayer
的路徑
self.shapeLayer.path = self.bezierPath.CGPath;
此時已經(jīng)劃出需要的圖案,接著是執(zhí)行動畫
- (void)addStrokeEndAnimationToLayer:(CAShapeLayer *)layer {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.fromValue = @0;
animation.toValue = @1;
animation.duration = self.animationDuration;
[layer addAnimation:animation forKey:@"stokeEndAnimation"];
}
//調(diào)用動畫
[self addStrokeEndAnimationToLayer:self.shapeLayer];
三逃贝、展示效果
接下來是展示動畫效果:
相關(guān)代碼我都放在我的Github-AWPolygonView上谣辞,后續(xù)會有優(yōu)化更新,有什么問題歡迎大家提出想法沐扳,互相學(xué)習(xí)進(jìn)步泥从。