android折线图,简单的android折线图绘制

本文介绍了如何在Android中自适应地绘制折线图,包括使用Canvas、Paint和Path工具,以及如何设置坐标轴、绘制表格和数据点。通过计算坐标点和调整比例,实现了屏幕适配的折线图效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上图

2f1a994f2253d6bb4a5743c01b2f393d.png

说到android的折线图,我就必须要说一下关于绘制view的几个重要的工具,Canvas(画布),Paint(画笔),Path(路径)。

Canvas顾名思义就是用来作画的板子或者说是布。没有它就算有了画笔也是无从下手。当然我们可以通过Canvas的各种属性来设置Canvas,例如:

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轴同理

这样整个折线图的画法就很清晰啦。下面直接上代码

// 画表格

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);

}

}// 画横纵轴

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);

}// 画数据

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;

}

}

最后不要忘了@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);

}

完整项目的代码在下面,有兴趣的可以自己下载来玩玩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值