📄 xgraph.cpp
字号:
dlg.m_pGraph = this;
dlg.m_pGraphDataSerie = &serie;
dlg.DoModal();
Invalidate();
}
#endif
break;
}
}
}
m_bDataPointMoving = false;
if (m_bLButtonDown && nXIndex != -1 && m_opOperation == opEditCurve)
{
m_nmCurrentPointMoving.nCurve = nEditSerie;
m_nmCurrentPointMoving.nIndex = nXIndex;
m_nmCurrentPointMoving.dOldVal = m_Data[nEditSerie].m_pData[nXIndex].fYVal;
m_nmCurrentPointMoving.dNewVal = GetYAxis(m_Data[nEditSerie].GetYAxis()).GetValueForPos (m_CurrentPoint.y);
// Inform parent
::PostMessage(GetParent()->m_hWnd, XG_POINTCHANGED, (long)&m_nmCurrentPointMoving, (long) this);
m_Data[nEditSerie].m_pData[nXIndex].fYVal = GetYAxis(m_Data[nEditSerie].GetYAxis()).GetValueForPos (m_CurrentPoint.y);
m_fCurrentEditValue = m_Data[nEditSerie].m_pData[nXIndex].fYVal;
m_bDataPointMoving = true;
Invalidate();
}
if (!bHasNotified)
for (i = 0; i < m_SelectByMarker.size(); i++)
{
bool bSelected = m_SelectByMarker[i].markerRect.PtInRect (m_CurrentPoint);
if (bCheckFocusOnly && bSelected)
return true;
m_SelectByMarker[i].pObject->m_bSelected = bSelected;
if (bSelected)
{
bHasNotified = true;
#ifndef _WIN32_WCE
if (bEditAction && m_bInteraction)
{
CXGraphDataSerie& serie = m_Data[i];
m_nSelectedSerie = i;
CChartPage dlg;
dlg.m_pGraph = this;
dlg.m_pGraphDataSerie = &serie;
dlg.DoModal();
Invalidate();
}
#endif
break;
}
}
#ifndef _WIN32_WCE
if (!bHasNotified && bEditAction && m_bInteraction)
{
::PostMessage(GetParent()->m_hWnd, XG_GRAPHDBLCLICK, 0, (long) this);
CChartPage dlg;
dlg.m_pGraph = this;
dlg.DoModal();
Invalidate();
}
#endif
return false;
}
void CXGraph::InsertDataNotation(int nCurve, int nIndex)
{
CString cText, cXFmt, cYFmt, cFmt;
bool bXDT = m_XAxis[m_Data[nCurve].m_nXAxis].m_bDateTime;
bool bYDT = m_YAxis[m_Data[nCurve].m_nYAxis].m_bDateTime;
cYFmt = cXFmt = "%s";
cYFmt = "%s";
cFmt = "[%d] : " + cXFmt + "%s," + cYFmt + "%s";
if (bXDT)
#ifndef _WIN32_WCE
cXFmt = COleDateTime(m_Data[nCurve].m_pData[nIndex].fXVal).Format(m_XAxis[m_Data[nCurve].m_nXAxis].m_cDisplayFmt);
#else
cXFmt = COleDateTime(m_Data[nCurve].m_pData[nIndex].fXVal).Format();
#endif
else
cXFmt.Format(m_XAxis[m_Data[nCurve].m_nXAxis].m_cDisplayFmt, m_Data[nCurve].m_pData[nIndex].fXVal);
if (bYDT)
#ifndef _WIN32_WCE
cYFmt = COleDateTime(m_Data[nCurve].m_pData[nIndex].fYVal).Format(m_YAxis[m_Data[nCurve].m_nYAxis].m_cDisplayFmt);
#else
cYFmt = COleDateTime(m_Data[nCurve].m_pData[nIndex].fYVal).Format();
#endif
else
cYFmt.Format(m_YAxis[m_Data[nCurve].m_nYAxis].m_cDisplayFmt, m_Data[nCurve].m_pData[nIndex].fYVal);
cText.Format(cFmt, nIndex + 1, cXFmt, m_XAxis[m_Data[nCurve].m_nXAxis].m_cLabel, cYFmt, m_YAxis[m_Data[nCurve].m_nYAxis].m_cLabel);
CXGraphDataNotation *pNotation = (CXGraphDataNotation*) new CXGraphDataNotation;
pNotation->m_fXVal = m_Data[nCurve].m_pData[nIndex].fXVal;
pNotation->m_fYVal = m_Data[nCurve].m_pData[nIndex].fYVal;
pNotation->m_cText = cText;
pNotation->m_nCurve = nCurve;
pNotation->m_nIndex = nIndex;
pNotation->m_pGraph = this;
m_Objects.AddTail (pNotation);
Invalidate();
}
void CXGraph::OnLButtonUp(UINT nFlags, CPoint point)
{
if (!m_bLButtonDown)
return;
ReleaseCapture();
m_OldPoint = CPoint(0,0);
m_MouseUpPoint = point;
m_bLButtonDown = false;
if (m_opOperation == opMeasure)
{
AdjustPointToData(point);
m_Measures.push_back(m_MeasureDef);
}
if (m_opOperation == opCursor)
{
if (!CheckObjectSelection() && m_nSnappedCurve != -1)
{
long nIndex;
m_XAxis[m_Data[m_nSnappedCurve].m_nXAxis].GetIndexByXVal(nIndex, m_fSnappedXVal, m_nSnappedCurve);
InsertDataNotation(m_nSnappedCurve, nIndex);
}
}
if (m_opOperation == opZoom)
DoZoom();
if (m_opOperation == opNone || m_opOperation == opEditCurve)
CheckObjectSelection();
Invalidate(TRUE);
CWnd::OnLButtonUp(nFlags, point);
}
void CXGraph::OnLButtonDown(UINT nFlags, CPoint point)
{
SetFocus();
SetCapture();
m_MouseDownPoint = point;
if (m_opOperation == opMeasure)
AdjustPointToData(point);
m_MouseDownPoint = point;
m_bLButtonDown = true;
m_pCurrentObject = NULL;
// Check objects
for (POSITION pos = m_Objects.GetHeadPosition (); pos != NULL; )
{
CXGraphObject *pObject = (CXGraphObject*) m_Objects.GetNext (pos);
if (pObject->m_clRect.PtInRect(point))
m_pCurrentObject = pObject;
if (pObject->m_bSizing && pObject->m_Tracker.HitTest(point) != CRectTracker::hitNothing)
{
ReleaseCapture();
if (pObject->m_Tracker.Track(this, point) && pObject->m_bCanMove && pObject->m_bCanResize)
{
pObject->m_clRect = pObject->m_Tracker.m_rect;
Invalidate(FALSE);
}
}
}
CWnd::OnLButtonDown(nFlags, point);
}
BOOL CXGraph::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CXGraph::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if (m_opOperation == opNone)
{
m_pTracker = NULL;
CheckObjectSelection(true);
}
CWnd::OnLButtonDblClk(nFlags, point);
}
BOOL CXGraph::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_pTracker && m_pTracker->SetCursor(this, nHitTest))
return TRUE;
if (m_opOperation == opPan)
{
HCURSOR hCur = AfxGetApp()->LoadStandardCursor(IDC_SIZEALL);
if (hCur)
{
::SetCursor(hCur);
return TRUE;
}
}
else
if (m_opOperation == opZoom || m_opOperation == opCursor)
{
HCURSOR hCur = AfxGetApp()->LoadStandardCursor(IDC_CROSS);
if (hCur)
{
::SetCursor(hCur);
return TRUE;
}
}
else
if (m_bObjectSelected && m_opOperation == opNone)
{
HCURSOR hCur = AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649));
if (hCur)
{
::SetCursor(hCur);
return TRUE;
}
}
else
if (m_opOperation == opEditCurve && m_nSelectedSerie != -1)
{
HCURSOR hCur = AfxGetApp()->LoadStandardCursor(IDC_SIZENS);
if (hCur)
{
::SetCursor(hCur);
return TRUE;
}
}
return CWnd::OnSetCursor(pWnd, nHitTest, message);
}
BOOL CXGraph::PreTranslateMessage(MSG* pMsg)
{
if ((pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) && pMsg->wParam == VK_DELETE)
{
if (m_pCurrentObject && m_pCurrentObject->m_bSizing)
{
if (m_Objects.GetHead() != m_pCurrentObject)
{
m_Objects.RemoveAt(m_Objects.Find(m_pCurrentObject));
delete m_pCurrentObject;
m_pCurrentObject = NULL;
m_pTracker = NULL;
Invalidate();
}
}
}
return CWnd::PreTranslateMessage(pMsg);
}
#ifndef _WIN32_WCE
void CXGraph::OnRButtonUp(UINT nFlags, CPoint point)
{
CheckObjectSelection();
m_bRButtonDown = false;
if (m_opOperation == opCursor)
{
m_oldCursorPoint = CPoint(-1,-1);
Invalidate();
}
if (m_pCurrentObject && m_pCurrentObject->m_clRect.PtInRect (point))
m_pCurrentObject->InvokeProperties();
else
::PostMessage(GetParent()->m_hWnd, XG_RBUTTONUP, 0, (long) this);
CWnd::OnRButtonUp(nFlags, point);
}
#endif
void CXGraph::InsertEmptyLabel()
{
InsertLabel();
Invalidate();
}
void CXGraph::OnProperties()
{
AFX_MANAGE_STATE(AfxGetModuleState( ));
CheckObjectSelection(true);
}
#ifndef _WIN32_WCE
void CXGraph::OnPrint()
{
AFX_MANAGE_STATE(AfxGetModuleState());
CPrintDialog dlg(FALSE);
if (dlg.DoModal () == IDOK)
{
CDCEx dc;
dc.Attach (dlg.GetPrinterDC ());
dc.Prepare (dc.m_hAttribDC);
int nWidth = dc.GetDeviceCaps (HORZRES);
int nHeight = dc.GetDeviceCaps (VERTRES);
m_clPrintRect.SetRect(0, 0, nWidth / dc.m_fScaleX, nHeight / dc.m_fScaleY);
m_pPrintDC = &dc;
m_pPrintDC->m_bPrinting = true;
m_pPrintDC->StartDoc ("Graph");
m_pPrintDC->StartPage ();
OnPaint();
m_pPrintDC->EndPage ();
m_pPrintDC->EndDoc ();
m_pPrintDC = NULL;
dc.Detach ();
}
//Invalidate();
}
void CXGraph::PrintGraph(CDC *pDC)
{
CDCEx dc;
dc.Attach (pDC->m_hDC);
dc.Prepare (pDC->m_hAttribDC);
int nWidth, nHeight;
if (pDC->m_hDC == pDC->m_hAttribDC)
{
m_pPrintDC = &dc;
nWidth = pDC->GetDeviceCaps (HORZRES);
nHeight = pDC->GetDeviceCaps (VERTRES);
dc.m_bPrintPreview = false;
dc.m_bPrinting = true;
DOCINFO docinfo;
memset(&docinfo, 0, sizeof(docinfo));
docinfo.cbSize = sizeof(docinfo);
docinfo.lpszDocName = _T("Graph");
int nRet;//= dc.StartDoc(&docinfo);
nRet = GetLastError();
nRet = dc.StartPage();
m_clPrintRect.SetRect(0, 0, nWidth / dc.m_fScaleX, nHeight / dc.m_fScaleY);
OnPaint();
dc.EndPage ();
dc.EndDoc ();
m_pPrintDC = NULL;
}
else
{
nWidth = ::GetDeviceCaps (pDC->m_hAttribDC ,HORZRES);
nHeight = ::GetDeviceCaps (pDC->m_hAttribDC ,VERTRES);
dc.m_bPrintPreview = true;
m_clPrintRect.SetRect(0, 0, nWidth / dc.m_fScaleX, nHeight / dc.m_fScaleY);
m_pPrintDC = &dc;
m_pPrintDC->m_bPrinting = true;
OnPaint();
m_pPrintDC = NULL;
}
}
void CXGraph::PrintGraph(CDC *pDC, CRect printRect)
{
CDCEx dc;
dc.Attach (pDC->m_hDC);
dc.Prepare (pDC->m_hAttribDC);
int nWidth, nHeight;
nWidth = pDC->GetDeviceCaps (HORZRES);
nHeight = pDC->GetDeviceCaps (VERTRES);
if (pDC->m_hDC == pDC->m_hAttribDC)
{
m_pPrintDC = &dc;
dc.m_bPrintPreview = false;
dc.m_bPrinting = true;
DOCINFO docinfo;
memset(&docinfo, 0, sizeof(docinfo));
docinfo.cbSize = sizeof(docinfo);
docinfo.lpszDocName = _T("Graph");
int nRet;//= dc.StartDoc(&docinfo);
nRet = GetLastError();
nRet = dc.StartPage();
m_clPrintRect.SetRect(printRect.left / dc.m_fScaleX, printRect.top / dc.m_fScaleX, printRect.right / dc.m_fScaleX, printRect.bottom / dc.m_fScaleX);
OnPaint();
dc.EndPage ();
dc.EndDoc ();
m_pPrintDC = NULL;
}
else
{
dc.m_bPrintPreview = true;
m_clPrintRect.SetRect(printRect.left / dc.m_fScaleX, printRect.top / dc.m_fScaleX, printRect.right / dc.m_fScaleX, printRect.bottom / dc.m_fScaleX);
m_pPrintDC = &dc;
m_pPrintDC->m_bPrinting = true;
OnPaint();
m_pPrintDC = NULL;
}
}
#endif
void CXGraph::CubicTrend()
{
AddCubicTrend(m_Data[m_nSelectedSerie]);
}
void CXGraph::LinearTrend()
{
AddLinearTrend(m_Data[m_nSelectedSerie]);
}
void CXGraph::AddLinearTrend(CXGraphDataSerie& serie)
{
TDataPoint* pTrend = serie.GetLinearTrend ();
int nCurveCount = GetCurveCount ();
CString cLabel = serie.m_cLabel;
CXGraphDataSerie &ret = SetData (pTrend, serie.m_nCount, nCurveCount, serie.m_nXAxis, serie.m_nYAxis, true);
ret.m_cLabel = cLabel + " linear trend";
delete pTrend;
}
void CXGraph::AddCubicTrend(CXGraphDataSerie& serie)
{
TDataPoint* pTrend = serie.GetCubicTrend ();
int nCurveCount = GetCurveCount ();
CString cLabel = serie.m_cLabel;
CXGraphDataSerie &ret = SetData (pTrend, serie.m_nCount, nCurveCount, serie.m_nXAxis, serie.m_nYAxis, true);
ret.m_cLabel = cLabel + " cubic trend";
delete pTrend;
}
void CXGraph::DrawCursor(CDCEx* pDC)
{
CPenSelector ps(0L, 1, pDC);
long nIndex;
TDataPoint point;
int nOldROP2 = pDC->SetROP2 (R2_NOTXORPEN);
m_nSnappedCurve = -1;
if (m_nForcedSnapCurve != -1)
{
m_nSnappedCurve = m_nForcedSnapCurve;
m_fSnappedXVal = m_XAxis[m_Data[m_nForcedSnapCurve].m_nXAxis].GetValueForPos (m_CurrentPoint.x);
// Find index for this value
m_XAxis[m_Data[m_nForcedSnapCurve].m_nXAxis].GetIndexByXVal(nIndex, m_fSnappedXVal, m_nForcedSnapCurve);
// get yval for index
m_fSnappedYVal = m_Data[m_nForcedSnapCurve].m_pData[nIndex].fYVal;
point.fYVal = m_fSnappedYVal;
m_CurrentPoint.y = m_YAxis[m_Data[m_nSnappedCurve].m_nYAxis].GetPointForValue(&point).y;
}
else
if (m_bSnapCursor)
// Snap cursor to nearest curve
for (int i = 0; i < m_Data.size(); i++)
{
// Get xval for current position
m_fSnappedXVal = m_XAxis[m_Data[i].m_nXAxis].GetValueForPos (m_CurrentPoint.x);
// Find index for this value
m_XAxis[m_Data[i].m_nXAxis].GetIndexByXVal(nIndex, m_fSnappedXVal, i);
// get yval for index
m_fSnappedYVal = m_Data[i].m_pData[nIndex].fYVal;
point.fYVal = m_fSnappedYVal;
// Check if cursor is in snap-range
int y = m_YAxis[m_Data[i].m_nYAxis].GetPointForValue(&point).y;
if (abs(m_CurrentPoint.y - y) < m_nSnapRange)
{
m_nSnappedCurve = i;
m_CurrentPoint.y = y;
break;
}
}
if (m_oldCursorPoint != CPoint(-1,-1))
{
if (m_nCursorFlags & XGC_VERT)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -