android 股票K线图
现在在手上的是一个证券资讯类型的app,其中有涉及到股票行情界面,行情中有K线图等,看到网上很多人在求这方面的资料,所以我特地写了一个demo在此处给大家分享一下。
下面是做出来的效果图:
这个 界面 是如何画出来的我就不做介绍了,大家可以去下载项目源码。
背景图是利用canvas先画出一个矩形,然后再画几根虚线,均线图是通过path来绘制的,总之图的绘制是很简单的,我就不在这里作介绍了,大家可以去github下载源码看看。涉及到均线、最高价、最低价、收盘价、开盘价的概念大家可以百度一下。
我再这里要介绍的是计算问题:
大家可以看到分时图、日K、月K的左边的成交价格都是不一样的,而我们的k线都是通过这个价格来绘制的,也就是说价格是时刻变动,那么我们的k线绘制也是变动的。假设我们要计算分时图中价格为25.69的那一分钟应该如何画,画在屏幕中的哪一个位置,那么这个应该怎么画呢,价格是变动的,画的位置也是变动的,但是有一点我们屏幕的大小是不变的。所以我们可以通过背景图的高度来计算某个价格的线图应该从哪个地方开始画。我们可以计算出一个像素点对应多少个价格,分析图如下:
价格和像素形成个一个比例计算是:double heightScale = (endY - startY)/(highPrice - lowPrice);
所以价格25.69应该是画在mStartY = (float) (startY+ (highPrice - 25.69) * heightScale);
这个明白了之后其他的原理都是一样的,我就不介绍了,下面是部分代码:
- @Override
- protected void drawKChatBackGround() {
- Rect dirty = new Rect(left, kChartTop, right, KChartbottom);
- // 画背景图的矩形
- mCanvas.drawRect(dirty, LineGrayPaint);
- PathEffect effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
- LineGrayPaint.setPathEffect(effects);
- Path path = new Path();
- int y = kChartTop + 15;
- // 画上面的虚线
- path.moveTo(left, y );
- path.lineTo(right, y );
- String text = getPriceText(highPrice);
- int textHeight = (int) (textGrayPaint.descent() - textGrayPaint.ascent());
- mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2 ,textGrayPaint);
- double max = highPrice - lowPrice;
- if (max > 10){
- // 分成四等分
- // 画中间的三根虚线
- int n = 4;
- double sper = (highPrice - lowPrice) / 4;// 每一等分代表的价格
- for(int i=1;i<n;i++){
- y = i*((KChartbottom - kChartTop)/n) + kChartTop;
- path.moveTo(left, y);
- path.lineTo(right,y);
- text = getPriceText(highPrice - i*sper);
- mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);
- }
- }else{
- // 分成两等分
- // 画中间的虚线
- y = (KChartbottom - kChartTop)/2 + kChartTop;
- path.moveTo(left, y);
- path.lineTo(right, y);
- text = getPriceText(highPrice - (highPrice - lowPrice) / 2);
- mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);
- }
- // 画下面的虚线
- y = KChartbottom - 15;
- path.moveTo(left, y);
- path.lineTo(right, y);
- text = getPriceText(lowPrice);
- mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);
- // // 画等分的虚线和下面的日期
- for (int i = num - 1; i > 0; i--) {
- int x = left + perWidth * i;
- path.moveTo(x, kChartTop);
- path.lineTo(x, KChartbottom);
- perXPoint[i - 1] = x;
- }
- mCanvas.drawPath(path, LineGrayPaint);
- }
- @Override
- protected void drawMAChart() {
- // 画均线
- Path path5 = new Path();
- Path path10 = new Path();
- Path path20 = new Path();
- double heightScale = (KChartbottom - kChartTop)/(highPrice - lowPrice);
- int maStart = left;
- float maStartY;
- path5.moveTo(maStart, (float) (kChartTop + (highPrice - infos.get(0).getMaValue5()) * heightScale));
- path10.moveTo(maStart, (float) (kChartTop + (highPrice - infos.get(0).getMaValue10()) * heightScale));
- path20.moveTo(maStart, (float) (kChartTop + (highPrice - infos.get(0).getMaValue20()) * heightScale));
- for(SingleStockInfo info:infos){
- maStart += per * perHalf;// 每一天实际所占的数据是4/6,左右边距各1/6
- maStartY = (float) (kChartTop + (highPrice - info.getMaValue5()) * heightScale);
- path5.lineTo(maStart, maStartY);
- maStartY = (float) (kChartTop + (highPrice - info.getMaValue10()) * heightScale);
- path10.lineTo(maStart, maStartY);
- maStartY = (float) (kChartTop + (highPrice - info.getMaValue20()) * heightScale);
- path20.lineTo(maStart, maStartY);
- maStart += per * perHalf;
- }
- Paint paint = new Paint();
- paint.setColor(Color.BLUE);
- paint.setAntiAlias(true);
- paint.setStrokeWidth(2);
- paint.setStyle(Style.STROKE);
- mCanvas.drawPath(path5, paint);
- paint.setColor(Color.MAGENTA);
- mCanvas.drawPath(path10, paint);
- paint.setColor(Color.GREEN);
- mCanvas.drawPath(path20, paint);
- }
- /**
- * 下面的柱形图
- */
- @Override
- protected void drawPillarsChart(int flag) {
- LineGrayPaint.setPathEffect(null);
- Rect dirty = new Rect(left, pillarsChartTop, right, pillarsChartbottom);
- // 画背景图的矩形
- mCanvas.drawRect(dirty, LineGrayPaint);
- int y = pillarsChartTop + (pillarsChartbottom - pillarsChartTop)/2;
- mCanvas.drawLine(left,y,right, y, LineGrayPaint);
- // 中间的值
- String totalCount = getPriceText(maxCount/2/10000);
- float maginLeft = left - textGrayPaint.measureText(totalCount)- 5;
- mCanvas.drawText(totalCount, maginLeft, y,textGrayPaint);
- // 上面的值
- totalCount = getPriceText(maxCount/10000);
- maginLeft = left - textGrayPaint.measureText(totalCount)- 5;
- mCanvas.drawText(totalCount, maginLeft, pillarsChartTop,textGrayPaint);
- // 下面的值
- totalCount = "万手";
- maginLeft = left - textGrayPaint.measureText(totalCount) - 5;
- mCanvas.drawText(totalCount, maginLeft, pillarsChartbottom,textGrayPaint);
- int pStart = left;
- float pStartY;
- double heightScale = (pillarsChartbottom - pillarsChartTop)/maxCount;
- Paint paint = new Paint();
- paint.setAntiAlias(true);
- paint.setStyle(Paint.Style.FILL);
- if (flag == StockService.FLAG){
- for(MinuteInfo info:minuteInfos){
- pStart += per * per16;// 每一天实际所占的数据是4/6,加上1/6
- pStartY = (float) (pillarsChartTop + (maxCount - info.getVolume()) * heightScale);
- dirty = new Rect(pStart, (int) pStartY, (int) (pStart + per * per46), pillarsChartbottom-2);
- paint.setColor(info.getColor());
- // 画背景图的矩形
- mCanvas.drawRect(dirty, paint);
- pStart += per * per56;// 右边的间距 5/6
- }
- }else{
- for(SingleStockInfo info:infos){
- pStart += per * per16;// 每一天实际所占的数据是4/6,加上1/6
- pStartY = (float) (pillarsChartTop + (maxCount - info.getTotalCount()) * heightScale);
- dirty = new Rect(pStart, (int) pStartY, (int) (pStart + per * per46), pillarsChartbottom-2);
- paint.setColor(info.getColor());
- // 画背景图的矩形
- mCanvas.drawRect(dirty, paint);
- pStart += per * per56;// 右边的间距 5/6
- }
- }
- }
- /**
- * 分时图
- */
- @Override
- public void drawHoursChart(){
- double heightScale = (KChartbottom - kChartTop)/(highPrice - lowPrice);
- int cLeft = left;
- int cTop = 0;
- Path path = new Path();
- path.moveTo(cLeft, KChartbottom-2);
- int position = 0;
- int perPointX = perXPoint[position];// 记录第一条垂直虚线的x坐标
- for(MinuteInfo info:minuteInfos){
- cLeft += per * per16;
- cTop = (int) (kChartTop + (highPrice - info.getNow()) * heightScale);
- path.lineTo(cLeft + per * per26, cTop);
- if (cLeft >= perPointX){
- // 恰好画到第一条垂直虚线的地方,需要画下面的时间
- String text = KChartUtil.getMinute(info.getMinute());
- float textWidth = textGrayPaint.measureText(text);
- int textHeight = (int) (textGrayPaint.descent()- textGrayPaint.ascent());
- mCanvas.drawText(text, perPointX - textWidth/2, KChartbottom + textHeight, textGrayPaint);
- if (!(position == perXPoint.length-1)){
- Log.e(TAG, perPointX+"----------"+info.getMinute()+"---"+text);
- perPointX = perXPoint[++position];
- }
- }
- cLeft += per * per56;// 右边的间距 5/6
- }
- path.lineTo(cLeft, KChartbottom-2);
- Paint LinePaint = new Paint();
- LinePaint.setColor(Color.BLUE);
- LinePaint.setAntiAlias(true);
- LinePaint.setStrokeWidth(1);
- LinePaint.setStyle(Style.STROKE);
- // LinePaint.setStyle(Style.STROKE);
- mCanvas.drawPath(path, LinePaint);
- LinePaint.setAlpha(50);
- LinePaint.setStyle(Style.FILL);
- mCanvas.drawPath(path, LinePaint);
- }
需要的请给我留言
android 股票K线图的更多相关文章
- 股票K线图-JfreeChart版
http://blog.csdn.net/ami121/article/details/3953272 股票K线图-JfreeChart版 标签: jfreechartpropertiesapplet ...
- 利用JFreeChart绘制股票K线图完整解决方案
http://blog.sina.com.cn/s/blog_4ad042e50100q7d9.html 利用JFreeChart绘制股票K线图完整解决方案 (2011-04-30 13:27:17) ...
- IOS 股票K线图、分时图
IOS 股票K线图.分时图,网上开源项目很少,质量也是参差不齐:偶尔搜索到看似有希望的文章,点进去,还是个标题党:深受毒害.经过一段时间的探索,终于在开源基础上完成了自己的股票K线图.分时图: 先放出 ...
- 基于Echarts的股票K线图展示
发布时间:2018-10-31 技术:javascript+html5+canvas 概述 基于echarts的股票K线图展示,只需引用单个插件,通过简单配置,导入数据,即可实现炫酷复杂的K线 ...
- Highstock生成股票K线图
在线演示 本地下载 使用HightStock生成股票K线图例子.
- WPF中使用amCharts绘制股票K线图
原文:WPF中使用amCharts绘制股票K线图 本想自己用GDI绘图, 通过数据直接绘制一张蜡柱图, 但觉得这样子的功能比较少, 所以到网上搜索一些能画出K线图的控件. 发现DynamicDataD ...
- PHP使用HighChart生成股票K线图详解
本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群: 281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29Lo ...
- python pandas 画图、显示中文、股票K线图
目录: 1.pandas官方画图链接 2.标记图中数据点 3.画图显示中文 4.画股票K线图 5.matplotlib基本用法 6.format输出 6.format输出例子 eps_range=[0 ...
- C#下如何用NPlot绘制期货股票K线图(2):读取数据文件让K线图自动更新
[内容介绍]上一篇介绍了K线图的基本绘制方法,但很不完善,本篇增加了它直接读取数据的功能,这对于金融市场的数据量大且又需要动态刷新功能的实现很重要. [实现方法] 1.需要一个数据文件,这里用的是直接 ...
随机推荐
- [apache2.4]configure: error: APR not found. Please read the documentation.
apache2.4 安装出现如下错误 ``` [lzz@localhost httpd-2.4.10]$ ./configure checking for chosen layout... Apac ...
- android 集成微博常见问题
我们在做微博集成登录.分享.聊天的时候,肯定会遇到很多的坑,这里总结下常见的问题. 文件不存在 C8998 的解决方法 如图我们走微博授权登录的时候如果OAuth2.0 授权设置回调页面设置和本地的不 ...
- Spark技术内幕: Task向Executor提交的源码解析
在上文<Spark技术内幕:Stage划分及提交源码分析>中,我们分析了Stage的生成和提交.但是Stage的提交,只是DAGScheduler完成了对DAG的划分,生成了一个计算拓扑, ...
- linux中echo的用法
1.echo命令我们常用的选项有两个,一个是-n,表示输出之后不换行,另外一个是-e,表示对于转义字符按相应的方式处理,如果不加-e那么对于转义字符会按普通字符处理. 2.echo输出时的转义字符 \ ...
- Cocos2D游戏项目CCTableView在Xcode7.2下的无法滚动问题
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 一个RPG游戏转换到Xcode7.2下发现一个问题,原来可以上 ...
- SpringMVC源码分析--容器初始化(三)HttpServletBean
在上一篇博客springMVC源码分析--容器初始化(二)DispatcherServlet中,我们队SpringMVC整体生命周期有一个简单的说明,并没有进行详细的源码分析,接下来我们会根据博客中提 ...
- 通过邮件找回密码功能的Java实现
1.有个需求就是,忘记密码后通过邮箱找回.现在的系统在注册的时候都会强制输入邮箱,其一目的就是 通过邮件绑定找回,可以进行密码找回.通过java发送邮件的功能我就不说了,重点讲找回密码. 2.参考别人 ...
- java根据概率生成数字
/** * JAVA 返回随机数,并根据概率.比率 * @author zhanglei * */ public class MathRandom { /** * 0出现的概率为%50 */ publ ...
- UNIX网络编程——并发服务器(TCP)
在迭代服务器中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现. 网络服务器通常用fork来同时 ...
- 关于APP界面布局设计的八种优缺点
学习UI设计的时候,经常要接触到页面的布局,布局的方式会直接影响一个APP的视觉效果,好的布局方式,往往能带来舒服的视觉效果,更能得到用户的接受与好评.然而万变不离其宗,移动端页面常用的布局,不外乎以 ...