📄 barline.h
字号:
#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 + -