?? chart.h
字號:
///////////////////////////////////////////////////////////////////////
//chart.h, Juan Carlos Sanchez
///////////////////////////////////////////////////////////////////////
#if !defined(GRAF_H_10101010)
#define GRAF_H_10101010
// \n | /\\ /\\\n |\\_/ \\ /\\_/ \\ _/\\\n | \\__/ \\__/ \\/\n |___________________________
#define CTLOFFSET 0
#define SCROLL_VALUE 1000.0
#define WM_NEWHORZLIMITS (CTLOFFSET + WM_USER + 701)
#define WM_NEWVERTLIMITS (CTLOFFSET + WM_USER + 702)
#define GS_NOTIFY 0x00000001L
#define LS_HORZAUTO 0x00010000
#define LS_POINT 0x00020000
#ifdef _AFXDLL
#define BEGIN_MESSAGE_MAP_TEMPLATES(thetemplate, theClass, baseClass) \
thetemplate const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() \
{ return &baseClass::messageMap; } \
thetemplate const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
thetemplate AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
{ &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; \
thetemplate AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{ \
#else
#define BEGIN_MESSAGE_MAP_TEMPLATES(thetemplate, theClass, baseClass) \
thetemplate const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
thetemplate AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
{ &baseClass::messageMap, &theClass::_messageEntries[0] }; \
thetemplate AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{ \
#endif //_AFXDLL
#pragma warning (disable: 4786 4788)
#include <afxwin.h>
#include <math.h>
#include <map>
#include <set>
using namespace std;
template<class T >
class CScrollChart: public CWnd
{
public:
int m_nSet;//用于得到子集數目
int XOutput;
UINT uX;
UINT uID;
protected:
typedef map<T, T> MAPDATA;
//
typedef map<UINT,CString> MAPTIME;
typedef struct{
MAPDATA m_mapData;
COLORREF crColor;
int nStyle;
int nWidth;
BOOL bIsVisible;
BOOL bIsAuto;
BOOL bPoints;
T nAutoHorzInc;
//
MAPTIME m_Time;
//
} stuctLine;
typedef map<UINT, stuctLine> MAPLINE;
T m_MaxValue;
T m_MinValue;
T m_pointIni;
T m_MaxHzVal;
T m_MinHzVal;
T m_nHzRange;
MAPLINE m_mapLines;
COLORREF m_ColorBk;
BOOL m_bGrid;
BOOL m_bNorify;
UINT m_nHorzDiv;
UINT m_nVertDiv;
UINT m_nMaxPoints;
set<UINT> m_setLinesID;
public:
//這里相當于構造函數,在這里進行了初始化賦值
CScrollChart(): CWnd(), m_pointIni(0,0), m_nHorzDiv(7), m_nVertDiv(14), m_nMaxPoints(0),
m_mapLines(), m_setLinesID(), m_MaxHzVal(1000), m_nHzRange(1000), m_MinHzVal(0)
/*自定義的一組變量*/,m_nSet(0),XOutput(0)/*自定義的一組變量*/{}
//函數聲明
BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
BOOL AddLine(UINT nID, COLORREF crColor, DWORD nStyle = PS_SOLID,
int nWidth = 1,BOOL bVisible = TRUE, int nAutoInc = 10);
BOOL AddData(UINT nID, T nX, T nY, BOOL bDraw = TRUE);
BOOL AddData(UINT nID, T nY, BOOL bDraw = TRUE);
COLORREF SetBkColor(COLORREF cr );
COLORREF GetBkColor() const;
COLORREF SetLineColor(UINT nID, COLORREF cr );
COLORREF GetLineColor(UINT nID);
void ShowLine(UINT nID, BOOL value = TRUE, BOOL bDraw = TRUE);
void ShowPoints(UINT nID, BOOL value = TRUE, BOOL bDraw = TRUE);
void SetGrid(BOOL value = TRUE);
T SetHorzRange(T nRange);
T SetAutoinc(UINT nID, T nInc);
UINT SetHorzDiv(UINT nDiv, BOOL bDraw = TRUE);
UINT GetHorzDiv() const {return m_nHorzDiv;}
UINT SetVertDiv(UINT nDiv, BOOL bDraw = TRUE);
UINT GetVertDiv() const {return m_nVertDiv;}
UINT SetMaxPoints(UINT nValue);
UINT GetMaxPoints() const { return m_nMaxPoints;}
int SetLineStyle(UINT nID, int nStile, BOOL bDraw = TRUE);
int GetLineStyle(UINT nID);
int SetLineWidth(UINT nID, int nWidth, BOOL bDraw = TRUE);
int GetLineWidth(UINT nID);
//Add a function to get system time
CString GetCurrentTime();
//Rong.LL 07-6-11 add double click mouse left event
protected:
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);//鼠標的雙擊事件
protected:
afx_msg void OnPaint();
afx_msg void OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar );
CPoint LPtoDP(T X, T Y);
CPoint LPtoDP(pair<T, T> pnt) {return LPtoDP(pnt.first, pnt.second);}
BOOL bIsFirstPoint();
void UpdateScrollInfo();
void SendNewLimits();
void Normalize();
BOOL ErasePoints();
DECLARE_MESSAGE_MAP()
};
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP_TEMPLATES(template<class T>, CScrollChart<T> , CWnd)
//{{AFX_MSG_MAP(CTestView)
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG_MAP
ON_WM_PAINT()
ON_WM_HSCROLL()
END_MESSAGE_MAP()
template<class T>
void CScrollChart<T>::OnPaint( )
{
//畫出繪制曲線圖的網格和區域
CRect RectClient;//用于存放客戶區
CPen *penLine;
CPen *oldPen;
CPaintDC lop(this);
GetClientRect(RectClient);
CDC PaintDc;
CBitmap bitm;
PaintDc.CreateCompatibleDC(&lop);
bitm.CreateCompatibleBitmap(&lop, RectClient.Width(), RectClient.Height());//創建位圖
CBitmap* pOldBitmap = PaintDc.SelectObject (&bitm);
PaintDc.SetBkMode(OPAQUE);//設置背景模式為SetBKColor()或者透明
PaintDc.SetBkColor(m_ColorBk);//設置背景顏色
PaintDc.SetViewportOrg(0, 0);
CBrush bursh(m_ColorBk);
PaintDc.FillRect(RectClient, &bursh);
if (m_bGrid)
{
//在此處加上Y軸坐標軸///////////////////////////////
CPen *pY;
pY = new CPen(PS_SOLID, 1, RGB(255,255,255 ));
PaintDc.SelectObject(pY);
PaintDc.Rectangle((m_nHzRange / m_nHorzDiv)*0.6,0,(m_nHzRange / m_nHorzDiv)*0.5\
,RectClient.Height() / m_nVertDiv*12);//畫出X軸
//PaintDc.MoveTo((m_nHzRange / m_nHorzDiv)*0.6,0);
//PaintDc.LineTo((m_nHzRange / m_nHorzDiv)*0.6,RectClient.Height() / m_nVertDiv*12);
//PaintDc.MoveTo((m_nHzRange / m_nHorzDiv)*0.6,0);//畫箭頭
//PaintDc.LineTo((m_nHzRange / m_nHorzDiv)*0.5,5);
//PaintDc.MoveTo((m_nHzRange / m_nHorzDiv)*0.6,0);
//PaintDc.LineTo((m_nHzRange / m_nHorzDiv)*0.7,5);
//X軸刻度
PaintDc.SetTextColor(RGB(255,255,255));
PaintDc.TextOut(0,0,"120");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*1,"220");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*2,"200");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*3,"180");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*4,"160");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*5,"140");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*6,"120");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*7,"100");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*8,"80");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*9,"60");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*10,"40");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*11,"20");
PaintDc.TextOut(0,RectClient.Height() / m_nVertDiv*11.5,"0");
///////////////////////////////////////////////////////
penLine = new CPen(PS_SOLID, 1, RGB(0, 128, 0));
oldPen = PaintDc.SelectObject(penLine);
if (m_nVertDiv > 0)
{
///////////////////////畫出水平的網格線///////////////////
for (int n = RectClient.Height() / m_nVertDiv; n < RectClient.Height ();
n += RectClient.Height() / m_nVertDiv)
{
PaintDc.MoveTo(0, n);
PaintDc.LineTo(RectClient.Width(), n);
}
}
if (m_nHorzDiv > 0)
{
///////////////////////畫出垂直的網格線///////////////////
for (int n = m_pointIni + ((m_nHzRange / m_nHorzDiv) - fmod(m_pointIni,m_nHzRange));
n < m_pointIni + m_nHzRange;
n += (m_nHzRange / m_nHorzDiv))
{
int nInipoint=LPtoDP(n, 0).x;
PaintDc.MoveTo(nInipoint, 0);
PaintDc.LineTo(nInipoint, RectClient.Width ());
}
}
PaintDc.SelectObject(oldPen);
delete(penLine);
} //Grid
if (!m_mapLines.empty())//實際劃線代碼使用了容器 有新數據就加入到尾部 每次畫一定長度的 在滾動條時再通過變量調整
{
MAPLINE::const_iterator iterLine = m_mapLines.begin();
while ((iterLine) != m_mapLines.end())
{
if (!(*iterLine).second.m_mapData.empty())
{
if ((*iterLine).second.bIsVisible)
{
CPoint pointDraw;
CPoint pointOld;
CSize sizePoint( 2+((*iterLine).second.nWidth),
2+((*iterLine).second.nWidth) );
CBrush brushPoint;
brushPoint.CreateSolidBrush((*iterLine).second.crColor);
penLine = new CPen((*iterLine).second.nStyle,
(*iterLine).second.nWidth,
(*iterLine).second.crColor);
oldPen = PaintDc.SelectObject(penLine);
CBrush* oldBrush = PaintDc.SelectObject(&brushPoint);
MAPDATA::const_iterator iter = (*iterLine).second.m_mapData.lower_bound(m_pointIni);
if (iter != (*iterLine).second.m_mapData.begin()) --iter;
pointDraw = LPtoDP((*iter));
PaintDc.MoveTo(pointDraw);
///////////////////////////////// TEST /////////////////////////////////////////////
//在變量定義部分定義了一個map容器用于存放對應數據點的時間 在此處定義此map的迭代器
//并將其取值范圍限定在一個窗口范圍內 當滾動滾動條的時候再相應改變
MAPTIME::const_iterator iterTime = (*iterLine).second.m_Time.lower_bound(m_pointIni);
PaintDc.TextOut(pointDraw.x,531,(*iterTime).second);//輸出時間
iterTime++;
///////////////////////////////// TEST /////////////////////////////////////////////
pointOld = pointDraw;
iter++;
while ( (iter != (*iterLine).second.m_mapData.upper_bound(m_nHzRange + m_pointIni))
&& (iter != (*iterLine).second.m_mapData.end())
&& (iterTime != (*iterLine).second.m_Time.upper_bound(m_nHzRange + m_pointIni)))
{
pointDraw = LPtoDP((*iter));
PaintDc.LineTo(pointDraw);//畫線完成
///////////////////////////////////////////////////////
PaintDc.TextOut(pointDraw.x,531,(*iterTime).second);
iterTime++;
///////////////////////////////////////////////////////
if ((*iterLine).second.bPoints)
PaintDc.Ellipse(CRect( pointOld - sizePoint,
pointOld + sizePoint) );
pointOld = pointDraw;
++iter;
}
if ((*iterLine).second.bPoints)
PaintDc.Ellipse(CRect( pointOld - sizePoint,
pointOld + sizePoint) );
if (iter != (*iterLine).second.m_mapData.end())
{
pointOld=LPtoDP(*iter);
PaintDc.LineTo(pointOld);
if ((*iterLine).second.bPoints)
PaintDc.Ellipse( CRect( pointOld - sizePoint,
pointOld + sizePoint) );
}
PaintDc.SelectObject(oldPen);
PaintDc.SelectObject(oldBrush);
delete(penLine);
}
}
iterLine++;
}
} // not empty
lop.BitBlt(0,0,RectClient.Width(), RectClient.Height(), &PaintDc, 0, 0, SRCCOPY);
PaintDc.SelectObject(pOldBitmap);
}
template<class T>
BOOL CScrollChart<T>::AddData(UINT nID, T nY, BOOL bDraw)
{
if ( (m_setLinesID.find(nID) == m_setLinesID.end()) || (!(m_mapLines[nID].bIsAuto)) )
return FALSE;
if (m_mapLines[nID].m_mapData.empty())
return AddData(nID, 0, nY, bDraw);
return AddData(nID,
(*(--m_mapLines[nID].m_mapData.end())).first + m_mapLines[nID].nAutoHorzInc,
nY, bDraw);
}
template<class T>
BOOL CScrollChart<T>::AddData(UINT nID, T nX, T nY, BOOL bDraw)
{
if (m_setLinesID.find(nID) == m_setLinesID.end())
return FALSE;
BOOL bScrollModi = FALSE;
if (bIsFirstPoint())
{
m_MaxValue = 200;//在這里控制坐標的最大值和最小值,默認是nY
m_MinValue = 0;
SendNewLimits();
}
else
{
if (!m_mapLines[nID].m_mapData.empty())
{
if ( ((*(--(m_mapLines[nID].m_mapData.end()))).first >= m_pointIni) &&
((*(--(m_mapLines[nID].m_mapData.end()))).first <= m_pointIni + m_nHzRange) &&
(nX > m_pointIni + m_nHzRange * .9) )
{
//Move init
m_pointIni = nX - (m_nHzRange * .9);
bScrollModi = TRUE;
}
}
if ( (!bScrollModi) && (nX > m_MaxHzVal) && (nX>m_nHzRange) )
{
//right-out
m_MaxHzVal = nX + m_nHzRange * .1;
bScrollModi = TRUE;
}
if ( (!bScrollModi) && (nX < m_MinHzVal) )
{
//left
m_MinHzVal = nX;
bScrollModi = TRUE;
}
if (nY > m_MaxValue)
{
m_MaxValue = nY;
SendNewLimits();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -