股票行情K线图Android版

转载请注明出住:http://blog.csdn.net/andywuchuanlong

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

github地址:https://github.com/chuanlongwu/kChart4Android

时间: 2024-10-10 11:59:30

股票行情K线图Android版的相关文章

股票K线图-JfreeChart版

http://blog.csdn.net/ami121/article/details/3953272 股票K线图-JfreeChart版 标签: jfreechartpropertiesappletdatetabledataset 2009-03-03 16:00 9378人阅读 评论(8) 收藏 举报 分类: jfreechart(7) 股票的K线图是所有Chart图中最复杂的一种,把一个K线图拆分开来我们可以发现,K线图的上半截实际上是由阴阳线(阴阳线可以表示开盘价,收盘价,最高价,最低价

amCharts 股票走势K线图金融图表控件下载及详细介绍

amCharts股票走势图的主要目的是为了显示金融图表控件,但它可以用于任何日期(时间)为基础的数据可视化. 股票走势图,是一个功能强大的应用程序,让你忘了最枯燥的部分构建复杂的统计系统.它具有内置的期间和数据集选择工具,并能较长组数据.这使您可以向下钻取图表不用任何额外的编码,只使用一个数据文件.单击"最大"按钮下面的图表,你会发现该图表显示月度数据.点击"1月"的按钮,你会看到,现在的图表显示每天的数据. 主要特点: 支持线,柱,烛台,OHLC,步线的图表类型.

amCharts 金融图表股票走势K线图控件介绍

amCharts控件股票走势图的主要目的是为了显示金融图表,但它可以用于任何日期(时间)为基础的数据可视化. 股票走势图,是一个功能强大的应用程序,让你忘了最枯燥的部分构建复杂的统计系统.它具有内置的期间和数据集选择工具,并能较长组数据.这使您可以向下钻取图表不用任何额外的编码,只使用一个数据文件.单击"最大"按钮下面的图表,你会发现该图表显示月度数据.点击"1月"的按钮,你会看到,现在的图表显示每天的数据. 主要特点: 支持线,柱,烛台,OHLC,步线的图表类型.

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

本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29LoD19)    QQ:1542385235 HighChart是集合了各种常见的web图表的开源合集,其中产生股票K线图的部分叫做“HighStock”.大家如果需要可以到我的资源页下载,是最新版: http://download.csdn.net/detail/wangyuchun_799/9353525

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

[内容介绍]上一篇介绍了K线图的基本绘制方法,但很不完善,本篇增加了它直接读取数据的功能,这对于金融市场的数据量大且又需要动态刷新功能的实现很重要. [实现方法] 1.需要一个数据文件,这里用的是直接读取由另一个CTP程序从上期交易所接收的期货合约RB1609所写的行情文件日线数据rb1609_d1.txt 文件格式如下: 日期 时间 开盘 最高 最低 收盘 成交量 持仓量 20160810 0.100000 2555.00 2606.00 2540.00 2563.00 3114 6858 2

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

http://blog.sina.com.cn/s/blog_4ad042e50100q7d9.html 利用JFreeChart绘制股票K线图完整解决方案 (2011-04-30 13:27:17) 标签: 绘制 股票 k线 it 分类: 软件_Software 因为工作的需要,接触了一些股票图形绘制类的工作,其中最主要的还是股票K线图的绘制了,如果利用编程语言最底层的图形绘制方法去绘制这类图形,如果对编程语言不是特别熟悉的话,一般是有很大的困难的,通过在网上搜索发现,以自己最熟悉的两门语言为

YYStock开源----iOS股票K线绘制第二版

新的股票绘制粗来啦,欢迎围观star的说(*^__^*) 嘻嘻-- 捏合功能也准备完善了 Github:https://github.com/yate1996/YYStock 长按分时图+五档图 分时图+五档图 长按分时图 分时图 K线图 长按K线图 非全屏嵌入 咦,发现UI好看但是功能好像有点不够用??? 没事,欲求不满的话专业版K线Demo也有?(^?^*) 戳这里:https://github.com/yate1996/Y_KLine

功能分解——Android下画分时图与k线图有感

最近工作极度繁忙,已经好久没有更新博客了,总感觉要是再不抽空总结总结点东西,分分钟就会被懒惰的状态给打到了.同时也希望同学们谨记,如果你已经决定要坚持某些正确的东西,比如背完某章单词,看一完本书抑或是跑完多少公里等等,都要坚持下去,不要轻易被自己的懒惰与懈怠打败…… 今天要讲的是关于怎么解决某些砰然大物般的问题,我回想了一下过去遇到的所有难题,都可以划分成为一个个微不足道的小问题.于是想起了管理学里面有关“拆分”的内容,就是任何复杂的东西都可以拆分成一个个简单得任何人都可以做的地步. 想到这些问

Highstock生成股票K线图

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