📄 scatter.h
字号:
#if !defined(__SCATTER_H__)
#define __SCATTER_H__
#include "graphics.h"
//////////////////////////////////////////////////////////////////////////////////
////// struct CTPoint
template <class T>
struct CTPoint
{
T x;
T y;
CTPoint() { x = 0; y = 0; }
CTPoint(T initX, T initY) { x = initX; y = initY; }
void operator = (const CTPoint& pt) { x = pt.x; y = pt.y; }
};
//////////////////////////////////////////////////////////////////////////////////
////// class CLinear
template <class T>
class CLinear : public CGraphics
{
public:
virtual bool SetRange(double xmin, double ymin, double xmax, double ymax);
virtual POINT GetPoint(T x, T y);
virtual void GetValue(POINT& pt, T& x, T& y);
void Lines(T* x, T* y, int n, COLORREF cr, int Index = 0, const char* Name = NULL, int LineWidth = 0, int LineStyle = PS_SOLID);
void Markers(T* x, T* y, int n, COLORREF cr, int mode, int Index = 0, const char* Name = NULL, int size = 6);
void Polygon(T* x, T* y, int n);
void Polygon(CTPoint<T>* pt, int n);
void Lines(CTPoint<T>* pt, int n, COLORREF cr, int Index = 0, const char* Name = NULL, int LineWidth = 0, int LineStyle = PS_SOLID);
void Markers(CTPoint<T>* pt, int n, COLORREF cr, int mode, int Index = 0, const char* Name = NULL, int size = 6);
bool FilledPolygon(CTPoint<T>* pt, int n);
void FilledRectangle(T x1, T y1, T x2, T y2);
bool FilledPolygon(T* x, T* y, int n);
void FilledRectangle(CTPoint<T>&, CTPoint<T>&, COLORREF cr);
bool FilledPolygon(CTPoint<T>*, int n, COLORREF cr);
void FilledRectangle(T x1, T y1, T x2, T y2, COLORREF cr);
bool FilledPolygon(T* x, T* y, int n, COLORREF cr);
void MoveTo(T x, T y) { GetPoint(x, y); ::MoveToEx(m_hDC, m_Pt.x, m_Pt.y, NULL); }
void LineTo(T x, T y) { GetPoint(x, y); ::LineTo(m_hDC, m_Pt.x, m_Pt.y); }
void Line(T x1, T y1, T x2, T y2) { MoveTo(x1, y1); LineTo(x2, y2); }
void Line(CTPoint<T>& pt1, CTPoint<T>& pt2) { Line(pt1.x, pt1.y, pt2.x, pt2.y); }
void Rectangle(T x1, T y1, T x2, T y2) { MoveTo(x1, y1); LineTo(x2, y1); LineTo(x2, y2); LineTo(x1, y2); LineTo(x1, y1); }
void Rectangle(CTPoint<T>& pt1, CTPoint<T>& pt2) { Rectangle(pt1.x, pt1.y, pt2.x, pt2.y); }
void MoveTo(CTPoint<T>& pt) { MoveTo(pt.x, pt.y); }
void LineTo(CTPoint<T>& pt) { LineTo(pt.x, pt.y); }
void Marker(T x, T y, int mode, int size = 6) { GetPoint(x, y); DrawMarker(m_Pt.x, m_Pt.y, mode, size); };
void Marker(CTPoint<T>& pt, int mode, int size = 6) { Marker(pt.x, pt.y, mode, size); }
void FilledRectangle(CTPoint<T>& pt1, CTPoint<T>& pt2) { FilledRectangle(pt1.x, pt1.y, pt2.x, pt2.y); }
POINT GetTPoint(CTPoint<T>& pt) { return GetPoint(pt.x, pt.y); }
CTPoint<T> GetTValue(POINT& pt) { CTPoint<T> t; GetValue(pt, t.x, t.y); return t; }
protected:
void MarkerLegend(COLORREF cr, int Index, const char* Name, int mode, int size);
};
//////////////////////////////////////////////////////////////////////////////////
////// class CXLogYLinear
template <class T>
class CXLogYLinear : public CLinear<T>
{
public:
virtual bool SetRange(double xmin, double ymin, double xmax, double ymax);
virtual void XAxis();
virtual void Grid();
virtual POINT GetPoint(T x, T y);
virtual void GetValue(POINT& pt, T& x, T& y);
};
//////////////////////////////////////////////////////////////////////////////////
////// class CXLiearYLog
template <class T>
class CXLinearYLog : public CLinear<T>
{
public:
virtual bool SetRange(double xmin, double ymin, double xmax, double ymax);
virtual void YAxis();
virtual void Grid();
virtual POINT GetPoint(T x, T y);
virtual void GetValue(POINT& pt, T& x, T& y);
};
//////////////////////////////////////////////////////////////////////////////////
////// class CXLogYLog
template <class T>
class CXLogYLog : public CLinear<T>
{
public:
virtual bool SetRange(double xmin, double ymin, double xmax, double ymax);
virtual void XAxis();
virtual void YAxis();
virtual void Grid();
virtual POINT GetPoint(T x, T y);
virtual void GetValue(POINT& pt, T& x, T& y);
};
///////////////////////////////////////////////////////////////////////////////
// CLinear operations
template<class T>
bool CLinear<T>::SetRange(double xmin, double ymin, double xmax, double ymax)
{
m_nAxesType = XY;
m_Scale.xmin = xmin;
m_Scale.ymin = ymin;
m_Scale.xmax = xmax;
m_Scale.ymax = ymax;
return true;
}
template<class T>
POINT CLinear<T>::GetPoint(T x, T y)
{
m_Pt.x = (LONG)((x - m_Scale.xmin) / m_Scale.dx) + GL;
m_Pt.y = (LONG)(GB - (y - m_Scale.ymin) / m_Scale.dy);
return m_Pt;
}
template<class T>
void CLinear<T>::GetValue(POINT& pt, T& x, T& y)
{
x = (T)(m_Scale.xmin + (pt.x - GL) * m_Scale.dx);
y = (T)(m_Scale.ymin + (GB - pt.y) * m_Scale.dy);
}
template<class T>
void CLinear<T>::MarkerLegend(COLORREF cr, int Index, const char* Name, int mode, int size)
{
m_LogFont.lfHeight = (int)(m_Size.cx / -25.0);
if (m_LogFont.lfHeight > -10)
m_LogFont.lfHeight = -10;
m_LogFont.lfWeight = 500;
m_LogFont.lfOrientation= 0;
m_LogFont.lfEscapement = 0;
m_Font = ::CreateFontIndirect(&m_LogFont);
if (m_Font)
{
int n = (m_Rect.right - GR) / 20 + 1;
int xb = GR + 2 * n;
int xe = xb + 4 * n;
int y = GT - 3 * Index * m_LogFont.lfHeight / 2;
DrawMarker(GR + 4 * n, y, mode, size);
int bm = ::SetBkMode(m_hDC, TRANSPARENT);
HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font);
::SetTextColor(m_hDC, cr);
SetStringAlign(LEFT, CENTER);
PrintString(xe + n, y, 0, Name);
::SelectObject(m_hDC, hOldFont);
::DeleteObject(m_Font);
::SetBkMode(m_hDC, bm);
}
}
template<class T>
void CLinear<T>::Markers(T* x, T* y, int n, COLORREF cr, int mode, int Index, const char* Name, int size)
{
switch(mode)
{
case CROSS:
case XCROSS:
case STAR:
case CIRCLE:
case TRIANGLE:
case DIAMOND:
case SQUARE:
{
HPEN hPen = ::CreatePen(PS_SOLID, 0, cr);
HPEN hOldPen = (HPEN)::SelectObject(m_hDC, hPen);
for(int i = 0; i < n; i ++)
Marker(x[i], y[i], mode, size);
if (m_bEnableLegend && Index > 0 && Name)
MarkerLegend(cr, Index, Name, mode, size);
::SelectObject(m_hDC, hOldPen);
::DeleteObject(hPen);
break;
}
case FCIRCLE:
case FTRIANGLE:
case FDIAMOND:
case FSQUARE:
{
HBRUSH hBrush = ::CreateSolidBrush(cr);
HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush);
for(int i = 0; i < n; i ++)
Marker(x[i], y[i], mode, size);
if (m_bEnableLegend && Index > 0 && Name)
MarkerLegend(cr, Index, Name, mode, size);
::SelectObject(m_hDC, hBrold);
::DeleteObject(hBrush);
break;
}
}
}
template<class T>
void CLinear<T>::Markers(CTPoint<T>* pt, int n, COLORREF cr, int mode, int Index, const char* Name, int size)
{
switch(mode)
{
case CROSS:
case XCROSS:
case STAR:
case CIRCLE:
case TRIANGLE:
case DIAMOND:
case SQUARE:
{
HPEN hPen = ::CreatePen(PS_SOLID, 1, cr);
HPEN hOldPen = (HPEN)::SelectObject(m_hDC, hPen);
for(int i = 0; i < n; i ++)
Marker(pt[i].x, pt[i].y, mode, size);
if (m_bEnableLegend && Index > 0 && Name)
MarkerLegend(cr, Index, Name, mode, size);
::SelectObject(m_hDC, hOldPen);
::DeleteObject(hPen);
break;
}
case FCIRCLE:
case FTRIANGLE:
case FDIAMOND:
case FSQUARE:
{
HBRUSH hBrush = ::CreateSolidBrush(cr);
HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush);
for(int i = 0; i < n; i ++)
Marker(pt[i].x, pt[i].y, mode, size);
if (m_bEnableLegend && Index > 0 && Name)
MarkerLegend(cr, Index, Name, mode, size);
::SelectObject(m_hDC, hBrold);
::DeleteObject(hBrush);
break;
}
}
}
template<class T>
void CLinear<T>::FilledRectangle(CTPoint<T>& pt1, CTPoint<T>& pt2, COLORREF cr)
{
HBRUSH hBrush = ::CreateSolidBrush(cr);
HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush);
FilledRectangle(pt1, pt2);
::SelectObject(m_hDC, hBrold);
::DeleteObject(hBrush);
}
template<class T>
void CLinear<T>::Polygon(CTPoint<T>* pt, int n)
{
MoveTo(pt[0].x, pt[0].y);
for(int i = 1; i < n; i ++)
LineTo(pt[i].x, pt[i].y);
LineTo(pt[0].x, pt[0].y);
}
template<class T>
bool CLinear<T>::FilledPolygon(CTPoint<T>* pt, int n)
{
POINT *p = new POINT[n];
if (!p) return false;
for(int i = 0; i < n; i ++)
p[i] = GetTPoint(pt[i]);
::Polygon(m_hDC, p, n );
delete []p;
return true;
}
template<class T>
bool CLinear<T>::FilledPolygon(CTPoint<T>* pt, int n, COLORREF cr)
{
HBRUSH hBrush = ::CreateSolidBrush(cr);
HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush);
bool bl = FilledPolygon(pt, n);
::SelectObject(m_hDC, hBrold);
::DeleteObject(hBrush);
return bl;
}
template<class T>
void CLinear<T>::Lines(CTPoint<T>* pt, int n, COLORREF cr, int Index, const char* Name, int LineWidth, int LineStyle)
{
if (m_bPrinting) LineWidth *= m_nPrintScale;
HPEN hPen = ::CreatePen(LineStyle, LineWidth, cr);
HPEN hOldPen = (HPEN)::SelectObject(m_hDC, hPen);
MoveTo(pt[0].x, pt[0].y);
for(int i = 1; i < n; i ++)
LineTo(pt[i].x, pt[i].y);
if (m_bEnableLegend && Index > 0 && Name)
Legend(cr, Index, Name);
::SelectObject(m_hDC, hOldPen);
::DeleteObject(hPen);
}
template<class T>
void CLinear<T>::FilledRectangle(T x1, T y1, T x2, T y2)
{
POINT pt1 = GetPoint(x1, y1);
POINT pt2 = GetPoint(x2, y2);
::Rectangle(m_hDC, pt1.x, pt1.y, pt2.x, pt2.y);
}
template<class T>
void CLinear<T>::FilledRectangle(T x1, T y1, T x2, T y2, COLORREF cr)
{
HBRUSH hBrush = ::CreateSolidBrush(cr);
HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush);
FilledRectangle(x1, y1, x2, y2);
::SelectObject(m_hDC, hBrold);
::DeleteObject(hBrush);
}
template<class T>
void CLinear<T>::Polygon(T* x, T* y, int n)
{
MoveTo(x[0], y[0]);
for(int i = 1; i < n; i ++)
LineTo(x[i], y[i]);
LineTo(x[0], y[0]);
}
template<class T>
bool CLinear<T>::FilledPolygon(T* x, T* y, int n)
{
POINT *pt = new POINT[n];
if (!pt) return false;
for(int i = 0; i < n; i ++)
pt[i] = GetPoint(x[i], y[i]);
::Polygon(m_hDC, pt, n );
delete []pt;
return true;
}
template<class T>
bool CLinear<T>::FilledPolygon(T* x, T* y, int n, COLORREF cr)
{
HBRUSH hBrush = ::CreateSolidBrush(cr);
HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush);
bool bl = FilledPolygon(x, y, n);
::SelectObject(m_hDC, hBrold);
::DeleteObject(hBrush);
return bl;
}
template<class T>
void CLinear<T>::Lines(T* x, T* y, int n, COLORREF cr, int Index, const char* Name, int LineWidth, int LineStyle)
{
if (m_bPrinting) LineWidth *= m_nPrintScale;
HPEN hPen = ::CreatePen(LineStyle, LineWidth, cr);
HPEN hOldPen = (HPEN)::SelectObject(m_hDC, hPen);
MoveTo(x[0], y[0]);
for(int i = 1; i < n; i ++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -