折线图的绘制
来源:互联网 发布:那年呐服饰淘宝代理可信吗 编辑:程序博客网 时间:2024/04/30 12:17
最近在做股票相关的项目,避免不了折线图,在这里温习一下写法,都是很简单的东西。
先看一下效果图
然后贴代码:
public class FTenBrokenLineView extends View { public int XPoint = DipUtil.dip2px(40); //原点的X坐标 public int YPoint = DipUtil.dip2px(210); //原点的Y坐标 public int XScale = 55; //X的刻度长度 public int YScale = 40; //Y的刻度长度 public int XLength = 300; //X轴的长度 public int YLength = 210; //Y轴的长度 public String[] XLabel; //X的刻度 public String[] YLabel; //Y的刻度 public String[] Data; //数据 public String Title; //显示的标题 private Context context; private Paint axisPaint;// 轴线 private Paint dataPaint;// 数据线 private Paint yTextPaint;// 文字的笔 private Paint xTextPaint; private Paint titlePaint; // Y轴顶部的提示 private Paint annulusPaint; // 数据圆环 private Paint paint; private Path path; Paint paint1; private float radius = DipUtil.dip2px(4);// 数据圆环的半径 public FTenBrokenLineView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; init(); } public FTenBrokenLineView(Context context) { super(context); this.context = context; init(); } private void init() { XLength = DataManager.getInstance(context).getDeviceWidth(context) - DipUtil.dip2px(70);// 这个是把屏幕的宽度减去两边的间距的和 YLength = DipUtil.dip2px(190); } /** * 为折线图设置数据 * * @param XLabels x的刻度 * @param YLabels y的刻度 * @param AllData 传入的数据 */ public void setInfo(String[] XLabels, String[] YLabels, String[] AllData) { XLabel = XLabels; YLabel = YLabels; Data = AllData; XScale = XLength / (XLabel.length - 1); YScale = YLength / YLabel.length;// 因为Y轴方向上第0个点没有数据,所以要特殊处理 invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas);//重写onDraw方法 initPaint(); canvas.drawLine(XPoint, YPoint, XPoint + XLength, YPoint, axisPaint); //X轴 canvas.drawLine(XPoint, YPoint - YLength, XPoint, YPoint, axisPaint); //画Y轴 for (int i = 1; i <= YLabel.length; i++) { canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + XLength, YPoint - i * YScale, axisPaint); //画横着方向每一个刻度,长度是X轴的长度 int j = i - 1;// 因为Y轴方向上第0个点没有数据,这里特殊处理 canvas.drawText(YLabel[j], XPoint - DipUtil.dip2px(25), YPoint - i * YScale + DipUtil.dip2px(3), yTextPaint); //文字 } for (int i = 0; i < XLabel.length; i++) { canvas.drawLine(XPoint + i * XScale, YPoint, XPoint + i * XScale, YPoint - YLength, axisPaint); //画X轴方向刻度 if (i > 0 && YCoord(Data[i - 1]) != -999 && YCoord(Data[i]) != -999) { //保证有效数据 paint1 = new Paint(); paint1.setAntiAlias(true); paint1.setStyle(Paint.Style.FILL); paint1.setColor(0x153ea3ff);// 这个颜色就蓝色不透明8% path = new Path();// 以每一个间距绘制它的路径,然后填充颜色。 path.moveTo(XPoint + (i - 1) * XScale, YCoord(Data[i - 1])); path.lineTo(XPoint + i * XScale, YCoord(Data[i])); path.lineTo(XPoint + i * XScale, YPoint); path.lineTo(XPoint + (i - 1) * XScale, YPoint); path.close(); canvas.drawPath(path, paint1);// 这里是绘制阴影效果 canvas.drawLine(XPoint + (i - 1) * XScale, YCoord(Data[i - 1]), XPoint + i * XScale, YCoord(Data[i]), dataPaint);// 绘制数据线 } } // 循环X轴上的数据 for (int i = 0; i < XLabel.length; i++) { // 这里是计算X轴上的标示长度,因为是分为两行,所以分割为2015 和 三季度,然后计算长度 String str1 = XLabel[i].substring(0, 4); float strwid1 = xTextPaint.measureText(str1); String str2 = XLabel[i].substring(4); float strwid2 = xTextPaint.measureText(str2); canvas.drawText(str1, (XPoint + i * XScale) - strwid1 / 2, YPoint + DipUtil.dip2px(15), xTextPaint);// 绘制X轴上的刻度数据,第一行2015 canvas.drawText(str2, (XPoint + i * XScale) - strwid2 / 2, YPoint + DipUtil.dip2px(30), xTextPaint);// 绘制X轴上的刻度数据,第二行三季度 str1 = null; str2 = null; canvas.drawCircle(XPoint + i * XScale, YCoord(Data[i]), radius, annulusPaint);// 绘制数据点,是一个圆环 paint = new Paint(); paint.setAntiAlias(true); paint.setStyle(Paint.Style.FILL); paint.setColor(context.getResources().getColor(R.color.background_gray)); canvas.drawCircle(XPoint + i * XScale, YCoord(Data[i]), radius * 2 / 3, paint);// 在圆环内部绘制一个圆,颜色为背景颜色 } } private void initPaint() { axisPaint = new Paint(); axisPaint.setStyle(Paint.Style.STROKE); axisPaint.setAntiAlias(true); axisPaint.setStrokeWidth(DipUtil.dip2px(1)); axisPaint.setColor(context.getResources().getColor(R.color.line)); dataPaint = new Paint(); dataPaint.setStyle(Paint.Style.STROKE); dataPaint.setAntiAlias(true); dataPaint.setStrokeWidth(radius / 3); dataPaint.setColor(context.getResources().getColor(R.color.blue)); annulusPaint = new Paint(); annulusPaint.setAntiAlias(true); annulusPaint.setStrokeWidth(radius / 3); annulusPaint.setColor(context.getResources().getColor(R.color.blue)); yTextPaint = new Paint(); yTextPaint.setAntiAlias(true); yTextPaint.setColor(context.getResources().getColor(R.color.title_color)); yTextPaint.setTextSize(context.getResources().getDimension(R.dimen.text_size_12)); xTextPaint = new Paint(); xTextPaint.setColor(context.getResources().getColor(R.color.text_gray)); xTextPaint.setTextSize(context.getResources().getDimension(R.dimen.text_size_12)); xTextPaint.setAntiAlias(true); titlePaint = new Paint(); titlePaint.setAntiAlias(true); titlePaint.setColor(context.getResources().getColor(R.color.title_color)); titlePaint.setTextSize(context.getResources().getDimension(R.dimen.text_size)); } /** * 计算绘制时的Y坐标,无数据时返回-999 * @param y0 * @return */ private float YCoord(String y0) { double y; double k; try { y = Double.parseDouble(y0); } catch (Exception e) { return -999; //出错则返回-999 } try { k = (YLength - YScale) / (Double.parseDouble(YLabel[YLabel.length - 1]) - Double.parseDouble(YLabel[0])); return (float) (((Double.parseDouble(YLabel[YLabel.length - 1]) - y) * k) + (YPoint - YLength)); } catch (Exception e) { } return 0; }}
<com.....FTenBrokenLineView android:id="@+id/flBrokenLine" android:layout_width="match_parent" android:layout_height="wrap_content" />
上面是xml文件中的
下面是在代码中添加数据:
private FTenBrokenLineView flBrokenLine;public String[] YLabel = {"0.5", "0.6", "0.7", "0.8", "0.9", "1.0", "1.1", "1.2"}; //X的刻度public String[] XLabel = {"2014三季度", "2014年报", "2015一季度", "2015中报", "2015三季度"}; //Y的刻度public String[] Data = {"0.9", "0.8", "1.1", "0.65", "0.92"}; //数据
自定义的view代码写的很乱,因为中间写的时候会有覆盖问题,所以为了能显示出效果,就写的很随便了,也不是很通用。flBrokenLine = ViewHolder.init(view, R.id.flBrokenLine);flBrokenLine.setInfo(XLabel, YLabel, Data);
diputil.dip2px方法就是px和dp转换的方法。
DataManager.getInstance(context).getDeviceWidth(context)这个方法就是获取屏幕的宽度。
YCoord() 方法是:根据传入的要显示的参数,把这些值转换为屏幕上Y轴的像素,然后绘制出数据点。转换的跪着就是计算y轴上每一个间距对应的像素的一个比率K,然后用最大值减去传入的参数得到的值乘,这个K,再加上上面空隙的间距,就是返回的值(这写的。。。。我自己都看不懂。。。。。。)反正就是一个数学的比率。
反正代码很简单,复习一下。。。。
0 0
- 折线图的绘制
- H5canvas折线图的绘制
- 折线图(六)绘制真正可用的折线图
- 利用canvas实现折线图的绘制
- 用canvas绘制的折线图 +解析
- PHP:折线图和数据表的绘制
- 简单的android折线图绘制
- 使用matplotlib绘制简单的折线图
- C#绘制折线图
- WPF绘制折线图
- EXT3绘制折线图
- android 绘制折线图
- android绘制折线图
- highcharts绘制折线图
- android绘制折线图
- achartengine绘制折线图
- 绘制折线图
- echarts绘制折线图
- 错误 1 error C2440: “=”: 无法从“const char [11]”转换为“LPCWSTR”
- 山东省第二届ACM大学生程序设计竞赛:Identifiers
- 機器學習基石(Machine Learning Foundations) 机器学习基石 作业三 课后习题解答
- PHP中的语言结构详解
- 3——Building Microservices: Inter-Process Communication in a Microservices Architecture
- 折线图的绘制
- C++ STL中Map的按Key排序和按Value排序
- 配置集群各机器间免密码登陆(开启ssh互信)
- 菜单
- codeforces 660B. Seating On Bus
- 【NYOJ】[1092]数字分隔(二)
- Android开发学习总结(一)——搭建最新版本的Android开发环境
- 软件开发公司如何带新人?
- A + B Problem