上图
说到android的折线图,我就必须要说一下关于绘制view的几个重要的工具,Canvas(画布),Paint(画笔),Path(路径)。
Canvas顾名思义就是用来作画的板子或者说是布。没有它就算有了画笔也是无从下手。当然我们可以通过Canvas的各种属性来设置Canvas,例如:
1
|
canvas.drawColor(Color.BLACK);
//设置背景颜色为黑色
|
其他设置就自己去查看api了,这里不多讲了。
Paint画笔,用来作画的笔,不管我们在画布上面绘制什么,都离不开画笔,只要用到canvas的地方请带上画笔。和画布一样,画笔也可以设计他独特的属性,例如颜色呀,粗细呀虚实线呀什么的,这里也不多说了。
Path路径,就像是我们小学时候用的尺子一样,如果要画一条直线就得沿着尺子的边缘话,这就是路径的功能,不过这里的路径没有那么必须,简单的线还是可以直接用paint画出来的,画折线图用到path的地方主要是画虚线,其实我也不是很明白为何必须用path,不过如果直接用paint+PathEffect+坐标来画画出来就永远是直线了,大概因为虚线是一节节的画的吧。
上面简单的介绍了一下用到的工具,下面就讲讲我画折线图的一些思路吧。
首先,一个坐标图必然要有原点坐标,X,Y轴,绘制折线的基线表格,最后就是折线啦。
原点可以自己定义绘制在任何地方,我这里由于不知道手机屏幕的具体大小,怕绘制出来比较鸡肋,于是做了个屏幕自适应:
原点X坐标=边距(也就是距离边界的宽度,android的像素点是从屏幕的左上角开始的)
原点Y坐标 = 屏幕的高度 - 边距
X轴的长度 = 屏幕宽度 - 2*边距
Y轴的长度 = 屏幕高度 - 2*边距
X轴的单位长度 = (屏幕宽度 - 2 * 边距) / (X轴所显示的标线数 - 1);
Y轴的单位长度 = (屏幕高度 - 2* 边距 )/(Y轴所显示的标线数 - 1)
画图的时候各个点坐标的计算方法是:
Y轴坐标 = (Y轴的单位长度 /(Y轴1点显示的数字 - 原点Y轴显示的数字))*(数据的Y轴数据-原点数字)
X轴同理
这样整个折线图的画法就很清晰啦。下面直接上代码
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
|
// 画表格
private
void
drawTable(Canvas canvas) {
Paint paint =
new
Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GRAY);
Path path =
new
Path();
PathEffect effects =
new
DashPathEffect(
new
float
[] {
5
,
5
,
5
,
5
},
1
);
paint.setPathEffect(effects);
// 纵向线
for
(
int
i =
1
; i * Xscale <= (
this
.getWidth() -
this
.Margin); i++) {
int
startX = Xpoint + i * Xscale;
int
startY = Ypoint;
int
stopY = Ypoint - (
this
.Ylabel.length -
1
) * Yscale;
path.moveTo(startX, startY);
path.lineTo(startX, stopY);
canvas.drawPath(path, paint);
}
// 横向线
for
(
int
i =
1
; (Ypoint - i * Yscale) >=
this
.Margin; i++) {
int
startX = Xpoint;
int
startY = Ypoint - i * Yscale;
int
stopX = Xpoint + (
this
.Xlabel.length -
1
) * Xscale;
path.moveTo(startX, startY);
path.lineTo(stopX, startY);
paint.setColor(Color.DKGRAY);
canvas.drawPath(path, paint);
paint.setColor(Color.WHITE);
paint.setTextSize(
this
.Margin /
2
);
canvas.drawText(
this
.Ylabel[i],
this
.Margin /
4
, startY
+
this
.Margin /
4
, paint);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// 画横纵轴
private
void
drawXLine(Canvas canvas, Paint p) {
canvas.drawLine(Xpoint, Ypoint,
this
.Margin,
this
.Margin, p);
canvas.drawLine(Xpoint,
this
.Margin, Xpoint - Xpoint /
3
,
this
.Margin
+
this
.Margin /
3
, p);
canvas.drawLine(Xpoint,
this
.Margin, Xpoint + Xpoint /
3
,
this
.Margin
+
this
.Margin /
3
, p);
}
private
void
drawYLine(Canvas canvas, Paint p) {
canvas.drawLine(Xpoint, Ypoint,
this
.getWidth() -
this
.Margin, Ypoint,
p);
canvas.drawLine(
this
.getWidth() -
this
.Margin, Ypoint,
this
.getWidth()
-
this
.Margin -
this
.Margin /
3
, Ypoint -
this
.Margin /
3
, p);
canvas.drawLine(
this
.getWidth() -
this
.Margin, Ypoint,
this
.getWidth()
-
this
.Margin -
this
.Margin /
3
, Ypoint +
this
.Margin /
3
, p);
}
|
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
|
// 画数据
private
void
drawData(Canvas canvas) {
Paint p =
new
Paint();
p.setAntiAlias(
true
);
p.setColor(Color.WHITE);
p.setTextSize(
this
.Margin /
2
);
// 纵向线
for
(
int
i =
1
; i * Xscale <= (
this
.getWidth() -
this
.Margin); i++) {
int
startX = Xpoint + i * Xscale;
canvas.drawText(
this
.Xlabel[i], startX -
this
.Margin /
4
,
this
.getHeight() -
this
.Margin /
4
, p);
canvas.drawCircle(startX, calY(Data[i]),
4
, p);
canvas.drawLine(Xpoint+(i-
1
)*Xscale, calY(Data[i-
1
]), startX, calY(Data[i]), p);
}
}
/**
*
* @param y
* @return
*/
private
int
calY(
int
y){
int
y0 =
0
;
int
y1 =
0
;
try
{
y0 = Integer.parseInt(Ylabel[
0
]);
y1 = Integer.parseInt(Ylabel[
1
]);
}
catch
(Exception e){
return
0
;
}
try
{
return
Ypoint-((y-y0)*Yscale/(y1-y0)) ;
}
catch
(Exception e){
return
0
;
}
}
|
最后不要忘了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@Override
protected
void
onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
Paint p1 =
new
Paint();
p1.setStyle(Paint.Style.STROKE);
p1.setAntiAlias(
true
);
p1.setColor(Color.WHITE);
p1.setStrokeWidth(
2
);
init();
this
.drawXLine(canvas, p1);
this
.drawYLine(canvas, p1);
this
.drawTable(canvas);
this
.drawData(canvas);
}
|
完整项目的代码在下面,有兴趣的可以自己下载来玩玩
本文出自 “7780410” 博客,请务必保留此出处http://7790410.blog.51cto.com/7780410/1534093