📄 barline.h
字号:
HPEN hPen, hOldPen;
hPen = ::CreatePen(LineStyle, LineWidth, crTable[nRow + 1]);
hOldPen = (HPEN)::SelectObject(m_hDC, hPen);
int nHPos = ptOrigin.x;
for (int nCol = 0; nCol < m_nDataCols; nCol ++)
{
int nVPos;
nVPos = (int)((*pData++) * sizePixelsPerTick.cy / nValuePerTick);
if (nCol == 0)
::MoveToEx(m_hDC, nHPos, ptOrigin.y - nVPos, NULL);
else
::LineTo(m_hDC, nHPos, ptOrigin.y - nVPos);
nHPos += sizePixelsPerTick.cx;
}
if (m_bEnableLegend)
CGraphics::Legend(crTable[nRow + 1], nRow + 1, m_pRowsLable[nRow].c_str());
::SelectObject(m_hDC, hOldPen);
::DeleteObject(hPen);
}
}
template<class T>
void CBarLine<T>::Bar(bool HasGrid, bool bVert)
{
m_bHasGrid = HasGrid;
T nMaxValue = GetMaxValue();
double nValuePerTick = GetTickValue(nMaxValue, 5);
int nVTicks = bVert ? 5 : m_nDataCols;
int nHTicks = bVert ? m_nDataCols : 5;
SIZE sizeGraph;
SIZE sizePixelsPerTick;
POINT ptOrigin;
int nCharHeight = GetBarLineMetrics(nHTicks, nVTicks, sizeGraph, sizePixelsPerTick, ptOrigin);
AxesTicks(ptOrigin, sizePixelsPerTick, nHTicks, nVTicks,
bVert ? TICKS_VERT : TICKS_HORZ);
PlotCaptions(ptOrigin, sizePixelsPerTick, (T)0, nValuePerTick,
6, nCharHeight, bVert);
// offset Origin to plot column letters in middle of Division
POINT ptTemp;
ptTemp.x = ptOrigin.x;
ptTemp.y = ptOrigin.y;
if (!bVert)
ptTemp.y -= sizePixelsPerTick.cy / 2;
else
ptTemp.x += sizePixelsPerTick.cx / 2;
PlotCaptions(ptTemp, sizePixelsPerTick,
m_nDataCols, nCharHeight, !bVert);
// m_nDataRows bars per division, plus 1 bar width for space
int nDataSetWidth = bVert ? sizePixelsPerTick.cx : sizePixelsPerTick.cy;
int nBarWidth = nDataSetWidth / (m_nDataRows + 1);
int nSpaceWidth = (nDataSetWidth - (m_nDataRows * nBarWidth)) / 2;
// in the loop, xPos means distance from origin along Data Set axis
// not necessarily horizontal position
if (m_bLegendShadow && m_bEnableLegend)
DrawShadow(m_nDataRows);
for (int nCol = 0; nCol < m_nDataCols; nCol++)
{
int xPos = nDataSetWidth * nCol + nSpaceWidth;
for (int nRow = 0; nRow < m_nDataRows; nRow++)
{
T Value;
int yPos;
Value = m_pData[nRow * m_nDataCols + nCol];
yPos = (int)(Value*(bVert ? sizePixelsPerTick.cy : sizePixelsPerTick.cx)
/ nValuePerTick);
HBRUSH hBrush = ::CreateSolidBrush(crTable[nRow+1]);
HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush);
if (bVert)
::Rectangle(m_hDC, ptOrigin.x + xPos, ptOrigin.y - yPos,
ptOrigin.x + xPos + nBarWidth, ptOrigin.y);
else
::Rectangle(m_hDC, ptOrigin.x, ptOrigin.y - xPos - nBarWidth,
ptOrigin.x + yPos, ptOrigin.y - xPos);
if (m_bEnableLegend && nCol == m_nDataCols - 1)
Legend(crTable[nRow + 1], nRow + 1, m_pRowsLable[nRow].c_str());
::SelectObject(m_hDC, hBrold);
::DeleteObject(hBrush);
xPos += nBarWidth;
}
}
}
template<class T>
void CBarLine<T>::Bar3D(bool HasGrid, bool bVert)
{
m_bHasGrid = HasGrid;
T nMaxValue = GetMaxValue();
double nValuePerTick = GetTickValue(nMaxValue, 5);
int nVTicks = bVert ? 5 : m_nDataCols;
int nHTicks = bVert ? m_nDataCols : 5;
// Tell Chart Metrics that there is an extra division in both directions
SIZE sizeGraph;
SIZE sizePixelsPerTick;
POINT ptOrigin;
int nCharHeight = GetBarLineMetrics(nHTicks + 1, nVTicks + 1, sizeGraph, sizePixelsPerTick, ptOrigin);
int nColWidth = bVert ? sizePixelsPerTick.cx : sizePixelsPerTick.cy;
int nDivHeight = bVert ? sizePixelsPerTick.cy : sizePixelsPerTick.cx;
// Determine offsets of each column
int deltaX = sizePixelsPerTick.cx / m_nDataRows;
int deltaY = sizePixelsPerTick.cy / m_nDataRows;
int nHeight = sizePixelsPerTick.cy * nVTicks;
int nWidth = sizePixelsPerTick.cx * nHTicks;
::MoveToEx(m_hDC, ptOrigin.x, ptOrigin.y - nHeight, NULL);
::LineTo(m_hDC, ptOrigin.x, ptOrigin.y);
::LineTo(m_hDC, ptOrigin.x + nWidth, ptOrigin.y);
POINT ptOffset;
ptOffset.x = ptOrigin.x;
ptOffset.y = ptOrigin.y;
ptOffset.x += m_nDataRows * deltaX;
ptOffset.y -= m_nDataRows * deltaY;
::MoveToEx(m_hDC, ptOffset.x, ptOffset.y - nHeight, NULL);
::LineTo(m_hDC, ptOffset.x, ptOffset.y);
::LineTo(m_hDC, ptOffset.x + nWidth, ptOffset.y);
// Draw top and right edges of back of grid
int nTop = ptOffset.y - sizePixelsPerTick.cy * nVTicks;
int nRight = ptOffset.x + sizePixelsPerTick.cx * nHTicks;
::MoveToEx(m_hDC, ptOrigin.x, nTop + m_nDataRows * deltaY, NULL);
::LineTo(m_hDC, ptOffset.x, nTop);
::LineTo(m_hDC, nRight, nTop);
::LineTo(m_hDC, nRight, ptOffset.y);
::LineTo(m_hDC, nRight - m_nDataRows * deltaX, ptOrigin.y);
if (m_bHasGrid)
{
HPEN hPen, hOldPen;
hPen = ::CreatePen(PS_DOT, 0, m_nGridColor);
hOldPen = (HPEN)::SelectObject(m_hDC, hPen);
// Draw Value lines
if (bVert)
{ // Horizontal lines for vertical bars
int yPos = 0;
for (int nTick = 0; nTick < nVTicks; nTick++)
{
::MoveToEx(m_hDC, ptOrigin.x, ptOrigin.y - yPos, NULL);
::LineTo(m_hDC, ptOffset.x, ptOffset.y - yPos);
::LineTo(m_hDC, nRight, ptOffset.y - yPos);
yPos += sizePixelsPerTick.cy;
}
}
else // Vertical Lines for Horizontal Bars
{
int xPos = 0;
for (int nTick = 0; nTick < nHTicks; nTick++)
{
::MoveToEx(m_hDC, ptOrigin.x + xPos, ptOrigin.y, NULL);
::LineTo(m_hDC, ptOffset.x + xPos, ptOffset.y);
::LineTo(m_hDC, ptOffset.x + xPos, nTop);
xPos += sizePixelsPerTick.cx;
}
}
::SelectObject(m_hDC, hOldPen);
::DeleteObject(hPen);
}
PlotCaptions(ptOrigin, sizePixelsPerTick, (T)0, nValuePerTick,
6, nCharHeight, bVert);
// offset Origin to plot column letters in middle of Division
POINT ptTemp;
ptTemp.x = ptOrigin.x;
ptTemp.y = ptOrigin.y;
if (!bVert)
ptTemp.y -= sizePixelsPerTick.cy / 2;
else
ptTemp.x += sizePixelsPerTick.cx / 2;
PlotCaptions(ptTemp, sizePixelsPerTick, m_nDataCols, nCharHeight, !bVert);
// 2/3 of division used for bar--centered in division
int nDivWidth = bVert ? sizePixelsPerTick.cx : sizePixelsPerTick.cy;
int nBarWidth = nDivWidth * 2 / 3;
int nSpaceWidth = nDivWidth / 6;
// in the loop, xPos means distance from origin along Column axis
// not necessarily horizontal position
if (m_bLegendShadow && m_bEnableLegend)
DrawShadow(m_nDataRows);
for (int nRow = m_nDataRows; nRow--;)
{
int xPos = (bVert ? deltaX : deltaY) * nRow + nSpaceWidth;
int yOffset = (bVert ? deltaY : deltaX) * nRow;
HBRUSH hBrush, hBrold;
hBrush = ::CreateSolidBrush(crTable[nRow+1]);
hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush);
for (int nCol = 0; nCol < m_nDataCols; nCol++)
{
int yPos;
float Value = m_pData[nRow * m_nDataCols + nCol];
yPos = (int)(Value * (bVert ? sizePixelsPerTick.cy : sizePixelsPerTick.cx)
/nValuePerTick) + yOffset;
RECT rcFace;
if (bVert)
{
rcFace.left = ptOrigin.x + xPos;
rcFace.top = ptOrigin.y - yPos;
rcFace.right = rcFace.left + nBarWidth + 1;
rcFace.bottom = ptOrigin.y - yOffset;
}
else
{
rcFace.left = ptOrigin.x + yOffset;
rcFace.bottom = ptOrigin.y - xPos;
rcFace.right = ptOrigin.x + yPos + 1;
rcFace.top = rcFace.bottom - nBarWidth;
}
// Paint front face
::Rectangle(m_hDC, rcFace.left, rcFace.top, rcFace.right, rcFace.bottom);
rcFace.right--;
// Paint top face
POINT ptArray[4];
ptArray[0].x = rcFace.left;
ptArray[0].y = rcFace.top;
ptArray[1].x = ptArray[0].x + deltaX;
ptArray[1].y = ptArray[0].y - deltaY;
ptArray[3].x = rcFace.right;
ptArray[3].y = rcFace.top;
ptArray[2].x = ptArray[3].x + deltaX;
ptArray[2].y = ptArray[3].y - deltaY;
::Polygon(m_hDC, ptArray, 4);
// Leave points 2 & 3 the same
// for right face
ptArray[0].x = rcFace.right;
ptArray[0].y = rcFace.bottom;
ptArray[1].x = ptArray[0].x + deltaX;
ptArray[1].y = ptArray[0].y - deltaY;
::Polygon(m_hDC, ptArray, 4);
xPos += nDivWidth;
if (m_bEnableLegend && nCol == m_nDataCols - 1)
Legend(crTable[nRow + 1], nRow + 1, m_pRowsLable[nRow].c_str());
}
::SelectObject(m_hDC, hBrold);
::DeleteObject(hBrush);
}
}
template<class T>
void CBarLine<T>::GanttBar(bool HasGrid, bool bVert)
{
m_bHasGrid = HasGrid;
double nMaxValue = -1.0e-30;
T* pData = m_pData;
for (int nRow = 0; nRow < m_nDataRows; nRow++)
{
double nSum = 0.0;
for (int nCol = 0; nCol < m_nDataCols; nCol++)
nSum += *pData++;
if (nSum > nMaxValue)
nMaxValue = nSum;
}
double nValuePerTick = GetTickValue(nMaxValue, 5);
int nVTicks = bVert ? 5 : m_nDataRows;
int nHTicks = bVert ? m_nDataRows : 5;
SIZE sizeGraph;
SIZE sizePixelsPerTick;
POINT ptOrigin;
int nCharHeight = GetBarLineMetrics(nHTicks, nVTicks, sizeGraph, sizePixelsPerTick, ptOrigin);
AxesTicks(ptOrigin, sizePixelsPerTick, nHTicks, nVTicks, bVert ? TICKS_VERT : TICKS_HORZ);
PlotCaptions(ptOrigin, sizePixelsPerTick, (T)0, nValuePerTick, 6, nCharHeight, bVert);
// offset Origin to plot row numbers in middle of Division
POINT ptTemp;
ptTemp.x = ptOrigin.x;
ptTemp.y = ptOrigin.y;
if (!bVert)
ptTemp.y -= sizePixelsPerTick.cy / 2;
else
ptTemp.x += sizePixelsPerTick.cx / 2;
PlotGanttCaptions(ptTemp, sizePixelsPerTick, m_nStartRow, m_nDataRows, nCharHeight, !bVert);
// 2/3 of division used for bar--centered in division
int nDivWidth = bVert ? sizePixelsPerTick.cx : sizePixelsPerTick.cy;
int nBarWidth = nDivWidth * 2 / 3;
int nSpaceWidth = nDivWidth / 6;
// in the loop, xPos means distance from origin along Data Set axis
// not necessarily horizontal position
pData = m_pData;
if (m_bLegendShadow && m_bEnableLegend)
DrawShadow(m_nDataCols);
for (nRow = 0; nRow < m_nDataRows; nRow++)
{
int xPos = nDivWidth * nRow + nSpaceWidth;
int yPos = 0;
for (int nCol = 0; nCol < m_nDataCols; nCol++)
{
int nValue = (int)((*pData++) * (bVert ? sizePixelsPerTick.cy : sizePixelsPerTick.cx) / nValuePerTick);
HBRUSH hBrush = ::CreateSolidBrush(crTable[nCol+1]);
HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush);
if (bVert)
::Rectangle(m_hDC, ptOrigin.x + xPos, ptOrigin.y - yPos - nValue,
ptOrigin.x + xPos + nBarWidth, ptOrigin.y - yPos + 1);
else
::Rectangle(m_hDC, ptOrigin.x + yPos, ptOrigin.y - xPos - nBarWidth,
ptOrigin.x + yPos + nValue + 1, ptOrigin.y - xPos);
if (m_bEnableLegend && nRow == m_nDataRows - 1)
Legend(crTable[nCol + 1], nCol + 1, m_pColsLable[nCol].c_str());
::SelectObject(m_hDC, hBrold);
::DeleteObject(hBrush);
yPos += nValue;
}
}
}
template<class T>
void CBarLine<T>::Legend(COLORREF cr, int Index, const char* Name)
{
m_LogFont.lfHeight = (int)(m_Size.cx / -25.0);
if (m_LogFont.lfHeight > -10)
m_LogFont.lfHeight = -10;
m_LogFont.lfWeight = 700;
m_LogFont.lfOrientation= 0;
m_LogFont.lfEscapement = 0;
m_Font = ::CreateFontIndirect(&m_LogFont);
if (m_Font)
{
int n = (m_Rect.right - GR) / 20 + 1;
int xb = GR + 2 * n;
int xe = xb + 4 * n;
int y = GT - 3 * Index * m_LogFont.lfHeight / 2;
int y1 = y + m_LogFont.lfHeight / 3;
int y2 = y - m_LogFont.lfHeight / 3;
::Rectangle(m_hDC, xb, y1, xe, y2);
int bm = ::SetBkMode(m_hDC, TRANSPARENT);
HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font);
::SetTextColor(m_hDC, cr);
SetStringAlign(LEFT, CENTER);
PrintString(xe + n, y, 0, Name);
::SelectObject(m_hDC, hOldFont);
::DeleteObject(m_Font);
::SetBkMode(m_hDC, bm);
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -