📄 xgraph.cpp
字号:
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 + -