现在在手上的是一个证券资讯类型的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. ERROR: In <declare-styleable> MenuView, unable to find attribute android:preserveIconSpacing

    eclipse  sdk从低版本切换到高版本sdk的时候   v7包会包这个错ERROR: In <declare-styleable> MenuView, unable to find ...

  2. EBS并发程序监控

    SELECT s.* FROM fnd_concurrent_requests r, v$session v, v$sql s WHERE r.oracle_session_id = v.audsid ...

  3. ssh远程登录操作 和ssh信任

    ssh 可以参考上一篇telnet的文章 1.安装openssh-server     sudo dpkg -i openssh-client_1%3a5.5p1-4ubuntu6_i386.deb ...

  4. python 多进程 logging:ConcurrentLogHandler

    python 多进程 logging:ConcurrentLogHandler python的logging模块RotatingFileHandler仅仅是线程安全的,如果多进程多线程使用,推荐 Co ...

  5. gradle2.0笔记——让项目升级到gradle2.0

    昨晚看到QQ群消息说gradle2.0发布了,今天去看了一下,确实是昨天发布的,为rc版本:Gradle 2.0-rc-2.于是决定试一下. gradle可以在官网上下载,地址如下:http://ww ...

  6. android fragement报nullexcption错误

    ,这题目起的够骚情了,原创傲慢的上校哦,转载请标明:http://blog.csdn.net/aomandeshangxiao/article/details/7753421 其实有些方法也是从网上找 ...

  7. UNIX网络编程——心跳包

    所谓的心跳包就是在客户端和服务器端间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送,类似于心跳,所以叫做心跳包. 一般是用来判断对方(设备,进程或其它网元)是否正常动行,一般采用定 ...

  8. React Native入门教程2 -- 基本组件使用及样式

    在上一篇文章中,我们学会了如何搭建React Native的环境(React Native入门教程(笔记) 1 – 开发环境搭建),不知道你们是否搭建好了呢,如果还没有,那么快动起小手,来体验RN带给 ...

  9. 1025. PAT Ranking (25)

    题目如下: Programming Ability Test (PAT) is organized by the College of Computer Science and Technology ...

  10. Cocos2D:塔防游戏制作之旅(十二)

    以上代码块相当直观 - 但是它分解的有些细致了. 首先,敌人通过传递HelloWorldLayer对象的引用而初始化.在init方法里,少数重要的变量被设置: maxHP:定义敌人有多经打(Tough ...