首页
IT
登录
6mi
u
盘
搜
搜 索
IT
Android 风向玫瑰图绘制
Android 风向玫瑰图绘制
xiaoxiao
2021-03-25
90
/**
风向玫瑰图绘制
Demo,
默认使用
16
个风向
* Created by yang_lei 2017/3/9.
*/
public class
RoseChart
extends
View
{
//
图标尺寸
private int
chart_size
;
private static
Context
context
;
//
传入参数
(
各个风向百分比
)
private
List
<
Float
>
percentageList
;
//
风向标签
private final
String
arrPerLabel
[] =
new
String
[]{
"N"
,
"NNE"
,
"NE"
,
"ENE"
,
"E"
,
"ESE"
,
"SE"
,
"SSE"
,
"S"
,
"SSW"
,
"SW"
,
"WSW"
,
"W"
,
"WNW"
,
"NW"
,
"NNW"
};
public
RoseChart
(
Context context
,
AttributeSet
attrs
) {
this
(
context
,
attrs
,
0
,
null
);
}
public
RoseChart
(
Context context
) {
this
(
context
,
null
);
}
/**
(默认顺时针方向
N-->NNE-->NE-->ENE-->E.....
)
*
@param
context
*
@param
attrs
*
@param
defStyle
*
@param
percentageList
风向百分比(默认顺时针方向从正北开始
N-->NNE-->NE-->ENE-->E.....
两个方向之间数据不可缺省,数据末尾可以缺省)
*/
public
RoseChart
(
Context context
,
AttributeSet
attrs
,
int
defStyle
,
List
<
Float
>
percentageList
) {
super
(
context
,
attrs
,
defStyle
);
//
初始化 风向百分比 集合
this
.
percentageList
=
percentageList
;
this
.
context
=
context
;
/**
*
获得我们所定义的自定义样式属性
*/
TypedArray
a
=
context
.
getTheme
().
obtainStyledAttributes
(
attrs
,
R.styleable
.
RoseChart
,
defStyle
,
0
);
chart_size
=
a
.
getDimensionPixelSize
(
R.styleable
.
RoseChart_chart_size
,
0
);
a
.
recycle
();
}
@Override
public void
onDraw
(
Canvas canvas
) {
//
画布背景
canvas
.
drawColor
(
getResources
().
getColor
(
R.color
.
blue1
));
float
cirX
=
getWidth
() /
2
;
float
cirY
=
getHeight
() /
2
;
//
计算绘制区域半径
float
radius
= (
float
) (
getHeight
() *
0.42
);
//150;
float
arcLeft
=
cirX
-
radius
;
float
arcTop
=
cirY
-
radius
;
float
arcRight
=
cirX
+
radius
;
float
arcBottom
=
cirY
+
radius
;
RectF
arcRF0
=
new
RectF
(
arcLeft
,
arcTop
,
arcRight
,
arcBottom
);
//
画笔初始化
Paint
PaintArc
=
new
Paint
();
Paint
PaintLabel
=
new
Paint
();
//
汉字标识
PaintLabel
.
setColor
(
Color
.
WHITE
);
PaintLabel
.
setAntiAlias
(
true
);
PaintArc
.
setAntiAlias
(
true
);
//
位置计算类
XChartCalc
xcalc
=
new
XChartCalc
();
float
Percentage
=
0.0f
;
float
CurrPer
=
0.0f
;
//
绘制 扇形区域 当前起始角度
float
CurrPerLabel
=
0.0f
;
//
绘制 风向标识 当前起始角度
float
NewRaidus
=
0.0f
;
//
计算每个扇区的圆心角度数
// Percentage = 360 / arrPerLabel.length;
// Percentage = (float) (Math.round(Percentage * 100)) / 100;
Percentage
= (
float
)
round
(
360.00
/
arrPerLabel
.
length
,
2
);
//
计算起始扇形区域角度(默认顺时针方向
N-->NNE-->NE-->ENE-->E.....
填充扇区)
CurrPer
-= (
float
)
round
((
Percentage
-
4
) /
2
,
2
);
CurrPerLabel
-= (
float
)
round
((
Percentage
-
4
) /
2
,
2
);
//
绘制三个不同百分比同心圆
PaintLabel
.
setStyle
(
Paint.Style
.
STROKE
);
PaintLabel
.
setStrokeCap
(
Paint.Cap
.
BUTT
);
canvas
.
drawCircle
(
cirX
,
cirY
,
radius
,
PaintLabel
);
canvas
.
drawCircle
(
cirX
,
cirY
, (
float
) (
radius
*
0.75
),
PaintLabel
);
canvas
.
drawCircle
(
cirX
,
cirY
, (
float
) (
radius
*
0.5
),
PaintLabel
);
canvas
.
drawCircle
(
cirX
,
cirY
, (
float
) (
radius
*
0.25
),
PaintLabel
);
//
绘制三个不同百分比标识
//1,
取出最大百分比
Float
max
=
Collections
.
max
(
percentageList
);
//
绘制 风向 扇区
for
(
int
i
=
0
;
i
<
percentageList
.
size
();
i
++) {
//
将百分比转换为新扇区的半径
if
(
percentageList
.
get
(
i
) ==
max
) {
NewRaidus
=
radius
;
}
else
{
NewRaidus
=
radius
* (
percentageList
.
get
(
i
) /
max
);
NewRaidus
= (
float
) (
Math
.
round
(
NewRaidus
*
100
)) /
100
;
}
float
NewarcLeft
=
cirX
-
NewRaidus
;
float
NewarcTop
=
cirY
-
NewRaidus
;
float
NewarcRight
=
cirX
+
NewRaidus
;
float
NewarcBottom
=
cirY
+
NewRaidus
;
RectF
NewarcRF
=
new
RectF
(
NewarcLeft
,
NewarcTop
,
NewarcRight
,
NewarcBottom
);
//
分配颜色
// PaintArc.setARGB(255, arrColorRgb[i][0], arrColorRgb[i][1], arrColorRgb[i][2]);
PaintArc
.
setColor
(
getResources
().
getColor
(
R.color
.
yellow1
));
PaintArc
.
setAlpha
(
200
);
//
在饼图中显示所占比例
canvas
.
drawArc
(
NewarcRF
,
CurrPer
-
90
,
Percentage
-
4
,
true
,
PaintArc
);
//
下次的起始角度
CurrPer
+=
Percentage
;
}
//2
,计算每个同心圆半径所占百分比
float
ThreePercentage
=
max
/
4
;
ThreePercentage
= (
float
) (
Math
.
round
(
ThreePercentage
*
100
)) /
100
;
//3,
绘制百分比标识
PaintLabel
.
setColor
(
getResources
().
getColor
(
R.color
.
red1
));
PaintLabel
.
setTextSize
(
getResources
().
getDimension
(
R.dimen
.
RoseChart_persent
));
PaintLabel
.
setFakeBoldText
(
true
);
canvas
.
drawText
(
ThreePercentage
+
"%"
,
cirX
+ (
float
) (
radius
*
0.18
),
cirY
-
18
,
PaintLabel
);
canvas
.
drawText
(
ThreePercentage
*
2
+
"%"
,
cirX
+ (
float
) (
radius
*
0.43
),
cirY
-
18
,
PaintLabel
);
canvas
.
drawText
(
ThreePercentage
*
3
+
"%"
,
cirX
+ (
float
) (
radius
*
0.68
),
cirY
-
18
,
PaintLabel
);
canvas
.
drawText
(
ThreePercentage
*
4
+
"%"
,
cirX
+ (
float
) (
radius
*
0.93
),
cirY
-
18
,
PaintLabel
);
//
绘制
16
个外圈风向标识
for
(
int
j
=
0
;
j
<
arrPerLabel
.
length
;
j
++) {
//
计算百分比标签
xcalc
.
CalcArcEndPointXY
(
cirX
,
cirY
,
radius
, (
float
) (
CurrPerLabel
+ (
Percentage
-
4
) *
0.5
));
//
标识
PaintLabel
.
setColor
(
Color
.
WHITE
);
PaintLabel
.
setTextSize
(
getResources
().
getDimension
(
R.dimen
.
RoseChart_direction
));
PaintLabel
.
setStrokeWidth
((
float
)
0.8
);
canvas
.
drawText
(
arrPerLabel
[
j
],
xcalc
.
getPosX
(),
xcalc
.
getPosY
(),
PaintLabel
);
//
下次的起始角度
CurrPerLabel
+=
Percentage
;
}
PaintLabel
.
setColor
(
Color
.
BLACK
);
canvas
.
drawText
(
"author:Yang_lei"
,
cirX
-
radius
,
cirY
+
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance4
),
PaintLabel
);
}
public static class
XChartCalc
{
private static float
x
;
private static float
y
;
private static float
r
;
public static void
CalcArcEndPointXY
(
float
cirX
,
float
cirY
,
float
radius
,
float
Percentage
) {
double
a
=
2
*
Math
.
PI
* (
Percentage
/
360
);
if
(
Percentage
>=
0
&&
Percentage
<
130
) {
r
=
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance1
);
}
else if
(
Percentage
>=
130
&&
Percentage
<
180
) {
r
=
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance2
);
}
else if
(
Percentage
==
180
) {
r
=
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance3
);
}
else if
(
Percentage
>
180
&&
Percentage
<
240
) {
r
=
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance4
);
}
else if
(
Percentage
>
240
&&
Percentage
<
270
) {
r
=
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance5
);
}
else if
(
Percentage
==
270
) {
r
=
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance6
);
}
else if
(
Percentage
>
270
&&
Percentage
<
300
) {
r
=
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance5
);
}
else if
(
Percentage
>=
300
&&
Percentage
<
330
) {
r
=
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance6
);
}
else if
(
Percentage
>=
330
&&
Percentage
<
350
){
r
=
radius
+
context
.
getResources
().
getDimension
(
R.dimen
.
RoseChart_distance3
);
}
y
=
cirY
- (
float
) (
r
* (
Math
.
cos
(
a
)));
x
=
cirX
+ (
float
) (
r
* (
Math
.
sin
(
a
)));
}
public static float
getPosX
() {
return
x
;
}
public static float
getPosY
() {
return
y
;
}
}
/**
返回指定小数位数
*
@param
v
*
@param
scale
*
@return
*/
public static double
round
(
double
v
,
int
scale
) {
if
(
scale
<
0
) {
throw new
IllegalArgumentException
(
"The scale must be a positive integer or zero"
);
}
BigDecimal
b
=
new
BigDecimal
(
Double
.
toString
(
v
));
BigDecimal
one
=
new
BigDecimal
(
"1"
);
return
b
.
divide
(
one
,
scale
,
BigDecimal
.
ROUND_HALF_UP
).
doubleValue
();
}
}
<
resources
>
<
dimen
name=
"RoseChart_persent"
>
10sp
</
dimen
>
<
dimen
name=
"RoseChart_direction"
>
8sp
</
dimen
>
<
dimen
name=
"RoseChart_distance1"
>
4dp
</
dimen
>
<
dimen
name=
"RoseChart_distance2"
>
8dp
</
dimen
>
<
dimen
name=
"RoseChart_distance3"
>
10dp
</
dimen
>
<
dimen
name=
"RoseChart_distance4"
>
16dp
</
dimen
>
<
dimen
name=
"RoseChart_distance5"
>
22dp
</
dimen
>
<
dimen
name=
"RoseChart_distance6"
>
12dp
</
dimen
>
</
resources
>
转载请注明原文地址: https://ju.6miu.com/read-22425.html
技术
最新回复
(
0
)