现在在手上的是一个证券资讯类型的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);

这个明白了之后其他的原理都是一样的,我就不介绍了,下面是部分代码:

[java] view
plain
 copy

  1. @Override
  2. protected void drawKChatBackGround() {
  3. Rect dirty = new Rect(left, kChartTop, right, KChartbottom);
  4. // 画背景图的矩形
  5. mCanvas.drawRect(dirty, LineGrayPaint);
  6. PathEffect effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
  7. LineGrayPaint.setPathEffect(effects);
  8. Path path = new Path();
  9. int y = kChartTop + 15;
  10. // 画上面的虚线
  11. path.moveTo(left, y );
  12. path.lineTo(right, y );
  13. String text = getPriceText(highPrice);
  14. int textHeight = (int) (textGrayPaint.descent() - textGrayPaint.ascent());
  15. mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2 ,textGrayPaint);
  16. double max = highPrice - lowPrice;
  17. if (max > 10){
  18. // 分成四等分
  19. // 画中间的三根虚线
  20. int n = 4;
  21. double sper = (highPrice - lowPrice) / 4;// 每一等分代表的价格
  22. for(int i=1;i<n;i++){
  23. y  =  i*((KChartbottom - kChartTop)/n) + kChartTop;
  24. path.moveTo(left, y);
  25. path.lineTo(right,y);
  26. text = getPriceText(highPrice - i*sper);
  27. mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);
  28. }
  29. }else{
  30. // 分成两等分
  31. // 画中间的虚线
  32. y = (KChartbottom - kChartTop)/2 + kChartTop;
  33. path.moveTo(left, y);
  34. path.lineTo(right, y);
  35. text = getPriceText(highPrice - (highPrice - lowPrice) / 2);
  36. mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);
  37. }
  38. // 画下面的虚线
  39. y = KChartbottom - 15;
  40. path.moveTo(left, y);
  41. path.lineTo(right, y);
  42. text = getPriceText(lowPrice);
  43. mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);
  44. //      // 画等分的虚线和下面的日期
  45. for (int i = num - 1; i > 0; i--) {
  46. int x = left + perWidth * i;
  47. path.moveTo(x, kChartTop);
  48. path.lineTo(x, KChartbottom);
  49. perXPoint[i - 1] = x;
  50. }
  51. mCanvas.drawPath(path, LineGrayPaint);
  52. }
[cpp] view
plain
 copy

  1. @Override
  2. protected void drawMAChart() {
  3. // 画均线
  4. Path path5 = new Path();
  5. Path path10 = new Path();
  6. Path path20 = new Path();
  7. double heightScale = (KChartbottom - kChartTop)/(highPrice - lowPrice);
  8. int maStart = left;
  9. float maStartY;
  10. path5.moveTo(maStart, (float) (kChartTop + (highPrice - infos.get(0).getMaValue5()) * heightScale));
  11. path10.moveTo(maStart, (float) (kChartTop + (highPrice - infos.get(0).getMaValue10()) * heightScale));
  12. path20.moveTo(maStart, (float) (kChartTop + (highPrice - infos.get(0).getMaValue20()) * heightScale));
  13. for(SingleStockInfo info:infos){
  14. maStart += per * perHalf;// 每一天实际所占的数据是4/6,左右边距各1/6
  15. maStartY = (float) (kChartTop + (highPrice - info.getMaValue5()) * heightScale);
  16. path5.lineTo(maStart, maStartY);
  17. maStartY = (float) (kChartTop + (highPrice - info.getMaValue10()) * heightScale);
  18. path10.lineTo(maStart, maStartY);
  19. maStartY = (float) (kChartTop + (highPrice - info.getMaValue20()) * heightScale);
  20. path20.lineTo(maStart, maStartY);
  21. maStart += per * perHalf;
  22. }
  23. Paint paint = new Paint();
  24. paint.setColor(Color.BLUE);
  25. paint.setAntiAlias(true);
  26. paint.setStrokeWidth(2);
  27. paint.setStyle(Style.STROKE);
  28. mCanvas.drawPath(path5, paint);
  29. paint.setColor(Color.MAGENTA);
  30. mCanvas.drawPath(path10, paint);
  31. paint.setColor(Color.GREEN);
  32. mCanvas.drawPath(path20, paint);
  33. }
[java] view
plain
 copy

  1. /**
  2. * 下面的柱形图
  3. */
  4. @Override
  5. protected void drawPillarsChart(int flag) {
  6. LineGrayPaint.setPathEffect(null);
  7. Rect dirty = new Rect(left, pillarsChartTop, right, pillarsChartbottom);
  8. // 画背景图的矩形
  9. mCanvas.drawRect(dirty, LineGrayPaint);
  10. int y = pillarsChartTop + (pillarsChartbottom - pillarsChartTop)/2;
  11. mCanvas.drawLine(left,y,right, y, LineGrayPaint);
  12. // 中间的值
  13. String totalCount = getPriceText(maxCount/2/10000);
  14. float maginLeft = left - textGrayPaint.measureText(totalCount)- 5;
  15. mCanvas.drawText(totalCount, maginLeft, y,textGrayPaint);
  16. // 上面的值
  17. totalCount = getPriceText(maxCount/10000);
  18. maginLeft = left - textGrayPaint.measureText(totalCount)- 5;
  19. mCanvas.drawText(totalCount, maginLeft, pillarsChartTop,textGrayPaint);
  20. // 下面的值
  21. totalCount = "万手";
  22. maginLeft = left - textGrayPaint.measureText(totalCount) - 5;
  23. mCanvas.drawText(totalCount, maginLeft, pillarsChartbottom,textGrayPaint);
  24. int pStart = left;
  25. float pStartY;
  26. double heightScale = (pillarsChartbottom - pillarsChartTop)/maxCount;
  27. Paint paint = new Paint();
  28. paint.setAntiAlias(true);
  29. paint.setStyle(Paint.Style.FILL);
  30. if (flag == StockService.FLAG){
  31. for(MinuteInfo info:minuteInfos){
  32. pStart += per * per16;// 每一天实际所占的数据是4/6,加上1/6
  33. pStartY = (float) (pillarsChartTop + (maxCount - info.getVolume()) * heightScale);
  34. dirty = new Rect(pStart, (int) pStartY, (int) (pStart + per * per46), pillarsChartbottom-2);
  35. paint.setColor(info.getColor());
  36. // 画背景图的矩形
  37. mCanvas.drawRect(dirty, paint);
  38. pStart += per * per56;// 右边的间距 5/6
  39. }
  40. }else{
  41. for(SingleStockInfo info:infos){
  42. pStart += per * per16;// 每一天实际所占的数据是4/6,加上1/6
  43. pStartY = (float) (pillarsChartTop + (maxCount - info.getTotalCount()) * heightScale);
  44. dirty = new Rect(pStart, (int) pStartY, (int) (pStart + per * per46), pillarsChartbottom-2);
  45. paint.setColor(info.getColor());
  46. // 画背景图的矩形
  47. mCanvas.drawRect(dirty, paint);
  48. pStart += per * per56;// 右边的间距 5/6
  49. }
  50. }
  51. }
[java] view
plain
 copy

  1. /**
  2. * 分时图
  3. */
  4. @Override
  5. public void drawHoursChart(){
  6. double heightScale = (KChartbottom - kChartTop)/(highPrice - lowPrice);
  7. int cLeft = left;
  8. int cTop = 0;
  9. Path path = new Path();
  10. path.moveTo(cLeft, KChartbottom-2);
  11. int position = 0;
  12. int perPointX = perXPoint[position];// 记录第一条垂直虚线的x坐标
  13. for(MinuteInfo info:minuteInfos){
  14. cLeft += per * per16;
  15. cTop = (int) (kChartTop + (highPrice - info.getNow()) * heightScale);
  16. path.lineTo(cLeft + per * per26, cTop);
  17. if (cLeft >= perPointX){
  18. // 恰好画到第一条垂直虚线的地方,需要画下面的时间
  19. String text = KChartUtil.getMinute(info.getMinute());
  20. float textWidth = textGrayPaint.measureText(text);
  21. int textHeight = (int) (textGrayPaint.descent()- textGrayPaint.ascent());
  22. mCanvas.drawText(text, perPointX - textWidth/2, KChartbottom + textHeight, textGrayPaint);
  23. if (!(position == perXPoint.length-1)){
  24. Log.e(TAG, perPointX+"----------"+info.getMinute()+"---"+text);
  25. perPointX = perXPoint[++position];
  26. }
  27. }
  28. cLeft += per * per56;// 右边的间距 5/6
  29. }
  30. path.lineTo(cLeft, KChartbottom-2);
  31. Paint LinePaint = new Paint();
  32. LinePaint.setColor(Color.BLUE);
  33. LinePaint.setAntiAlias(true);
  34. LinePaint.setStrokeWidth(1);
  35. LinePaint.setStyle(Style.STROKE);
  36. //      LinePaint.setStyle(Style.STROKE);
  37. mCanvas.drawPath(path, LinePaint);
  38. LinePaint.setAlpha(50);
  39. LinePaint.setStyle(Style.FILL);
  40. mCanvas.drawPath(path, LinePaint);
  41. }

需要的请给我留言

android 股票K线图的更多相关文章

  1. 股票K线图-JfreeChart版

    http://blog.csdn.net/ami121/article/details/3953272 股票K线图-JfreeChart版 标签: jfreechartpropertiesapplet ...

  2. 利用JFreeChart绘制股票K线图完整解决方案

    http://blog.sina.com.cn/s/blog_4ad042e50100q7d9.html 利用JFreeChart绘制股票K线图完整解决方案 (2011-04-30 13:27:17) ...

  3. IOS 股票K线图、分时图

    IOS 股票K线图.分时图,网上开源项目很少,质量也是参差不齐:偶尔搜索到看似有希望的文章,点进去,还是个标题党:深受毒害.经过一段时间的探索,终于在开源基础上完成了自己的股票K线图.分时图: 先放出 ...

  4. 基于Echarts的股票K线图展示

    发布时间:2018-10-31   技术:javascript+html5+canvas   概述 基于echarts的股票K线图展示,只需引用单个插件,通过简单配置,导入数据,即可实现炫酷复杂的K线 ...

  5. Highstock生成股票K线图

    在线演示 本地下载 使用HightStock生成股票K线图例子.

  6. WPF中使用amCharts绘制股票K线图

    原文:WPF中使用amCharts绘制股票K线图 本想自己用GDI绘图, 通过数据直接绘制一张蜡柱图, 但觉得这样子的功能比较少, 所以到网上搜索一些能画出K线图的控件. 发现DynamicDataD ...

  7. PHP使用HighChart生成股票K线图详解

    本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29Lo ...

  8. python pandas 画图、显示中文、股票K线图

    目录: 1.pandas官方画图链接 2.标记图中数据点 3.画图显示中文 4.画股票K线图 5.matplotlib基本用法 6.format输出 6.format输出例子 eps_range=[0 ...

  9. C#下如何用NPlot绘制期货股票K线图(2):读取数据文件让K线图自动更新

    [内容介绍]上一篇介绍了K线图的基本绘制方法,但很不完善,本篇增加了它直接读取数据的功能,这对于金融市场的数据量大且又需要动态刷新功能的实现很重要. [实现方法] 1.需要一个数据文件,这里用的是直接 ...

随机推荐

  1. Android双击退出

    重写返回键 private long tempTime = 0; /** * 双击退出 */ @Override public void onBackPressed() { long firstCli ...

  2. SQL语句常见问题的总结(持续更新)

    语言问题 修改语言注册表\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432\ORACLE\KEY_DevSuitHome1中的NLS_LANG修改为AMERICAN_AMERIC ...

  3. Java进阶(四十七)Socket通信

    Java进阶(四十七)Socket通信   今天讲解一个 Hello Word 级别的 Java Socket 通信的例子.具体通讯过程如下: 先启动Server端,进入一个死循环以便一直监听某端口是 ...

  4. 有两个序列a,b,大小都为n,序列元素的值是任意整数,无序。

    要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小. 例如: var a=[100,99,98,1,2, 3]; var b=[1, 2, 3, 4,5,40]. in ...

  5. EventBus详解

    EventBus详解 简介 github原文 EventBus... * simplifies the communication between components - decouples eve ...

  6. 关闭Win10自动更新

    使用过Windows10系统的小伙伴们都清楚,在Windows10中强制开启了自动更新功能,我们无法通过常规的办法关闭自动更新功能,那么我们该怎么去关闭自动更新呢?欢迎速来围观我的经验啦. 工具/原料 ...

  7. Xcode7.2中如何添加一个Empty Application模板

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Xcode 6.0正式版之后已经没有所谓的Empty Appl ...

  8. (NO.00005)iOS实现炸弹人游戏(四):游戏数据的初始化(一)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上一篇我们初步看了一下MainScene类的初始化方法里都做了神 ...

  9. 统计git代码提交量

    以下是我写的一个脚本,可以统计在某个项目中,自己修改代码的行数,包括增加多少行,删除多少行. 可以统计当天,24小时内或全部时间内.使用时需要把代码中的author对应的值换成自己的名字. 代码如下: ...

  10. Mybatis简单入门

    MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用 ...