⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2dklinegraph.cpp

📁 我做的一个简单的读取*.day股票历史数据的显示成KLine的小例子。
💻 CPP
字号:

#include "stdafx.h"
#include ".\2dklinegraph.h"


C2DKLineGraph::C2DKLineGraph(CSize size)
{
	m_Size = size;

	m_GraphValues = NULL;
	m_AnalysePeriod = GP_DAY;
	m_GraphValuesCount = 0;
	
	m_MinValue = 999999;
	m_MaxValue = 0;
	m_DisplayMinValue = 999999;
	m_DisplayMaxValue = 0;
}

C2DKLineGraph::~C2DKLineGraph(void)
{
	ClearGraph();
}

void C2DKLineGraph::CreateGraph(CDC * pDC)
{
	//找到原点
	//画水平坐标(线,刻度),根据起始时间和结束时间定义水平坐标系
	//画垂直坐标(线,刻度),根据最大值最小值定义垂直坐标系

	int clientWidth = m_Size.cx-50;
	int clientHeight = m_Size.cy-20;

	CPen red_pen;
	red_pen.CreatePen(PS_SOLID, 0, RGB(255,0,0));
	pDC->SelectObject(red_pen);

	pDC->MoveTo(0, clientHeight);
	pDC->LineTo(m_Size.cx, clientHeight);

	pDC->MoveTo(clientWidth, 0);
	pDC->LineTo(clientWidth, m_Size.cy);

	if (m_GraphValuesCount>0)
	{
		int drawindex = 0;
		int drawcount = m_GraphValuesCount;
		if (m_GraphValuesCount>100)
		{
			drawindex = m_GraphValuesCount-100;
			drawcount = 100;
		}

		double segmentWidth = clientWidth/drawcount;
		//for(int i=0;i<drawcount;i++)
		//{
		//	pDC->MoveTo(i*(int)segmentWidth, clientHeight);
		//	pDC->LineTo(i*(int)segmentWidth, m_Size.cy);
		//}

		//求出最低值和最高值
		_2DKLineGraphValues* cur_val = m_GraphValues;
		while(cur_val!=NULL)
		{
			int index = cur_val->index;
			if (index>=drawindex)
			{
				index = index-drawindex;
				double min = cur_val->minvalue;
				double max = cur_val->maxvalue;
				double week = cur_val->weekma;
				double halfmonth = cur_val->halfmonthma;
				double month = cur_val->monthma;
				double quarter = cur_val->quarterma;

				if (m_DisplayMinValue>min)
					m_DisplayMinValue = min;
				if (m_DisplayMinValue>week)
					m_DisplayMinValue = week;
				if (m_DisplayMinValue>halfmonth)
					m_DisplayMinValue = halfmonth;
				if (m_DisplayMinValue>month)
					m_DisplayMinValue = month;
				if (m_DisplayMinValue>quarter)
					m_DisplayMinValue = quarter;

				if (m_DisplayMaxValue<max)
					m_DisplayMaxValue = max;
				if (m_DisplayMaxValue<week)
					m_DisplayMaxValue = week;
				if (m_DisplayMaxValue<halfmonth)
					m_DisplayMaxValue = halfmonth;
				if (m_DisplayMaxValue<month)
					m_DisplayMaxValue = month;
				if (m_DisplayMaxValue<quarter)
					m_DisplayMaxValue = quarter;
			}
			cur_val = cur_val->next;
		}

		double unitScale = (clientHeight-40)/(m_DisplayMaxValue-m_DisplayMinValue);
		
		CPoint *weekmapoints = new CPoint[drawcount];
		CPoint *halfmonthmapoints = new CPoint[drawcount];
		CPoint *monthmapoints = new CPoint[drawcount];
		CPoint *quartermapoints = new CPoint[drawcount];

		int cur_month = 0;
		cur_val = m_GraphValues;
		while(cur_val!=NULL)
		{
			int index = cur_val->index;
			double min = cur_val->minvalue;
			double max = cur_val->maxvalue;
			double start = cur_val->startvalue;
			double end = cur_val->endvalue;
			double week = cur_val->weekma;
			double halfmonth = cur_val->halfmonthma;
			double month = cur_val->monthma;
			double quarter = cur_val->quarterma;
			CTime time = CTime(cur_val->t);

			if (index>=drawindex)
			{
				index = index-drawindex;
				
				if (cur_month!=0)
				{
					if (time.GetMonth()!=cur_month)
					{
						CPen red_pen;
						red_pen.CreatePen(PS_SOLID, 0, RGB(255,0,0));
						pDC->SelectObject(red_pen);

						CFont font;   
						font.CreatePointFont(90,   "MyFont");   
						pDC->SelectObject(font);   

						CRect monthRect(index*(int)segmentWidth+(int)(0.5*(int)segmentWidth)+3,m_Size.cy-20,index*(int)segmentWidth+(int)(0.5*(int)segmentWidth)+10,m_Size.cy);
						CString strMonth;
						strMonth.Format("%d",time.GetMonth());
						pDC->SetTextColor(RGB(255,0,0));
						pDC->SetBkColor(RGB(0,0,0));
						pDC->DrawText(strMonth,&monthRect, DT_VCENTER | DT_SINGLELINE );

						pDC->MoveTo(index*(int)segmentWidth+(int)(0.5*(int)segmentWidth), clientHeight);
						pDC->LineTo(index*(int)segmentWidth+(int)(0.5*(int)segmentWidth), m_Size.cy);

					}
				}
				if (time.GetMonth()!=cur_month)
				{
					cur_month = time.GetMonth();
				}

				if (index ==0)
				{
					CPen red_pen;
					red_pen.CreatePen(PS_SOLID, 0, RGB(255,0,0));
					pDC->SelectObject(red_pen);

					CFont font;   
					font.CreatePointFont(90,   "MyFont");   
					pDC->SelectObject(font);   

					CRect yearRect(0,m_Size.cy-20,50,m_Size.cy);
					CString strYear;
					strYear.Format("%d %d",time.GetYear(),time.GetMonth());
					pDC->SetTextColor(RGB(255,0,0));
					
					pDC->SetBkColor(RGB(0,0,0));
					pDC->DrawText(strYear,&yearRect, DT_VCENTER | DT_SINGLELINE );
				}
				else
				{
				}
				if (start>end)
				{
					//画绿线
					int x1 = (int)(segmentWidth*(0.1)+(segmentWidth*(index)));
					int y1 = (int)((m_DisplayMaxValue-start)*unitScale+20);
					int x2 = (int)(segmentWidth*(0.9)+(segmentWidth*(index)));
					int y2 = (int)((m_DisplayMaxValue-end)*unitScale+20);
					CBrush greenBrush(RGB(0,255,255));
					CRect greenlineRect(x1,y1,x2,y2);
					pDC->FillRect(greenlineRect,&greenBrush);

					int x3 = (x2-x1)/2+x1;
					int y3 = (int)((m_DisplayMaxValue-max)*unitScale+20);
					int x4 = (x2-x1)/2+x1;
					int y4 = (int)((m_DisplayMaxValue-min)*unitScale+20);
					CPen green_pen;
					green_pen.CreatePen(PS_SOLID, 0, RGB(0,255,255));
					pDC->SelectObject(green_pen);

					pDC->MoveTo(x3, y3);
					pDC->LineTo(x4, y4);
				}
				else if (start==end)
				{
					//画白线
					int x1 = (int)(segmentWidth*(0.1)+(segmentWidth*(index)));
					int x2 = (int)(segmentWidth*(0.9)+(segmentWidth*(index)));

					int y1 = (int)((m_DisplayMaxValue-start)*unitScale+20);

					CPen white_pen;
					white_pen.CreatePen(PS_SOLID, 0, RGB(255,255,255));
					pDC->SelectObject(white_pen);

					pDC->MoveTo(x1, y1);
					pDC->LineTo(x2, y1);

					int x3 = (x2-x1)/2+x1;
					int y3 = (int)((m_DisplayMaxValue-max)*unitScale+20);
					int y4 = (int)((m_DisplayMaxValue-min)*unitScale+20);

					pDC->MoveTo(x3, y3);
					pDC->LineTo(x3, y4);


				}
				else if (start<end)
				{
					//画红线
					int x1 = (int)(segmentWidth*(0.1)+(segmentWidth*(index)));
					int y1 = (int)((m_DisplayMaxValue-end)*unitScale+20);
					int x2 = (int)(segmentWidth*(0.9)+(segmentWidth*(index)));
					int y2 = (int)((m_DisplayMaxValue-start)*unitScale+20);
					CPen red_pen;
					red_pen.CreatePen(PS_SOLID, 0, RGB(255,0,0));
					pDC->SelectObject(red_pen);
					CRect redlineRect(x1,y1,x2,y2);
					pDC->Rectangle(redlineRect);

					int x3 = (x2-x1)/2+x1;
					int y3 = (int)((m_DisplayMaxValue-max)*unitScale+20);
					int x4 = (x2-x1)/2+x1;
					int y4 = (int)((m_DisplayMaxValue-min)*unitScale+20);

					pDC->MoveTo(x3, y3);
					pDC->LineTo(x4, y1);

					pDC->MoveTo(x3, y2);
					pDC->LineTo(x4, y4);
				}


				weekmapoints[index].x = (int)(segmentWidth*(0.5)+(segmentWidth*(index)));
				weekmapoints[index].y = (int)((m_DisplayMaxValue-week)*unitScale+20);

				halfmonthmapoints[index].x = (int)(segmentWidth*(0.5)+(segmentWidth*(index)));
				halfmonthmapoints[index].y = (int)((m_DisplayMaxValue-halfmonth)*unitScale+20);

				monthmapoints[index].x = (int)(segmentWidth*(0.5)+(segmentWidth*(index)));
				monthmapoints[index].y = (int)((m_DisplayMaxValue-month)*unitScale+20);

				quartermapoints[index].x = (int)(segmentWidth*(0.5)+(segmentWidth*(index)));
				quartermapoints[index].y = (int)((m_DisplayMaxValue-quarter)*unitScale+20);
			}
			cur_val = cur_val->next;
		}
		//画5日均线
		CPen white_pen;
		white_pen.CreatePen(PS_SOLID, 0, RGB(255,255,255));
		pDC->SelectObject(white_pen);
		pDC->Polyline(weekmapoints,drawcount);
		//画10日均线
		CPen yellow_pen;
		yellow_pen.CreatePen(PS_SOLID, 0, RGB(255,255,0));
		pDC->SelectObject(yellow_pen);
		pDC->Polyline(halfmonthmapoints,drawcount);
		//画20日均线
		CPen purple_pen;
		purple_pen.CreatePen(PS_SOLID, 0, RGB(255,0,255));
		pDC->SelectObject(purple_pen);
		pDC->Polyline(monthmapoints,drawcount);
		//画60日均线
		CPen green_pen;
		green_pen.CreatePen(PS_SOLID, 0, RGB(0,255,0));
		pDC->SelectObject(green_pen);
		pDC->Polyline(quartermapoints,drawcount);

		delete weekmapoints;
		delete halfmonthmapoints;
		delete monthmapoints;
		delete quartermapoints;

	}
}


void C2DKLineGraph::SetValue(__time64_t t, double startvalue, double maxvalue, double minvalue, double endvalue)
{
	m_GraphValuesCount++;

	_2DKLineGraphValues* new_val = new _2DKLineGraphValues;
	new_val->t = t;
	new_val->minvalue = minvalue;
	new_val->maxvalue = maxvalue;
	new_val->startvalue = startvalue;
	new_val->endvalue = endvalue;
	new_val->next = NULL;
	new_val->prev = NULL;

	_2DKLineGraphValues* cur_val = m_GraphValues;
	if(cur_val == NULL)
	{
		m_MinValue = new_val->minvalue;
		m_MaxValue = new_val->maxvalue;
		new_val->index = 0;
		m_GraphValues = new_val;
	}
	else
	{
		int index = 1;
		while(cur_val->next!=NULL)
		{
			cur_val = cur_val->next;
			index++;
		}
		new_val->index = index;
		new_val->prev = cur_val;
		cur_val->next = new_val;
	}

	new_val->weekma = GetMAValue(new_val,5);
	new_val->halfmonthma = GetMAValue(new_val,10);
	new_val->monthma = GetMAValue(new_val,20);
	new_val->quarterma = GetMAValue(new_val,60);

	if (new_val->minvalue<m_MinValue)
	{
		m_MinValue = new_val->minvalue;
	}
	if (new_val->maxvalue>m_MaxValue)
	{
		m_MaxValue = new_val->maxvalue;
	}
}


void C2DKLineGraph::SetGraphSize(CSize g_size)
{
	m_Size = g_size;
}


void C2DKLineGraph::ClearGraph()
{
	_2DKLineGraphValues* prev_val; 
	_2DKLineGraphValues* cur_val = m_GraphValues;
	while(cur_val!=NULL)
	{
		prev_val = cur_val;
		cur_val = cur_val->next;
		delete prev_val;
	}
	m_GraphValues = NULL;
	m_MaxValue = 0;
	m_MinValue = 999999;
	m_DisplayMaxValue = 0;
	m_DisplayMinValue = 999999;
	m_GraphValuesCount =0;
}

double C2DKLineGraph::GetMAValue(_2DKLineGraphValues* cur_val,int period)
{

	_2DKLineGraphValues* tmp_val;
	int i =0;
	double fivematotal= 0;
	double fivemavalue = 0;
	tmp_val = cur_val;
	while(tmp_val!=NULL && i<period)
	{
		if (tmp_val!=NULL)
		{
			fivematotal += tmp_val->endvalue;
		}
		tmp_val = tmp_val->prev;
		i++;
	}
	if (i==period)
	{
		fivemavalue = fivematotal/period;
	}
	return fivemavalue;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -