android 图表控件的实现(一)
前段时间公司要做图表,本来想用个三方库就完事的,然而有很多个性化的实现,那就自己动手吧。先上图
实现的效果感觉还行,再有什么特殊的需求,自己写的东西,改起来也方便。
接下来是把图表功能涉及到的类都先抽象出来。
ChartData包下是绘图时要用到的数据。
Xvalues:X轴下每个点要绘制的东西,如上面柱状图中绘制的月份数据。
Yvalues:每个X轴坐标对应的Y轴数据点。
XaxisData: X坐标轴
YaxisData: Y坐标轴
ChartDataManager: 绘制图表可能需要以上数据的配合,所以,还要把上面的数据放到一个地方进行统一管理,这个类里包含了以上上面的所有数据。
ChartDrawUtil包下是每一中图的绘制工具
DrawUtil是绘制图表的基类和一些公用方法。绘制图表,我把它分割成了三个步骤
1.绘制X轴 ——-》2.绘制Y轴————-》3.绘制图表内容。
所以在基类里写了三个抽象方法
abstract protected void startContent(Canvas canvas);abstract protected void drawXaxis(Canvas canvas);abstract protected void drawYaxis(Canvas canvas);
相应的子类实现对应的绘制就行了。
除了上面两个包里的类,剩下的就是实现好的图表类。
接下来就来看看图表的实现,上图中第一个,最简单的圆形进度控件CircleProgressChart
思路也很简单,先绘制一个底部的灰色圆环,再绘制上层的进度圆环,最后绘制中心文字。
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawCircle(centerX,centerY,circirRudias,bottomCirclePaint);//底部圆环绘制float currentDegree=360*currentPercent;//通过进度百分比计算对应的弧度float left=centerX-circirRudias;float top=centerY-circirRudias;float right=centerX+circirRudias;float bottom=centerY+circirRudias;RectF rectF=new RectF(left,top,right,bottom);canvas.drawArc(rectF,-90,currentDegree,false,topCirclePaint);//绘制对应的进度弧度int percentText= (int) (currentPercent*100);String drawtext=percentText+"%";Paint.FontMetrics metrics=textPaint.getFontMetrics();float textwidth= textPaint.measureText(drawtext);float textX=(getMeasuredWidth()-textwidth)/2; //文字X坐标点计算float textY=centerY-(metrics.ascent+metrics.descent)/2; //文字Y坐标点计算canvas.drawText(drawtext,textX,textY,textPaint);}
这个实在太简单了,还没用上上面设计的数据结构,不过接下来的图表会用到。
第二个图是含有多个种类的圆环图
这个图的实现也是很简单,显然,它要有一个各个种类的数据集合,我是用Yvalues来表示一个种类。
public class MultiTypeCircleProgressChart extends View {private int centerX,centerY;private int circirRudias;Paint textPaint,bottomCirclePaint,topCirclePaint;int bottomCircleColor=Color.GRAY,topCirlceColor= Color.RED,textColor=Color.BLACK;float currentPercent=0.50f;float circleWidth=20;float textSize=30;List<Yvalues> allTypeValues;//图包含的种类集合List<Integer> allTypeDegree;//不同种类的对应的弧度集合public MultiTypeCircleProgressChart(Context context) {super(context);init(context);}public MultiTypeCircleProgressChart(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init(context);}public MultiTypeCircleProgressChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}private void init(Context context){textPaint=new Paint();textPaint.setAntiAlias(true);textPaint.setDither(true);textPaint.setColor(textColor);textPaint.setTextSize(textSize);bottomCirclePaint=new Paint();bottomCirclePaint.setAntiAlias(true);bottomCirclePaint.setDither(true);bottomCirclePaint.setColor(bottomCircleColor);bottomCirclePaint.setStrokeWidth(circleWidth);bottomCirclePaint.setStyle(Paint.Style.STROKE);topCirclePaint=new Paint();topCirclePaint.setAntiAlias(true);topCirclePaint.setDither(true);topCirclePaint.setColor(topCirlceColor);topCirclePaint.setStrokeWidth(circleWidth);topCirclePaint.setStyle(Paint.Style.STROKE);allTypeDegree=new ArrayList<>();allTypeValues=new ArrayList<>();}//这个方法是计算不同种类对应的弧度private List<Integer> getRelativeDegree(List<Yvalues> yvaluesList){List<Integer> relativeDegree=new ArrayList<>();int size=yvaluesList.size();int totalValues=0;for(int i=0;i<size;i++){totalValues+=yvaluesList.get(i).getValue();}for(int i=0;i<size;i++){int degree= (int) (360*yvaluesList.get(i).getValue()*1.0f/totalValues);relativeDegree.add(degree);}return relativeDegree;}public void updateView(List<Yvalues> yvaluesList){this.allTypeValues=yvaluesList;this.allTypeDegree=getRelativeDegree(yvaluesList);invalidate();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);centerX=getMeasuredWidth()/2;centerY=getMeasuredHeight()/2;circirRudias=Math.min(centerX,centerY)-30;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int startDegree=-90;//圆环绘制的起点从12点钟方向开始canvas.drawCircle(centerX,centerY,circirRudias,bottomCirclePaint);float left=centerX-circirRudias;float top=centerY-circirRudias;float right=centerX+circirRudias;float bottom=centerY+circirRudias;RectF rectF=new RectF(left,top,right,bottom);int size=allTypeValues.size();for(int i=0;i<size;i++){topCirclePaint.setColor(allTypeValues.get(i).getTextcolor());canvas.drawArc(rectF,startDegree,allTypeDegree.get(i),false,topCirclePaint);startDegree+=allTypeDegree.get(i);}}
}
小知识点提示:
1.绘制底部圆的时候,设置画笔描边属性: bottomCirclePaint.setStyle(Paint.Style.STROKE);
2.绘制弧度首尾两头半圆装的属性:topCirclePaint.setStrokeCap(Paint.Cap.ROUND);
3.绘制弧度起点设为0的话,起点对应的是3点钟方向,我这里写成-90是对应的就是12点方向。
4.让文字居中的坐标点计算原理参考 http://blog.csdn.net/doctorzhong/article/details/53079511。
android 图表控件的实现(一)相关推荐
- Android图表控件MPAndroidChart——曲线图LineChart的使用(财富收益图)
目录 前言 本文涉及文章 其他相关文章 1.数据准备 1.1 数据来源 2.曲线展示 2.1 MPAndroidChart获取 2.2 数据对象获取 2.3 数据展示 3.曲线完善 3.1 图表背景. ...
- Android图表控件MPAndroidChart——BarChart实现多列柱状图以及堆积柱状图
目录 前言 1. 数据准备 1.1 数据来源 2. 图表展示 2.1 MPAndroidChart获取 2.2 数据对象获取 2.3 数据展示 3. 柱状图外观完善 3.1 去掉图表外框,描述内容以及 ...
- Android图表控件MPAndroidChart的使用
转载一篇Android图表控件MPAndroidChart的博客. 相关文章: Android图表控件MPAndroidChart的简单介绍(MPAndroidChart3.0) Android图表控 ...
- Android图表控件MPAndroidChart——LineChart实现 XY轴、原点线的直尺刻度样式
接上文: Android图表控件MPAndroidChart--曲线图LineChart的使用(多条曲线) 其他相关文章: Android图表控件MPAndroidChart的简单介绍(MPAndro ...
- Android图表控件MPAndroidChart实现左右滑动以及联动
前言 MPAndroidChart是一个功能强大的Android图表控件库,它实现了许多常见的图表效果.关于MPAndroidChart的使用文章已经很多了,这里不再详细介绍它的使用.当数据量过多时, ...
- android好用的曲线图控件,Android图表控件MPAndroidChart——曲线图LineChart的使用(多条曲线)...
发现最新的MPAndroidChart和以前版本的使用有一些差距,就写下了现在新版的使用方法 相关文章: Android图表控件MPAndroidChart的简单介绍(MPAndroidChart3. ...
- android开发原点表框架,Android图表控件MPAndroidChart——LineChart实现 XY轴、原点线的直尺刻度样式...
接上文: Android图表控件MPAndroidChart--曲线图LineChart的使用(多条曲线) 其他相关文章: Android图表控件MPAndroidChart的简单介绍(MPAndro ...
- android图表控件 坐标,android-charts 基于Java和Android开发的图形图表控件 | 李大仁博客...
王晓龙 April 8th, 2014 at 09:44 | #1 我再github上看到了你写的控件,给了我很大启发,我现在在做K线图一类的图表,正好用到了您开发的这款控件,但是有些地方使用的不太舒 ...
- Android图表控件MPChart-柱状+折线组合图表基本使用
一.效果图 双模式效果:柱形图加折线图,双y轴,从右向左滑动- 二.实现代码 1. 加入依赖 implementation 'com.github.PhilJay:MPAndroidChart:v3. ...
最新文章
- 我是如何在2年内逆袭成为BAT年薪40W的资深开发工程师的?
- 无敌了,不需要操作系统就能运行 Python 了!
- linux 判断网卡类型 有线 无线
- 系统进入低功耗的配置
- Redis 持久化之RDB和AOF
- Spring Bootstrap中带有配置元数据的高级配置
- springboot2——MyBatis入门
- 【zookeeper】zookeeper 的监听机制
- 协议protocol
- python创建文件的编码格式
- 2021 五一数学建模 赛题思路
- 电商ERP软件、订单管理系统、库存管理系统
- AI再造一个“李佳琦”,难嘛?
- html手机保存图片不显示,手机保存的图片在相册显示不了解决方法
- dlopen failed: empty/missing DT_HASH in quot;libx.soquot; (built with --hash-style=gnu?)
- 天津达内可靠么 老员工揭秘真实的达内教育
- 什么是软件需求?软件需求是什么意思?
- 单目视觉定位测距的两种方式
- 【学习笔记】群论基础
- Android开发者网址大全(不定期更新)
热门文章
- 2.4fxblue跟单ea如何实现多跟一,一跟多,或者多跟多
- Sublime3 设置Python快捷键
- js版微信测试号推送消息、生日、纪念日、网易云热评、舔狗日记【JavaScript版】保姆级教程 青龙面板做微信测试号推送生日、纪念日
- 计算机一级ms office应用题,计算机一级MSOffice考试练习题及答案
- JUC高并发编程从入门到精通(全)
- 计算机组成原理包健百度云,计算机组成原理包健版答案及解析.doc
- YII2使用Gii生成代码
- java-net-php-python-47ssm志愿者管理系统程序计算机毕业设计程序
- 强烈质疑第二届Android应用开发中国大学生挑战赛
- 小程序公共封装ajax,微信小程序HTTP请求从0到1封装