Android版股票K线图实现方案
前言
本文将介绍股票K线图的实现方案,项目名为KLineChart,github地址https://github.com/zengzg/KLineChart。
介绍
K线图一般分为日K、周K、月K,显示的内容有开/收盘价、最高/低价、成交量,额外信息为均线(ma5/10/20)。例如,日K图中就为当日开/收盘价、最高/低价、成交量和5/10/20日均线。K线图支持滑动,滑动过程中,动态改变最高最低价(和成交量);放大缩小可以由两根手指触发,双击也可以放大K线图;节点应该由右向左按时间倒序分布,支持“加载更多”。
无论是日K还是周K、月K显示的内容的模型其实是一样,只是采样周期不同,所以节点可以封装为同一个,名为Entry,包含属性:open、close、high、low、volume、ma5、ma10、ma20。显然K线图会同时显示多个节点,那就封装为EntryData,除了封装有一个节点集合外,还封装了对集合的所有相关操作,比如计算最大最小价、添加节点等。为了方便使用,可以将K线图做成一个自定义控件,并且可以将所有绘制工作封装在一起,名为Renderer,这个控件名当然就叫KLineChart了,由于滑动相关的实现与Android触摸事件处理息息相关,所以就写在KLineChart类中了。
详细设计
我不打算将每行代码都在这篇文章中一一细说,本文就实现中的2个重点作讲解,具体代码大家可以去查看源码。
首先要说的第一点就是绘制Entry。对于Entry的绘制,难点在于坐标映射,也就是说要将Entry集合一一计算出最终在canvas上绘制的坐标。这种映射逻辑可以用3个Matrix表示,下面我一一说明这3个Matrix的作用。
value matrix:坐标映射的第一步是将所有节点均匀分布在整个canvas绘制区域内。对于x轴,我们要计算的只是拉伸量,可以用width/entrise.size表示,entrise表示的就是Entry集合;对于y轴,除了拉伸量外还有个平移量,这是因为所有节点的Y值并不是从0开始的,可以用height/yValueRange表示,yValueRange就是所有节点的Y值区间(最大值-最小值);最后由于要实现从右到左分布节点,而且要y值越小的y坐标越大,可以将拉伸量设置为负数,并平移width(height)距离:
mMatrixValue.postTranslate(0, -yMin);
mMatrixValue.postScale(-scaleX, -scaleY);
mMatrixValue.postTranslate(rect.width(),rect.height());
这样value matrix就设置完成了,下面给张图帮助理解:
touch matrix:通过上面的value matrix变换后,我们就可以把当前集合中的所有节点映射到canvas上了,下一步拉伸(并平移)上面映射出的图形,因为往往一屏并不能显示出所有节点,为了支持滑动或者说当集合元素个数大于我们设置可绘制节点数时,就要对上一步变换后的图形作拉伸,x轴拉伸量可以用entries.size/drawCount表示,drawCount就是我们设置的可绘制节点数量:
mMatrixTouch.postScale(scaleX, scaleY);minTouchOffset = 0;maxTouchOffset = candleRect.width() * (scaleX - 1f);mMatrixTouch.postTranslate(-maxTouchOffset, 0);
其中y轴不需要拉伸,所以scaleY取1。有了这个x轴的拉伸量后,也就可以计算出x轴的最大最小平移量了,如上代码所示。下面给张图帮助理解:
offset matrix:这个matrix相对来说较为简单,它的作用是上面变换后的图形作平移,空出绘制y轴和x轴的区间。
mMatrixOffset.postTranslate(offsetX, offsetY);
这个平移大小y轴并没有特殊限制了,而x轴的平移大小应该和y值的绘制区间相关。下面给张图帮助理解:
通过上面3个矩阵变换后就可以得到最终的绘制点了,其实这本可以用1个矩阵来表示的,之所以分成3个最主要的原因是滑动过程中,我们只需要更新touch matrix的x轴的平移量便可,而平移的变化量自然就是由手指滑动距离来计算的了。
下面就开始介绍实现中的另一个难点了——滑动。与RecyclerView相同,定义滑动分为2部分scroll与fling,其中scroll是由触屏事件ACTION_MOVE触发的,fling是由触屏事件ACTION_UP触发的。
我们先通过ViewConfiguration获得启动滑动的最小位移量,名为touch slop,这个常量的用法是:当滑动偏移量首次大于这个值时,之后的ACTION_MOVE事件,才能识别为用户滑屏事件。当将ACTION_MOVE视为滑屏事件时,计算滑动偏移量dx,然后将这个偏移量作为x轴的平移增量更新touch matrix:
mMatrixTouch.getValues(matrixValues);matrixValues[Matrix.MTRANS_X] += -dx;
matrixValues[Matrix.MTRANS_Y] += dy;if (matrixValues[Matrix.MTRANS_X] < -maxTouchOffset) {matrixValues[Matrix.MTRANS_X] = -maxTouchOffset;
}
if (matrixValues[Matrix.MTRANS_X] > 0) {matrixValues[Matrix.MTRANS_X] = 0;
}mMatrixTouch.setValues(matrixValues);
这样再通过3个matrix变换后得到的Entry坐标就是我们滑动过后的新坐标,最后重绘UI。
fling的滑动是借助Scroller类实现的。捕获ACTION_UP事件,通过VelocityTracker类计算得到事件触发时的滑动初速度,在K线图中只用处理x轴的即可,这个初速度我命名为velocityX,对velocityX作边界检测,这个很好理解,速度不能太快或太慢,边界值或叫阀值同样可以通过ViewConfiguration获得;因为fling是一个自发的连续性动画,方法View.postOnAnimation(Runnable)可以使给定的Runnable对象在下一帧绘制时执行,我们可以利用这个机制,来实现一个“类递归”功能,以驱动fling的“自发及连续性”,将这个功能封装在类ViewFlinger中:
class ViewFlinger implements Runnable{public void run{final int x = scroller.getCurrX();final int y = scroller.getCurrY();final int dx = x - mLastFlingX;final int dy = y - mLastFlingY;mLastFlingX = x;mLastFlingY = y;scroll(dx, 0);if (!scroller.isFinished()) {postOnAnimation();}}public void fling(velocityX,velocityY){scroller.fling(0,0,velocityX,velocityY,...);postOnAnimation();}
}
上面就是ViewFling中的关键代码了,可以看出方法fling()就是触发这个“类递归”执行的地方,然后在这个Runnable执行过程中,调用的scroll()方法其实就是上文所讲的scroll过程中更新touch matrix并重绘UI的方法,只是给定的x轴平移增量是由Scroller计算得到的。至此K线图实现的2个难点就讲完了,如有不对,欢迎指正。最后再给张相对完整的演示图:
结束语
在实现基本的K线图功能中,对于坐标映射与滑动这2个难点的实现方案,其实并不是我想出来的。其中,坐标映射的方案来自开源项目MPAndroidChart,而滑动的方案取自RecyclerView。这就叫学以致用:)
Written with StackEdit.
Android版股票K线图实现方案相关推荐
- 利用JFreeChart绘制股票K线图
因为工作的需要,接触了一些股票图形绘制类的工作,其中最主要的还是股票K线图的绘制了,如果利用编程语言最底层的图形绘制方法去绘制这类图形,如果对编程语言不是特别熟悉的话,一般是有很大的困难的,通过在网上 ...
- layui + echarts股票K线图(含案例、代码、截图)(转载篇)
文章目录 layui + echarts股票K线图(含案例.代码.截图)(转载篇) 一.案例.代码.截图 经验 · 补充说明: layui + echarts股票K线图(含案例.代码.截图)(转载篇) ...
- java绘制均线图_利用JFreeChart绘制股票K线图完整解决方案
因为工作的需要,接触了一些股票图形绘制类的工作,其中最主要的还是股票K线图的绘制了,如果利用编程语言最底层的图形绘制方法去绘制这类图形,如果对编程语言不是特别熟悉的话,一般是有很大的困难的,通过在网上 ...
- 数据可视化7_股票K线图
文章目录 题目要求 数据源 代码 简单版 复杂版 遗忘的知识 1. numpy 2. json和python数据转换 题目要求 excel里的股票数据搞成K线图 数据源 阿里巴巴2020年股票数据.x ...
- 如何使用Tushare和Echarts来画股票K线图
如何使用Tushare和Echarts来画股票K线图 技术支持 Tushare大数据社区官网 首先介绍一下这次要使用的两个工具,Tushare是一个基于Python的金融数据接口,拥有丰富的数据内 ...
- plotly基于dataframe数据绘制股票K线图并过滤非交易时间
plotly基于dataframe数据绘制股票K线图并过滤非交易时间 #ohlc过滤非交易时间: import plotly as py # 导入plotly库并命名为py import plotly ...
- dax和m的区别_动态股票K线图----从M语言到DAX表达式
偶然见别人画的股票K线图,不禁见猎心喜,也来模仿一番.原图是不能动的,一动MACD移动平滑趋势线就没有了.这是微软excel的一个缺陷. 所以我想了一个办法弥补这个缺陷.由于手头没有数据,开始实施网抓 ...
- Python绘制股票K线图
目录 1 股票K线图知识了解 2 用Python绘制股票K线图 2.1 安装绘制K线图的mpl_finance库 2.2 引入相关库 2.3 用Tushare库获取股票基本数据 2.4 日期格式调整及 ...
- 利用 python numpy +matplotlib 绘制股票k线图
一.python numpy + matplotlib 画股票k线图 # -- coding: utf-8 -- import requests import numpy as np from mat ...
最新文章
- hadoop集群_Ambari搭建hadoop集群
- 谈谈Java中的volatile
- 2018-2019-2 网络对抗技术 20165337 Exp4 恶意代码分析
- 品牌网络推广方案浅析网站改版时如何更好地规避降权风险?
- 使用Navicat创建数据库,外键出现错误ERROR 1005: Can't create table (errno: 121)
- [python Cookbook]阅读笔记
- SAP Cloud for Customer里的Sales Lead和Lead
- SpringBoot2.x Flowable 6.4.2 开源项目
- 哈弗F7x驾舱数字化测试 语音识别精准
- 如何运行wifi服务器,技术:如何通过wifi进行文件传输?
- [转载] python 命名空间
- html项目组成员分工情况,分工.html · zhongjingxin/APP_I组_期末项目PRD文档 - Gitee.com...
- 【预测模型】基于VMD结合Elman神经网络预测数据matlab代码
- C primer plus 第六版pdf下载
- 观察者模式和模拟wow插件的例子
- 地震数据剖面图-matlab
- 小红书心灵捕手招募令,百亿流量扶持优质情感主播!
- 【洛谷 2958】木瓜的丛林
- VIN码识别-汽修行业新技术
- win10误禁用任务计划程序导致任务栏里的输入法丢失