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

📄 barline.h

📁 图像编程的参考资料
💻 H
📖 第 1 页 / 共 2 页
字号:
#if !defined(__BARLINE_H__)
#define __BARLINE_H__

#include "graphics.h"
#include <string>
using namespace std;

//////////////////////////////////////////////////////////////////////////////////
////// class CBarLine
template <class T>
class CBarLine : public CGraphics
{
public:
	CBarLine();

	virtual bool SetRange(double, double, double, double) { return true; }

	enum TicksType { TICKS_NONE, TICKS_VERT, TICKS_HORZ, TICKS_BOTH };
    void SetData(T* pData, int Rows, int Cols, string* RowLables, string* ColLables);                 
	T GetMaxValue();
	void Line(bool HasGrid = true, int LineStyle = PS_SOLID, int LineWidth = 0);
	void Bar(bool HasGrid = true, bool bVert = true);
	void Bar3D(bool HasGrid = true, bool bVert = true);
	void GanttBar(bool HasGrid = true, bool bVert = true);

protected: 
	virtual void Legend(COLORREF cr, int Index, const char* Name);
	double GetTickValue(T nMaxValue, int nNumDiv);
	int GetBarLineMetrics(int nHDiv, int nVDiv, SIZE& sizeGraph, 
						  SIZE& sizePixelsPerTick, POINT& ptOrigin);
	void AxesTicks(POINT ptOrigin, SIZE sizePixelsPerTick,
			  int nHorzTicks, int nVertTicks, int nDrawTicks);
	void PlotCaptions(POINT ptOrigin, SIZE sizePixelsPerTick, T nValue, double nValuePerTick, 
					  int nNumTicks, int nCharHeight, bool bVert = true);
	void PlotGanttCaptions(POINT ptOrigin, SIZE sizePixelsPerTick, double nValuePerTick, 
					  int nNumTicks, int nCharHeight, bool bVert = true);
	void PlotCaptions(POINT ptOrigin, SIZE sizePixelsPerTick, int nNumTicks, 
					  int nCharHeight, BOOL bVert);
    
	bool	m_bHasGrid;
	T*		m_pData;
	int		m_nDataRows;
	int		m_nDataCols;
	int		m_nStartRow;
	int		m_nStartCol;
	string* m_pRowsLable;
	string* m_pColsLable; 
	double	Graduations[21];	
};

///////////////////////////////////////////////////////////////////////////////
// CBarLine operations
template<class T>
CBarLine<T>::CBarLine()
{                           
    m_nStartRow		= 1;
	m_nStartCol		= 1;
	m_bHasGrid		= false;
	m_pData			= NULL;
	m_pColsLable	= NULL;
	Graduations[0]	= 0.1;
	Graduations[1]	= 0.2;
	Graduations[2]	= 0.5;
	Graduations[3]	= 0.75;
	Graduations[4]	= 1;
	Graduations[5]	= 2;
	Graduations[6]	= 5;
	Graduations[7]	= 10;
	Graduations[8]	= 20;
	Graduations[9]	= 50;
	Graduations[10] = 100;
	Graduations[11] = 200;
	Graduations[12] = 500;
	Graduations[13] = 1000;
	Graduations[14] = 2000;
	Graduations[15] = 5000;
	Graduations[16] = 10000;
	Graduations[17] = 20000;
	Graduations[18] = 50000;
	Graduations[19] = 100000;
	Graduations[20] = 0;

	SetRange(0, 0, 0, 0);
} 

template<class T>
void CBarLine<T>::SetData(T *pData, int Rows, int Cols, string* RowsLable, string* ColsLable)
{        
	m_pData			= pData;
    m_nDataRows		= Rows;
	m_nDataCols		= Cols;
	m_pRowsLable	= RowsLable;
	m_pColsLable	= ColsLable;                      
}

template<class T>
T CBarLine<T>::GetMaxValue()
{                          
    T* pnData = m_pData;
    T nMax    = *pnData;

    for (int i = m_nDataRows * m_nDataCols - 1; i--;)
	{
		if (*pnData > nMax)
			nMax = *pnData;
		pnData++;
	}

    return nMax;
} 

template<class T>
double CBarLine<T>::GetTickValue(T nMaxValue, int nNumDiv)
{
	// Determine values for vertical ticks
	T nValuePerTick = (T)(((int)nMaxValue + nNumDiv - 1) / nNumDiv);
	for (int i = 0; Graduations[i] > 0.; i++)
	{
		if (Graduations[i] >= nValuePerTick)
		{
			return Graduations[i];
		}
	}
	return Graduations[i-1];
}

template<class T>
int CBarLine<T>::GetBarLineMetrics(int nHDiv, int nVDiv, SIZE& sizeGraph, 
								 SIZE& sizePixelsPerTick, POINT& ptOrigin)
{                       
	SIZE  sizeText;

	::GetTextExtentPoint32(m_hDC, "M", 1, &sizeText);

	sizeGraph.cx = PX;
	sizeGraph.cy = PY;
                                            
	sizePixelsPerTick.cx = sizeGraph.cx / nHDiv;
	sizePixelsPerTick.cy = sizeGraph.cy / nVDiv;

	ptOrigin.x = GL;
	ptOrigin.y = GB;

	return sizeText.cy;
}

template<class T>
void CBarLine<T>::AxesTicks(POINT ptOrigin, SIZE sizePixelsPerTick,
						   int nHorzTicks, int nVertTicks, int nDrawTicks)
{
	int nHeight = sizePixelsPerTick.cy * nVertTicks;
	int nWidth  = sizePixelsPerTick.cx * nHorzTicks;

	// Draw Axes
	if (m_bHasGrid)
		DrawRectangle(ptOrigin.x, ptOrigin.y - nHeight, ptOrigin.x + nWidth, ptOrigin.y);
	else
	{
		::MoveToEx(m_hDC, ptOrigin.x, ptOrigin.y - nHeight, NULL);
		::LineTo(m_hDC, ptOrigin.x, ptOrigin.y);
		::LineTo(m_hDC, ptOrigin.x + nWidth, ptOrigin.y);
	}
	
	int nTickSize = (sizePixelsPerTick.cx / 20);
	if (nTickSize < 6)
		nTickSize = 6;

	if (nDrawTicks & TICKS_VERT)
	{
		// Draw Vertical Ticks
		int nVPos = ptOrigin.y - sizePixelsPerTick.cy;
		int xLeft  = ptOrigin.x - nTickSize;
		int xRight = ptOrigin.x;

		for (int i = 1; i < nVertTicks; i++)
		{
			DrawLine(xLeft, nVPos, xRight, nVPos);
			nVPos -= sizePixelsPerTick.cy;
		}

		if (m_bHasGrid)
		{
			nVPos  = ptOrigin.y - sizePixelsPerTick.cy;
			HPEN  hPen, hOldPen;
			hPen = ::CreatePen(PS_DOT, 0, m_nGridColor);
			hOldPen = (HPEN)::SelectObject(m_hDC, hPen);
			for (i = 1; i < nVertTicks; i++)
			{
				DrawLine(ptOrigin.x + 1, nVPos, ptOrigin.x + nWidth - 1, nVPos);
				nVPos -= sizePixelsPerTick.cy;
			}
			::SelectObject(m_hDC, hOldPen);
			::DeleteObject(hPen);
		}
	}

	if (nDrawTicks & TICKS_HORZ)
	{
		// Draw Horizontal Ticks
		int nHPos   = ptOrigin.x + sizePixelsPerTick.cx;
		int yTop    = ptOrigin.y;
		int yBottom = ptOrigin.y + nTickSize + 1;
		for (int i = 1; i < nHorzTicks; i++)
		{
			DrawLine(nHPos, yTop, nHPos, yBottom);
			nHPos += sizePixelsPerTick.cx;
		}

		if (m_bHasGrid)
		{
			nHPos = ptOrigin.x + sizePixelsPerTick.cx;
			HPEN  hPen, hOldPen;
			hPen = ::CreatePen(PS_DOT, 0, m_nGridColor);
			hOldPen = (HPEN)::SelectObject(m_hDC, hPen);
			for (i = 1; i < nHorzTicks; i++)
			{
				DrawLine(nHPos, ptOrigin.y - nHeight + 1, nHPos, ptOrigin.y - 1);
				nHPos += sizePixelsPerTick.cx;
			}
			::SelectObject(m_hDC, hOldPen);
			::DeleteObject(hPen);
		}
	}
}

template<class T>
void CBarLine<T>::PlotCaptions(POINT ptOrigin, SIZE sizePixelsPerTick, T nValue, 
							   double nValuePerTick, int nNumTicks, int nCharHeight, bool bVert)
{                 
    char  buf[80];
    
	int nTickSize = (bVert ? sizePixelsPerTick.cx : sizePixelsPerTick.cy) / 30;
	if (nTickSize < 2)
		nTickSize = 2;

	int nPos  = bVert ? ptOrigin.y : ptOrigin.x;
	int nStep = bVert ? -sizePixelsPerTick.cy : sizePixelsPerTick.cx;

	int bm = ::SetBkMode(m_hDC, TRANSPARENT);
	SetStringAlign(bVert ? RIGHT : CENTER, TOP);
	m_LogFont.lfHeight = (int)(m_Size.cx / -30.0);
	if (m_LogFont.lfHeight > -10) m_LogFont.lfHeight = -10;
	m_LogFont.lfWeight     = 500;
	m_LogFont.lfOrientation= 0;
	m_LogFont.lfEscapement = 0;
	m_Font = ::CreateFontIndirect(&m_LogFont);
	if (m_Font)
	{
		HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font);
		SetTextColor(m_hDC, m_nTickColor); 
		for (int i = 0; i < nNumTicks; i++)
		{
			Format(3, buf, nValue);
			if (bVert)
				PrintString(GL - m_lM / 6, nPos - nCharHeight / 2, 0, buf);
			else
				PrintString(nPos, GB + m_bM / 5, 0, buf);

			nValue += nValuePerTick;
			nPos   += nStep;
		}
		::SelectObject(m_hDC, hOldFont);
		::DeleteObject(m_Font);
	}
	::SetBkMode(m_hDC, bm);
}

template<class T>
void CBarLine<T>::PlotCaptions(POINT ptOrigin, SIZE sizePixelsPerTick, 
		                       int nNumTicks, int nCharHeight, BOOL bVert)
{
	int nTickSize = (bVert ? sizePixelsPerTick.cx : sizePixelsPerTick.cy) / 30;
	if (nTickSize < 2)
		nTickSize = 2;

	int nPos  = bVert ? ptOrigin.y : ptOrigin.x;
	int nStep = bVert ? -sizePixelsPerTick.cy : sizePixelsPerTick.cx;

	int bm = ::SetBkMode(m_hDC, TRANSPARENT);
	SetStringAlign(bVert ? RIGHT : CENTER, TOP);
		m_LogFont.lfHeight = (int)(m_Size.cx / -30.0);
	if (m_LogFont.lfHeight > -10) m_LogFont.lfHeight = -10;
	m_LogFont.lfWeight     = 500;
	m_LogFont.lfOrientation= 0;
	m_LogFont.lfEscapement = 0;
	m_Font = ::CreateFontIndirect(&m_LogFont);
	if (m_Font)
	{
		HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font);
		SetTextColor(m_hDC, m_nTickColor); 
		for (int i = 0; i < nNumTicks; i++)
		{
			if (bVert)
				PrintString(GL - m_lM / 6, nPos - nCharHeight / 2, 0, m_pColsLable[i].c_str());
			else
				PrintString(nPos, GB + m_bM / 5, 0, m_pColsLable[i].c_str());
			nPos   += nStep;
		}
		::SelectObject(m_hDC, hOldFont);
		::DeleteObject(m_Font);
	}
	::SetBkMode(m_hDC, bm);
}

template<class T>
void CBarLine<T>::PlotGanttCaptions(POINT ptOrigin, SIZE sizePixelsPerTick, 
									double nValuePerTick, int nNumTicks, int nCharHeight, bool bVert)
{                 
	int nTickSize = (bVert ? sizePixelsPerTick.cx : sizePixelsPerTick.cy) / 30;
	if (nTickSize < 2)
		nTickSize = 2;

	int nPos  = bVert ? ptOrigin.y : ptOrigin.x;
	int nStep = bVert ? -sizePixelsPerTick.cy : sizePixelsPerTick.cx;

	int bm = ::SetBkMode(m_hDC, TRANSPARENT);
	SetStringAlign(bVert ? RIGHT : CENTER, TOP);
	m_LogFont.lfHeight = (int)(m_Size.cx / -30.0);
	if (m_LogFont.lfHeight > -10) m_LogFont.lfHeight = -10;
	m_LogFont.lfWeight     = 500;
	m_LogFont.lfOrientation= 0;
	m_LogFont.lfEscapement = 0;
	m_Font = ::CreateFontIndirect(&m_LogFont);
	if (m_Font)
	{
		HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font);
		SetTextColor(m_hDC, m_nTickColor); 
		for (int i = 0; i < nNumTicks; i++)
		{
			if (bVert)
				PrintString(GL - m_lM / 6, nPos - nCharHeight / 2, 0, m_pRowsLable[i].c_str());
			else
				PrintString(nPos, GB + m_bM / 5, 0, m_pRowsLable[i].c_str());
			nPos   += nStep;
		}
		::SelectObject(m_hDC, hOldFont);
		::DeleteObject(m_Font);
	}
	::SetBkMode(m_hDC, bm);
}

template<class T>
void CBarLine<T>::Line(bool HasGrid, int LineStyle, int LineWidth)
{                   
	m_bHasGrid			 = HasGrid;
	T nMaxValue			 = GetMaxValue();  
	double nValuePerTick = GetTickValue(nMaxValue, 5);
	
	SIZE  sizeGraph;
	SIZE  sizePixelsPerTick;
	POINT ptOrigin;
	int nCharHeight = GetBarLineMetrics(m_nDataCols - 1, 5, sizeGraph, sizePixelsPerTick, ptOrigin);
	AxesTicks(ptOrigin, sizePixelsPerTick, m_nDataCols - 1, 5, TICKS_BOTH);
                        
	PlotCaptions(ptOrigin, sizePixelsPerTick, (T)0, nValuePerTick, 6, nCharHeight, TRUE);					
	PlotCaptions(ptOrigin, sizePixelsPerTick, m_nDataCols, nCharHeight, FALSE);                 
		                          
	T* pData = m_pData;
	if (m_bLegendShadow && m_bEnableLegend)
		DrawShadow(m_nDataRows);

	for (int nRow = 0; nRow < m_nDataRows; nRow ++)
	{

⌨️ 快捷键说明

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