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

📄 xgraph.cpp

📁 Displaying large amounts of technical data in a chart can be a frustrating task. You can find tons o
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	for (nYAxis = 0; nYAxis < m_YAxis.size (); nYAxis++)
	{
		m_YAxis[nYAxis].m_nTop = nBottom;
		m_YAxis[nYAxis].Draw(pDC);
	}
	
	// X-Axis
	for (nXAxis = 0; nXAxis < m_XAxis.size (); nXAxis++)
		m_XAxis[nXAxis].Draw(pDC);
	
	// Setup clipping
	CRgn  clipRegion;
	CRect rectClip(m_clInnerRect.left, m_clInnerRect.top, m_clInnerRect.right, m_clInnerRect.bottom);
	
	// Should move inside CDCEx in future
	if (pDC->m_bPrinting && !pDC->m_bPrintPreview)
		pDC->AdjustRatio (rectClip);

	
	clipRegion.CreateRectRgn (rectClip.left, rectClip.top, rectClip.right, rectClip.bottom);


	// PRB: Clipping doesn't work in print preview, no idea why ...
	pDC->SelectClipRgn (&clipRegion);
		

	// Draw curves
	for (UINT nCurve = 0; nCurve < m_Data.size (); nCurve++)
		if (m_Data[nCurve].m_bVisible)
			m_Data[nCurve].Draw(pDC);

	// Draw curve markers
	for (nCurve = 0; nCurve < m_Data.size (); nCurve++)
		if (m_Data[nCurve].m_bVisible && m_Data[nCurve].m_bShowMarker)
			m_Data[nCurve].DrawMarker(pDC);

	DrawMeasures (pDC);

	// Draw zoom if active
	if (m_opOperation == opZoom && m_bLButtonDown)
		DrawZoom(pDC);
	
	if (m_opOperation == opMeasure && m_bLButtonDown)
	{
		CRect tmpRect;
		tmpRect.SetRectEmpty ();
		DrawMeasure (pDC, tmpRect);
	}

	// Draw cursor if active
	if (m_opOperation == opCursor)
		DrawCursor(pDC);

	// DrawObjects
	for (POSITION pos = m_Objects.GetHeadPosition (); pos != NULL; )
	{
		CXGraphObject *pObject = (CXGraphObject*) m_Objects.GetNext (pos);
		pObject->Draw (pDC);
	}

	if (m_bDataPointMoving)
	{
		CQuickFont font("Arial", 13, FW_NORMAL);
		CFontSelector fs(&font, pDC, false);
		pDC->SetBkMode (TRANSPARENT);
		CString cPoint;
		cPoint.Format ("%.2f", m_fCurrentEditValue);
		pDC->TextOut(m_CurrentPoint.x + 10, m_CurrentPoint.y, cPoint);
	}

	pDC->RestoreDC(nSaveDC);
	pDC->Detach();

	delete pDC;

	if (pmdc)
		delete pmdc;
	
	delete pdc;

	
}

void CXGraph::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
	
	Invalidate(TRUE);
}

#if _MFC_VER >= 0x0700
BOOL CXGraph::OnMouseWheel( UINT nFlags, short zDelta, CPoint pt )
#else
void CXGraph::OnMouseWheel( UINT nFlags, short zDelta, CPoint pt )
#endif
{

	if (nFlags & MK_SHIFT)
	{
		for (int y = 0; y < GetYAxisCount(); y++)
		{
			m_YAxis[y].SetAutoScale(false);
			double fStep = (m_YAxis[y].m_fCurMax - m_YAxis[y].m_fCurMin) / 10.0;
			if (zDelta < 0)
				m_YAxis[y].SetCurrentRange(m_YAxis[y].m_fCurMin - fStep,m_YAxis[y].m_fCurMax - fStep);
			else
				m_YAxis[y].SetCurrentRange(m_YAxis[y].m_fCurMin + fStep,m_YAxis[y].m_fCurMax + fStep);
		}
	}
	else
	{
		for (int x = 0; x < GetXAxisCount(); x++)
		{
			m_XAxis[x].SetAutoScale(false);
			double fStep = (m_XAxis[x].m_fCurMax - m_XAxis[x].m_fCurMin) / 10.0;
			if (zDelta < 0)
				m_XAxis[x].SetCurrentRange(m_XAxis[x].m_fCurMin - fStep,m_XAxis[x].m_fCurMax - fStep);
			else
				m_XAxis[x].SetCurrentRange(m_XAxis[x].m_fCurMin + fStep,m_XAxis[x].m_fCurMax + fStep);
		}
	}

	Invalidate(TRUE);

#if _MFC_VER >= 0x0700
	return TRUE;
#endif
}


void CXGraph::OnMouseMove(UINT nFlags, CPoint point) 
{
	m_bLButtonDown = (nFlags & MK_LBUTTON);

	if (m_opOperation == opMeasure && m_bLButtonDown)
		AdjustPointToData(point);

	m_CurrentPoint = point;
		
	if (m_opOperation == opCursor)
	{
		m_bTmpDC = true;
		CDCEx dc;
		dc.Attach(GetDC()->m_hDC);
		DrawCursor(&dc);
		ReleaseDC(&dc);
		dc.Detach ();
		m_bTmpDC = false;
		::PostMessage(GetParent()->m_hWnd, XG_CURSORMOVED, 0, (long) this);
	}	

	m_bObjectSelected = CheckObjectSelection(false, m_opOperation != opEditCurve);

	if (m_bLButtonDown && m_opOperation == opPan && m_clInnerRect.PtInRect (point))
	{
		if (m_OldPoint == CPoint(0,0))
			m_OldPoint = point;
		else
			DoPan(point);
	}

	if (m_bRButtonDown && m_opOperation == opCursor && m_clInnerRect.PtInRect (point))
	{
		if (m_OldPoint == CPoint(0,0))
			m_OldPoint = point;
		else
			DoPan(point);
	}

	if (m_bLButtonDown && m_opOperation == opZoom /*&& m_clInnerRect.PtInRect (point)*/)
	{
		if (m_bDoubleBuffer)
			Invalidate();
		else
		{
			CDCEx dc;
			dc.Attach(GetDC()->m_hDC);
			DrawZoom(&dc);
			ReleaseDC(&dc);
			dc.Detach ();
		}
	}
	
	if (m_bLButtonDown && m_opOperation == opMeasure /*&& m_clInnerRect.PtInRect (point)*/)
	{
		if (m_bDoubleBuffer)
			Invalidate();
		else
		{
			CDCEx dc;
			dc.Attach(GetDC()->m_hDC);
			CRect tmpRect;
			tmpRect.SetRectEmpty ();
			DrawMeasure(&dc, tmpRect);
			ReleaseDC(&dc);
			dc.Detach ();
		}
	}
	
	CWnd::OnMouseMove(nFlags, point);
}


void CXGraph::AdjustPointToData(CPoint& point)
{
	int  nYDistance = 10000000;
	int  nY = point.y;
	long nIndex;

	for (int i = 0; i < m_Data.size(); i++)
	{
		// Get xval for current position
		double fSnappedXVal = m_XAxis[m_Data[i].m_nXAxis].GetValueForPos (point.x);
		// Find index for this value
		m_XAxis[m_Data[i].m_nXAxis].GetIndexByXVal(nIndex, fSnappedXVal, i);
		
		int y = m_YAxis[m_Data[i].m_nYAxis].GetPointForValue(&m_Data[i].m_pData[nIndex]).y;
				
		if (abs(point.y - y) < nYDistance)
		{
			nYDistance = abs(point.y - y);
			nY = y;
			if (point == m_MouseDownPoint)
			{
				m_nSnappedCurve = i;
				m_MeasureDef.nIndex1 = nIndex;
				m_MeasureDef.nCurve1 = i;
			}
			else
			{
				m_nSnappedCurve1 = i;
				m_MeasureDef.nIndex2 = nIndex;
				m_MeasureDef.nCurve2 = i;
			}

		}
	}

	point.y = nY;
	
}



bool CXGraph::CheckObjectSelection(bool bEditAction, bool bCheckFocusOnly)
{
	UINT i;
	static int nXMarkerMoving = -1;
	static int nYMarkerMoving = -1;

	AFX_MANAGE_STATE(AfxGetModuleState( ));

	bool bHasNotified = false;

	if (!m_bInteraction)
		return false;

		
	// Check y axis selection
	for (i = 0; i < m_YAxis.size(); i++)
	{

		// Check for Marker selections
		if (m_opOperation == opNone)
		for (int nMarker = 0; nMarker < m_YAxis[i].m_AxisMarkers.size(); nMarker++)
		{
			CRect	   hitRect;
			TDataPoint dPoint;


			if (nYMarkerMoving == -1)
			{
			
				dPoint.fYVal = m_YAxis[i].m_AxisMarkers[nMarker].fValue;
				CPoint point = m_YAxis[i].GetPointForValue (&dPoint);

				hitRect.SetRect(m_clInnerRect.left, point.y - 10, m_clInnerRect.right, point.y + 10);
				
				if (bCheckFocusOnly && nYMarkerMoving == -1 && !m_bLButtonDown)
					if (hitRect.PtInRect (m_CurrentPoint))
						return true;
					else
						continue;
			}

			if (m_bRButtonDown && hitRect.PtInRect (m_CurrentPoint))
			{
				m_YAxis[i].DeleteAxisMarker(nMarker);
				Invalidate();
			}
						
			if (m_bLButtonDown && nYMarkerMoving == -1 && hitRect.PtInRect (m_CurrentPoint))
				nYMarkerMoving = nMarker;
			
			if (!m_bLButtonDown && nYMarkerMoving != -1)
				nYMarkerMoving = -1;

			if (nYMarkerMoving != -1 && m_bLButtonDown)
			{
				m_YAxis[i].m_AxisMarkers[nYMarkerMoving].fValue = m_YAxis[i].GetValueForPos (m_CurrentPoint.y);
				Invalidate();
			}

		}
		
		if (bCheckFocusOnly)
			if (m_YAxis[i].m_clRect.PtInRect (m_CurrentPoint))
				return true;
			else
				continue;
	
		if (m_opOperation == opNone)
		if (m_YAxis[i].m_bSelected && !m_YAxis[i].m_clRect.PtInRect (m_CurrentPoint))
		{
			double fValue = m_YAxis[i].GetValueForPos (m_CurrentPoint.y);
			m_YAxis[i].SetAxisMarker(m_YAxis[i].m_AxisMarkers.size(), fValue, 0L);
		}
		
		m_YAxis[i].m_bSelected = m_YAxis[i].m_clRect.PtInRect (m_CurrentPoint);

		
		if (m_YAxis[i].m_bSelected)
		{
			bHasNotified = true;
			::PostMessage(GetParent()->m_hWnd, bEditAction ? XG_YAXISDBLCLICK :XG_YAXISCLICK, i, (long) this);
#ifndef _WIN32_WCE
			if (bEditAction && m_bInteraction)
			{
				CChartPage dlg;
				dlg.m_pGraph = this;
				dlg.m_pGraphAxis = &m_YAxis[i];
				dlg.DoModal();		
				Invalidate();
			}
#endif
		}
	}
			 
	// Check x axis selection
	for (i = 0; i < m_XAxis.size(); i++)
	{

		// Check for Marker selections
		if (m_opOperation == opNone)
		for (int nMarker = 0; nMarker < m_XAxis[i].m_AxisMarkers.size(); nMarker++)
		{
			CRect	   hitRect;
			TDataPoint dPoint;

			if (nXMarkerMoving == -1)
			{
				dPoint.fXVal = m_XAxis[i].m_AxisMarkers[nMarker].fValue;
				CPoint point = m_XAxis[i].GetPointForValue (&dPoint);

				hitRect.SetRect(point.x - 10, m_clInnerRect.top, point.x + 10, m_clInnerRect.bottom);
				
				if (bCheckFocusOnly && nXMarkerMoving == -1 && !m_bLButtonDown)
					if (hitRect.PtInRect (m_CurrentPoint))
						return true;
					else
						continue;
			}

			if (m_bRButtonDown && hitRect.PtInRect (m_CurrentPoint))
			{
				m_XAxis[i].DeleteAxisMarker(nMarker);
				Invalidate();
			}


			if (m_bLButtonDown && nXMarkerMoving == -1 && hitRect.PtInRect (m_CurrentPoint))
				nXMarkerMoving = nMarker;

			if (!m_bLButtonDown && nXMarkerMoving != -1)
				nXMarkerMoving = -1;

			if (nXMarkerMoving != -1 && m_bLButtonDown)
			{
				m_XAxis[i].m_AxisMarkers[nXMarkerMoving].fValue = m_XAxis[i].GetValueForPos (m_CurrentPoint.x);
				Invalidate();
			}

		}
	
		if (bCheckFocusOnly)
			if (m_XAxis[i].m_clRect.PtInRect (m_CurrentPoint))
				return true;
			else
				continue;
		
		if (m_opOperation == opNone)
		if (m_XAxis[i].m_bSelected && !m_XAxis[i].m_clRect.PtInRect (m_CurrentPoint))
		{
			double fValue = m_XAxis[i].GetValueForPos (m_CurrentPoint.x);
			m_XAxis[i].SetAxisMarker(m_XAxis[i].m_AxisMarkers.size(), fValue, 0L);
		}
		
		m_XAxis[i].m_bSelected = m_XAxis[i].m_clRect.PtInRect (m_CurrentPoint);

		if (m_XAxis[i].m_bSelected && !bHasNotified)
		{
			bHasNotified = true;
			::PostMessage(GetParent()->m_hWnd, bEditAction ? XG_XAXISDBLCLICK : XG_XAXISCLICK, i, (long) this);
#ifndef _WIN32_WCE
			if (bEditAction && m_bInteraction)
			{
				CChartPage dlg;
				dlg.m_pGraph = this;
				dlg.m_pGraphAxis = &m_XAxis[i];
				dlg.DoModal();		
				Invalidate();
			}
#endif
		}
	}

	bool bCheckCurves = true;

	// Check object selection
	for (POSITION pos = m_Objects.GetHeadPosition (); pos != NULL; )
	{
		CXGraphObject *pObject = (CXGraphObject*) m_Objects.GetNext (pos);

		if (bCheckFocusOnly)
			if (pObject->m_clRect.PtInRect (m_CurrentPoint) && pObject->m_bVisible)
				return true;
			else
				continue;
		
		pObject->m_bSelected = (pObject->m_clRect.PtInRect (m_CurrentPoint) && pObject->m_bVisible);
		
		if (bEditAction && pObject->m_bSelected )
		{
			bHasNotified = true;
			bCheckCurves = false;
			pObject->Edit ();
		}
		
		if (pObject->m_bSelected && !pObject->m_bEditing && m_pTracker == NULL)
		{
			bHasNotified = true;
			pObject->BeginSize ();
			m_pTracker = &pObject->m_Tracker; 
			bCheckCurves = false;
		}

		if (!pObject->m_bSelected && pObject->m_bEditing)
			pObject->EndEdit ();

		if (!pObject->m_bSelected && pObject->m_bSizing)
		{
			m_pTracker = NULL;
			pObject->EndSize ();
		}
		
	}

	if (!bCheckFocusOnly)
		m_nSelectedSerie = -1;

	
	// Special check for moving datapoint in edit mode
	static int  nEditSerie = -1;
	static long nXIndex = -1;

	// Reset previous stored informations about last selected curve and index
	if (!m_bLButtonDown)
	{
		nXIndex = -1;
		nEditSerie = -1;
	}

	
	// check curve selection
	for (i = 0; i < m_Data.size(); i++)
	{
		CXGraphDataSerie& serie = m_Data[i];
		
		if (!serie.m_bVisible)
			continue;

		if (!bCheckFocusOnly)
			serie.m_bSelected = false;

		if (!bCheckCurves)
			continue;
		

		for (int j = 0; j < serie.m_CurveRegions.size(); j++)
		{
			CRect hitRect(serie.m_CurveRegions[j].p1.x, serie.m_CurveRegions[j].p1.y,serie.m_CurveRegions[j].p2.x, serie.m_CurveRegions[j].p2.y);
			hitRect.NormalizeRect ();
			hitRect.InflateRect (2,2,2,2);
			
			if (bCheckFocusOnly)
				if (hitRect.PtInRect (m_CurrentPoint) && serie.HitTestLine(serie.m_CurveRegions[j].p1, serie.m_CurveRegions[j].p2, m_CurrentPoint, 4))
					return true;
				else
					continue;
			
			if (hitRect.PtInRect (m_CurrentPoint) && serie.HitTestLine(serie.m_CurveRegions[j].p1, serie.m_CurveRegions[j].p2,m_CurrentPoint, 4) && !bHasNotified)
			{
				::PostMessage(GetParent()->m_hWnd, bEditAction ? XG_CURVEDBLCLICK : XG_CURVECLICK, i, (long) this);
				m_nSelectedSerie = i;

				// User is editing a datapoint
				if (nXIndex == -1)
				{
					nEditSerie = i;
					double fX = m_XAxis[serie.GetXAxis ()].GetValueForPos (m_CurrentPoint.x - serie.m_nMarkerSize / 2);
					// Remember index of moving point
					GetXAxis(serie.GetXAxis ()).GetIndexByXVal (nXIndex, fX, i);
				}
				
				serie.m_bSelected = true;
				bHasNotified = true;
#ifndef _WIN32_WCE
				if (bEditAction && m_bInteraction)
				{
					CChartPage dlg;

⌨️ 快捷键说明

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