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

📄 graph.h

📁 Visual C++应用教程-源代码 本书在复习C++基础知识后
💻 H
字号:
#include <math.h>

class CGraph : public CObject
{
public:
	CGraph::CGraph();
	CGraph::CGraph(CRect rcDraw);
	CGraph::CGraph(CRect rcDraw, int nMode);
	void SetDrawRect(CRect rcDraw);
	void SetDrawMode(int nMode);
	void AddData(unsigned int data);		// 添加数据
	void Draw(CDC *pDC, bool isDispData = FALSE);	
	// 绘制,当isDispData务TRUE,在直方图的顶上显示数字或饼图中显示百分比
private:
	CRect m_rectDraw;				// 用于绘制直方图和饼图的整个范围
	int   m_nMode;					// 0表示直方图,其它值表示饼图
	CUIntArray  m_uDataArray;		// 用于存放各个分量的值
	LOGFONT m_lfData;

	void DrawBar(CDC *pDC, bool isDispData);
	void DrawPie(CDC *pDC);
	void InitGraph(CRect rcDraw, int nMode);
};

CGraph::CGraph()
{
	CRect rc(0, 0, 100, 100);
	InitGraph(rc, 0);
}
CGraph::CGraph(CRect rcDraw)
{
	InitGraph(rcDraw, 0);
}
CGraph::CGraph(CRect rcDraw, int nMode)
{
	InitGraph(rcDraw, nMode);
}
void CGraph::InitGraph(CRect rcDraw, int nMode)
{
	SetDrawRect(rcDraw);
	SetDrawMode(nMode);

	memset(&m_lfData, 0, sizeof(LOGFONT));	
	m_lfData.lfHeight = -13;
	m_lfData.lfCharSet = GB2312_CHARSET;
	strcpy((LPSTR)&(m_lfData.lfFaceName), "宋体");
}
void CGraph::SetDrawRect(CRect rcDraw)
{
	m_rectDraw = rcDraw;
}
void CGraph::SetDrawMode(int nMode)
{
	m_nMode = nMode;
}
void CGraph::AddData(unsigned int data)					// 添加数据
{
	m_uDataArray.Add(data);
}
void CGraph::Draw(CDC *pDC, bool isDispData)
{
	// 绘制背景区域
	pDC->FillSolidRect( m_rectDraw, RGB(255,255,255));
	pDC->Draw3dRect( m_rectDraw, RGB( 96, 96, 96 ), RGB( 255, 255, 255 ) );
	m_rectDraw.InflateRect( -10, -10 );

	if (m_nMode)
		DrawPie(pDC);
	else
		DrawBar(pDC, isDispData);
}

void CGraph::DrawBar(CDC *pDC, bool isDispData)
{
	// 计算最大的量
	UINT nData, nDataNum, nDataMax = 0;
	nDataNum = m_uDataArray.GetSize();
	if (nDataNum < 1) return;

	for (UINT i=0; i<nDataNum; i++) {
		nData = m_uDataArray.GetAt(i);
		if (nDataMax < nData)	nDataMax = nData;
	}
	double dbPerHeight = (double)(m_rectDraw.Height() - 20) / (double)nDataMax;
	int nPerWidth = m_rectDraw.Width() / nDataNum;

	UINT nHatch[] = {HS_BDIAGONAL, HS_FDIAGONAL, HS_CROSS, HS_DIAGCROSS, HS_HORIZONTAL, HS_VERTICAL};
	int nIndex = 0;
	CRect rcDraw = m_rectDraw;

	CFont		cf;	
	cf.CreateFontIndirect(&m_lfData); 
	CFont* oldfont = pDC->SelectObject(&cf);

	for (i=0; i<nDataNum; i++) 
	{
		nData = m_uDataArray.GetAt(i);

		CBrush brush(nHatch[nIndex], RGB(64,64,64));
		rcDraw.right = rcDraw.left + nPerWidth;
		rcDraw.top = rcDraw.bottom - (int)(nData*dbPerHeight);

		CBrush* oldBrush = pDC->SelectObject(&brush);
		pDC->Rectangle(rcDraw);
		pDC->SelectObject(oldBrush);

		if (isDispData) {
			CRect rcData = rcDraw;
			rcData.bottom = rcData.top;
			rcData.top -= 20;
			CString str;
			str.Format("%d", nData);
			pDC->DrawText(str, rcData, DT_VCENTER | DT_CENTER | DT_SINGLELINE );
		}

		nIndex++;
		if (nIndex >= 6) nIndex = 0;
		rcDraw.left = rcDraw.right;
	}

	pDC->SelectObject(oldfont);				// 恢复设备环境原来的属性
}
void CGraph::DrawPie(CDC *pDC)
{
	// 计算最大的量
	UINT nData, nDataNum, nDataSum = 0;
	nDataNum = m_uDataArray.GetSize();
	if (nDataNum < 1) return;

	for (UINT i=0; i<nDataNum; i++) 
		nDataSum += m_uDataArray.GetAt(i);	// 计算和

	// 调整绘图的范围,使之成为一个正方形区域
	CRect rcDraw = m_rectDraw;

	rcDraw.right	-= 68;

	int nDelta = rcDraw.Width() - rcDraw.Height();
	if (nDelta > 0)
		rcDraw.DeflateRect(nDelta/2, 0);
	else
		rcDraw.DeflateRect(0, -nDelta/2);

	double dbPer = (double)(3.14159 * 2.0) / (double)nDataSum;	// 每度相当于多少数值

	UINT nColor[] = {RGB(0,0,0), RGB(64, 64, 64), RGB(128, 128, 128), RGB(160, 160, 160),
					RGB(192, 192, 192), RGB(224, 224, 224)};
	int nIndex = 0, x, y;
	CPoint pt1 = rcDraw.CenterPoint(), pt2;
	pt1.x = rcDraw.right;

	CFont cf;	
	cf.CreateFontIndirect(&m_lfData); 
	CFont* oldfont = pDC->SelectObject(&cf);

	double dbDegree = 0;

	CRect	rcHint( rcDraw.right + 20, 20, rcDraw.right + 40, 34 );
	CString	strData;

	for (i=0; i<nDataNum; i++) 
	{
		nData = m_uDataArray.GetAt(i);
		strData.Format( "%d", nData );

		dbDegree += (double)nData * dbPer;
		x = (int)((double)rcDraw.Width()/2.0 * cos(dbDegree));
		y = (int)((double)rcDraw.Width()/2.0 * sin(dbDegree));
		pt2 = rcDraw.CenterPoint() + CPoint(x,y);

		CBrush brush(nColor[nIndex]);
		CBrush* oldBrush = pDC->SelectObject(&brush);
		pDC->Pie(rcDraw, pt2, pt1);
		pDC->Rectangle( rcHint );
		pDC->TextOut( rcHint.right + 2, rcHint.top, strData );
		pDC->SelectObject(oldBrush);

		rcHint.OffsetRect( 0, 16 );
		nIndex++;
		if (nIndex >= 6) nIndex = 0;
		pt1 = pt2;
	}

	pDC->SelectObject(oldfont);				// 恢复设备环境原来的属性
}

⌨️ 快捷键说明

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