📄 xgraphaxis.cpp
字号:
else
cTxt.Format(m_cDisplayFmt, fX2);
{
CFontSelector fs(&m_Font, pDC, false);
csText = GetTextExtentEx (pDC, cTxt);
}
CFontSelector fs(&m_Font, pDC);
if (fX1 == fX2)
{
CRect crText(fnX - csText.cx / 2, m_nTop + m_nTickSize, fnX + csText.cx / 2, m_nTop + csText.cy + m_nTickSize);
pDC->DrawText(cTxt, crText, DT_CENTER);
}
CPenSelector ps(m_crGridColor, 1, pDC, m_nGridStyle);
pDC->MoveTo(fnX, m_nTop + m_nTickSize);
// Spare last gridline to prevent axis to be overdrawn
if (!m_bShowGrid || (int)fnX == m_nLeft)
pDC->LineTo(fnX, m_nTop);
else
pDC->LineTo(fnX, m_clChart.top);
}
}
}
CPenSelector ps(m_crColor, 1, pDC);
pDC->MoveTo (m_nLeft, m_nTop);
pDC->LineTo (nChartRight, m_nTop);
DrawArc(pDC, CPoint(nChartRight, m_nTop), right, m_nArcSize);
m_clRect.SetRect(m_nLeft, m_nTop - 5, nChartRight, m_nTop + 5);
}
if (m_bSelected)
pDC->DrawFocusRect (m_clRect);
if (pTmpDC)
delete pTmpDC;
}
void CXGraphAxis::Draw(CDCEx* pDC)
{
if (m_AxisType == atLog)
{
DrawLog(pDC);
return;
}
CDCEx *pTmpDC = NULL;
if (!m_bVisible)
{
pTmpDC = new CDCEx;
pTmpDC->CreateCompatibleDC (pDC);
pDC = pTmpDC;
}
if (m_bAutoScale)
AutoScale(pDC);
m_fRange = m_fCurMax - m_fCurMin;
if (m_AxisKind == yAxis)
{
m_fSpareRange = (2*m_nArcSize);
m_fMarkerSpareSize = DrawCurveMarkers(pDC, false);
if (m_cLabel != _T(""))
{
CSize titleSize;
{
CFontSelector fs(&m_TitleFont, pDC, false);
titleSize = GetTitleSize(pDC);
m_fSpareRange += titleSize.cy;
}
}
int nChartTop = m_clChart.top + m_fMarkerSpareSize;
int nTop = m_pGraph->m_clInnerRect.top + m_fSpareRange + m_fMarkerSpareSize;
int nBottom = m_pGraph->m_clInnerRect.bottom;
double fSteps = (m_fCurMax - m_fCurMin) / m_fStep;
double fStep = ((double)(m_nTop - nChartTop - m_fSpareRange ) / fSteps);
double fnY = m_nTop;
double fnYC = fnY;
m_nRange = nBottom - nTop;
DrawColorRanges(pDC);
DrawAxisMarkers(pDC);
m_fMarkerSpareSize = DrawCurveMarkers(pDC);
if (pDC->m_bMono)
pDC->SetBkColor(RGB(255,255,255));
else
pDC->SetBkColor(m_pGraph->m_crGraphColor);
pDC->SetBkMode(OPAQUE);
if (m_cLabel != _T(""))
{
CSize titleSize;
{
CFontSelector fs(&m_TitleFont, pDC, false);
titleSize = GetTitleSize(pDC);
m_fSpareRange += titleSize.cy;
}
CFontSelector fs(&m_TitleFont, pDC);
if (m_Placement == apLeft)
{
CRect clTitle(m_nLeft - titleSize.cx - m_nTickSize, nChartTop, m_nLeft - m_nTickSize, nChartTop + titleSize.cy);
pDC->DrawText(m_cLabel, clTitle, DT_RIGHT);
}
else
{
CRect clTitle(m_nLeft + m_nTickSize, nChartTop, m_nLeft + titleSize.cx + m_nTickSize, nChartTop + titleSize.cy);
pDC->DrawText(m_cLabel, clTitle, DT_LEFT);
}
}
CString cTxt;
CSize csText;
for (double fY = m_fCurMin; fY <= m_fCurMax; fY += m_fStep, fnY -= fStep)
{
{
CFontSelector fs(&m_Font, pDC, false);
if (m_bDateTime)
#ifndef _WIN32_WCE
cTxt = COleDateTime(fY).Format(m_cDisplayFmt);
#else
cTxt = COleDateTime(fY).Format();
#endif
else
cTxt.Format(m_cDisplayFmt, fY);
csText = GetTextExtentEx (pDC, cTxt);
}
CFontSelector fs(&m_Font, pDC);
if (m_Placement == apLeft)
{
CRect crText(m_nLeft - csText.cx - m_nTickSize, fnY - csText.cy / 2, m_nLeft - m_nTickSize, fnY + csText.cy / 2);
pDC->DrawText(cTxt, crText, DT_RIGHT);
CPenSelector ps(m_crGridColor, 1, pDC, m_nGridStyle);
pDC->MoveTo(m_nLeft - m_nTickSize, fnY);
int nOldMode = pDC->SetBkMode (TRANSPARENT);
// Spare last gridline to prevent axis from being overdrawn
if (!m_bShowGrid || (int)fnY == m_nTop)
pDC->LineTo(m_nLeft, fnY);
else
pDC->LineTo(m_pGraph->m_clInnerRect.right, fnY);
pDC->SetBkMode (nOldMode);
}
if (m_Placement == apRight)
{
CRect crText(m_nLeft + m_nTickSize, fnY - csText.cy / 2, m_nLeft + csText.cx + m_nTickSize, fnY + csText.cy / 2);
pDC->DrawText(cTxt, crText, DT_LEFT);
CPenSelector ps(m_crGridColor, 1, pDC, m_nGridStyle);
pDC->MoveTo(m_nLeft + m_nTickSize, fnY);
// Spare last gridline to prevent axis from being overdrawn
int nOldMode = pDC->SetBkMode (TRANSPARENT);
if (!m_bShowGrid || (int)fnY == m_nTop)
pDC->LineTo(m_nLeft, fnY);
else
pDC->LineTo(m_pGraph->m_clInnerRect.left, fnY);
pDC->SetBkMode (nOldMode);
}
}
CPenSelector ps(m_crColor, 1, pDC);
pDC->MoveTo (m_nLeft, m_nTop);
pDC->LineTo (m_nLeft, nChartTop);
DrawArc(pDC, CPoint(m_nLeft, nChartTop), up, m_nArcSize);
m_clRect.SetRect(m_nLeft - 5, nChartTop, m_nLeft + 5, m_nTop);
// m_nRange = m_nTop - fnY - fStep;
}
else
{
m_fSpareRange = (4*m_nArcSize);
m_fMarkerSpareSize = DrawCurveMarkers(pDC, false);
if (m_cLabel != _T(""))
{
CSize titleSize;
{
CFontSelector fs(&m_TitleFont, pDC, false);
titleSize = GetTitleSize(pDC);
m_fSpareRange += titleSize.cx;
}
}
int nChartRight = m_pGraph->m_clInnerRect.right - m_fMarkerSpareSize;
int nLeft = m_pGraph->m_clInnerRect.left;
int nRight = m_pGraph->m_clInnerRect.right - m_fSpareRange - m_fMarkerSpareSize;
double fSteps = ((m_fCurMax - m_fCurMin) / m_fStep);
double fStep = ((double)(nChartRight - m_nLeft - m_fSpareRange) / fSteps);
double fnX = m_nLeft;
double fnXC = fnX;
// for (double f = m_fCurMin; f < m_fCurMax; f += m_fStep, fnXC += fStep);
m_nRange = fSteps * fStep;
//m_nRange = nChartRight - nLeft;
//m_nRange = fnXC - m_nLeft - fStep;
DrawColorRanges(pDC);
DrawAxisMarkers(pDC);
m_fMarkerSpareSize = DrawCurveMarkers(pDC);
if (pDC->m_bMono)
pDC->SetBkColor(RGB(255,255,255));
else
pDC->SetBkColor(m_pGraph->m_crGraphColor);
pDC->SetBkMode(OPAQUE);
CString cTxt;
CSize csText;
if (m_cLabel != _T(""))
{
CSize titleSize;
{
CFontSelector fs(&m_TitleFont, pDC, false);
titleSize = GetTitleSize(pDC);
m_fSpareRange += titleSize.cx;
}
CFontSelector fs(&m_TitleFont, pDC);
CRect clTitle(nChartRight - titleSize.cx, m_nTop + m_nTickSize, nChartRight, m_nTop + m_nTickSize + titleSize.cy);
pDC->DrawText(m_cLabel, clTitle, DT_LEFT);
}
for (double fX = m_fCurMin; fX < m_fCurMax; fX += m_fStep, fnX += fStep)
{
if (m_bDateTime)
#ifndef _WIN32_WCE
cTxt = COleDateTime(fX).Format(m_cDisplayFmt);
#else
cTxt = COleDateTime(fX).Format();
#endif
else
cTxt.Format(m_cDisplayFmt, fX);
{
CFontSelector fs(&m_Font, pDC, false);
csText = GetTextExtentEx (pDC, cTxt);
}
CFontSelector fs(&m_Font, pDC);
CRect crText(fnX - csText.cx / 2, m_nTop + m_nTickSize, fnX + csText.cx / 2, m_nTop + csText.cy + m_nTickSize);
pDC->DrawText(cTxt, crText, DT_CENTER);
CPenSelector ps(m_crGridColor, 1, pDC, m_nGridStyle);
pDC->MoveTo(fnX, m_nTop + m_nTickSize);
int nOldMode = pDC->SetBkMode (TRANSPARENT);
// Spare last gridline to prevent axis from being overdrawn
if (!m_bShowGrid || (int)fnX == m_nLeft)
pDC->LineTo(fnX, m_nTop);
else
pDC->LineTo(fnX, m_clChart.top);
pDC->SetBkMode (nOldMode);
}
CPenSelector ps(m_crColor, 1, pDC);
pDC->MoveTo (m_nLeft, m_nTop);
pDC->LineTo (nChartRight, m_nTop);
DrawArc(pDC, CPoint(nChartRight, m_nTop), right, m_nArcSize);
m_clRect.SetRect(m_nLeft, m_nTop - 5, nChartRight, m_nTop + 5);
// m_nRange = fnX - m_nLeft - fStep;
}
if (m_bSelected)
pDC->DrawFocusRect (m_clRect);
if (pTmpDC)
delete pTmpDC;
}
void CXGraphAxis::SetBestStep()
{
CDCEx *pDC = (CDCEx*) m_pGraph->GetDC();
if (m_AxisKind == yAxis)
{
int nTop = m_pGraph->m_clInnerRect.top + m_fSpareRange + m_fMarkerSpareSize;
int nBottom = m_pGraph->m_clInnerRect.bottom;
int nRange = nBottom - nTop;
if (nRange == 0)
nRange = 1;
int nLabelHeight = GetMaxLabelHeight(pDC);
m_fStep = (m_fCurMax - m_fCurMin) / (double) nRange * (double) nLabelHeight;
}
else
{
int nLeft = m_pGraph->m_clInnerRect.left;
int nRight = m_pGraph->m_clInnerRect.right - m_fSpareRange - m_fMarkerSpareSize;
int nRange = nRight - nLeft;
if (nRange == 0)
nRange = 1;
int nLabelWidth = GetMaxLabelWidth(pDC);
m_fStep = (m_fCurMax - m_fCurMin) / (double) nRange * (double) nLabelWidth;
}
m_pGraph->ReleaseDC(pDC);
}
bool CXGraphAxis::SetRange(double fMin, double fMax)
{
if (fMin > fMax)
return false;
if (m_AxisType == atLog)
{
// in log scale, m_fStep is not used.
if (fMin == fMax)
{
fMin *= 0.1;
fMax *= 10.0;
}
m_fStep = 0.0;
if (fMin < 1e-16)
m_fCurMin = m_fMin = 1e-16;
else
m_fCurMin = m_fMin = fMin;
if (fMax < 1e-15)
m_fCurMax = m_fMax = 1e-15;
else
m_fCurMax = m_fMax = fMax;
// Switch to exponential display if values exceed 10^6 or 10^-6
if ((fabs(m_fCurMin) > 1E6 || fabs(m_fCurMax) > 1E6) && !m_bDateTime)
m_cDisplayFmt = _T("%5.2e");
return true;
}
if (fMin == fMax)
{
fMin -= 1.0;
fMax += 1.0;
}
// Switch to exponential display if values exceed 10^6 or 10^-6
if ((fabs(fMin) > 1E6 || fabs(fMax) > 1E6) && !m_bDateTime)
m_cDisplayFmt = _T("%5.2e");
m_fCurMin = m_fMin = fMin;
m_fCurMax = m_fMax = fMax;
if (m_pGraph->IsWindowVisible())
SetBestStep();
else
m_fStep = (m_fCurMax - m_fCurMin) / 10.0;
return true;
}
bool CXGraphAxis::SetCurrentRange(double fMin, double fMax, double fStep)
{
if (fMin > fMax)
return false;
if (m_AxisType == atLog)
{
// in log scale, m_fStep is not be used.
if (fMin == fMax)
{
fMin *= 0.1;
fMax *= 10.0;
}
m_fStep = 0.0;
if (fMin < 1e-16)
m_fCurMin = 1e-16;
else
m_fCurMin = fMin;
if (fMax < 1e-15)
m_fCurMax = 1e-15;
else
m_fCurMax = fMax;
// Switch to exponential display if values exceed 10^6
if ((fabs(m_fCurMin) > 1E6 || fabs(m_fCurMax) > 1E6) && !m_bDateTime)
m_cDisplayFmt = _T("%5.2e");
return true;
}
if (fMin == fMax)
{
fMin -= 1.0;
fMax += 1.0;
}
// Switch to exponential display if values exceed 10^6 or 10^-6
if ((fabs(fMin) > 1E6 || fabs(fMax) > 1E6) && !m_bDateTime)
m_cDisplayFmt = _T("%5.2e");
m_fCurMin = fMin;
m_fCurMax = fMax;
if (fStep != 0.0)
m_fStep = fStep;
else
{
if (m_pGraph->IsWindowVisible())
SetBestStep();
else
m_fStep = (m_fCurMax - m_fCurMin) / 10.0;
}
return true;
}
void CXGraphAxis::Reset()
{
m_fCurMin = m_fMin;
m_fCurMax = m_fMax;
m_fStep = (m_fMax - m_fMin) / 10.0f;
}
void CXGraphAxis::AutoScale(CDCEx *pDC)
{
if (m_AxisType == atLog)
{
double fStep1 = 0.0;
double fStep2 = 0.0;
BOOL bFound = FALSE;
for (fStep1 = 1e-16; fStep1 < m_fCurMin; fStep1 *= 10)
{
for (fStep2 = fStep1; fStep2 < fStep1*10; fStep2 += fStep1)
{
if (fStep2 >= m_fCurMin)
{
m_fCurMin = fStep2 - fStep1;
bFound = TRUE;
break;
}
}
if (bFound == TRUE)
break;
}
bFound = FALSE;
for (fStep1 = 1e-16; fStep1 < m_fCurMax; fStep1 *= 10)
{
for (fStep2 = fStep1; fStep2 < fStep1*10; fStep2 += fStep1)
{
if (fStep2 >= m_fCurMax)
{
m_fCurMax = fStep2;
bFound = TRUE;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -