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

📄 xgraphaxis.cpp

📁 Displaying large amounts of technical data in a chart can be a frustrating task. You can find tons o
💻 CPP
📖 第 1 页 / 共 4 页
字号:
					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 + -