📄 xgraphaxis.cpp
字号:
// XGraphAxis.cpp: Implementierung der Klasse CXGraphAxis.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Afxwin.h"
#include "XGraphAxis.h"
#include "XGraph.h"
#include "GfxUtils.h"
#include "Math.h"
#include "float.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#pragma warning (disable : 4244)
#pragma warning (disable : 4800)
double CXGraphAxis::TimeStepTable[] = { 0, 1, 2, 5, 10, 15, 20, 30, 60,
2*60, 5*60, 10*60, 15*60, 30*60, 3600,
2*3600, 4*3600, 8*3600, 10*3600, 12*3600, 24*3600,
2*24*3600, 4*24*3600, 7*24*3600,
2*7*24*3600, 4*7*24*3600, 8*7*24*3600, 12*7*24*3600,
26*7*24*3600, 52*7*24*3600,
2*52*7*24*3600, 5*52*7*24*3600, 10*52*7*24*3600,
20*52*7*24*3600, 50*52*7*24*3600, -1} ;
IMPLEMENT_SERIAL( CXGraphAxis, CXGraphObject, 1 )
//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////
CXGraphAxis::CXGraphAxis()
{
m_AxisType = atLinear;
m_Placement = apAutomatic;
m_bAutoScale = true;
m_bShowMarker = true;
m_bVisible = true;
m_bShowGrid = true;
m_bDateTime = false;
m_cLabel = _T(" ");
m_cDisplayFmt = _T("%5.1f");
m_fMax = -DBL_MAX;
m_fMin = DBL_MAX;
m_fCurMin = DBL_MAX;
m_fCurMax = -DBL_MAX;
m_fStep = 0.1;
m_fRange = 1.0;
m_nRange = 1;
m_pGraph = NULL;
m_nArcSize = 5;
m_nTickSize = 5;
m_crColor = 0L;
m_crGridColor = RGB(150,150,150);
#ifndef _WIN32_WCE
m_nGridStyle = PS_DOT;
#else
m_nGridStyle = PS_SOLID;
#endif
m_fSpareRange = 0;
m_fMarkerSpareSize = 0;
m_nMarkerSize = 10;
SetFont(_T("Arial"), 13, FW_NORMAL);
SetTitleFont(_T("Arial"), 14, FW_BOLD);
}
CXGraphAxis::CXGraphAxis(const CXGraphAxis& copy)
{
*this = copy;
}
CXGraphAxis& CXGraphAxis::operator = (const CXGraphAxis& copy)
{
m_bAutoScale = copy.m_bAutoScale;
m_bVisible = copy.m_bVisible;
m_bShowGrid = copy.m_bShowGrid;
m_cDisplayFmt = copy.m_cDisplayFmt;
m_cLabel = copy.m_cLabel;
m_fMax = copy.m_fMax;
m_fMin = copy.m_fMin;
m_fCurMax = copy.m_fCurMax;
m_fCurMin = copy.m_fCurMin;
m_fStep = copy.m_fStep;
m_nTop = copy.m_nTop;
m_nLeft = copy.m_nLeft;
m_AxisKind = copy.m_AxisKind;
m_nArcSize = copy.m_nArcSize;
m_nTickSize = copy.m_nTickSize;
m_pGraph = copy.m_pGraph;
m_crColor = copy.m_crColor;
m_crGridColor = copy.m_crGridColor;
m_nGridStyle = copy.m_nGridStyle;
m_fSpareRange = copy.m_fSpareRange;
m_bDateTime = copy.m_bDateTime;
m_fMarkerSpareSize = copy.m_fMarkerSpareSize;
m_fRange = copy.m_fRange;
m_nRange = copy.m_nRange;
m_nMarkerSize = copy.m_nMarkerSize;
m_Placement = copy.m_Placement;
m_AxisType = copy.m_AxisType;
m_bShowMarker = copy.m_bShowMarker;
m_ColorRanges = copy.m_ColorRanges;
m_ZoomHistory = copy.m_ZoomHistory;
m_AxisMarkers = copy.m_AxisMarkers;
LOGFONT font;
if (m_TitleFont.m_hObject != NULL)
m_TitleFont.DeleteObject ();
if (m_Font.m_hObject != NULL)
m_Font.DeleteObject ();
((CFont&)copy.m_Font).GetLogFont (&font);
m_Font.CreateFontIndirect (&font);
((CFont&)copy.m_TitleFont).GetLogFont (&font);
m_TitleFont.CreateFontIndirect (&font);
return *this;
}
CXGraphAxis::~CXGraphAxis()
{
if (m_Font.m_hObject != NULL)
m_Font.DeleteObject ();
if (m_TitleFont.m_hObject != NULL)
m_TitleFont.DeleteObject ();
}
void CXGraphAxis::DeleteColorRange(int nRange)
{
if (nRange < m_ColorRanges.size())
m_ColorRanges.erase (&m_ColorRanges[nRange]);
}
void CXGraphAxis::DeleteAllColorRanges()
{
m_ColorRanges.clear ();
}
void CXGraphAxis::SetAxisMarker(int nMarker, double fValue, COLORREF crColor, UINT nStyle)
{
ASSERT(nMarker <= m_AxisMarkers.size());
AXISMARKER marker;
marker.bVisible = true;
marker.crColor = crColor;
marker.fValue = fValue;
marker.nStyle = nStyle;
marker.nSize = 1;
marker.bShowValue = true;
//CFont* font = CFont::FromHandle ((HFONT)::GetStockObject(SYSTEM_FONT));
m_Font.GetLogFont(&marker.lfFont);
if (m_AxisKind == xAxis)
{
marker.lfFont.lfEscapement = 900;
marker.lfFont.lfOrientation = 900;
marker.lfFont.lfClipPrecision = CLIP_LH_ANGLES;
}
if (nMarker == m_AxisMarkers.size())
m_AxisMarkers.push_back (marker);
else
m_AxisMarkers[nMarker] = marker;
m_pGraph->Invalidate();
}
void CXGraphAxis::DeleteAxisMarker(int nMarker)
{
if (nMarker < m_AxisMarkers.size())
m_AxisMarkers.erase (&m_AxisMarkers[nMarker]);
}
AXISMARKER& CXGraphAxis::GetAxisMarker(int nMarker)
{
ASSERT(nMarker < m_AxisMarkers.size());
return m_AxisMarkers[nMarker];
}
void CXGraphAxis::SetColorRange(int nRange, double fMin, double fMax, COLORREF crMinColor, COLORREF crMaxColor, CString cLabel, UINT nStyle)
{
ASSERT(nRange <= m_ColorRanges.size());
COLORRANGE range;
range.fMin = fMin;
range.fMax = fMax;
range.crMinColor = crMinColor;
range.crMaxColor = crMaxColor;
range.nStyle = nStyle;
#ifndef _WIN32_WCE
_tcscpy(range.szLabel, cLabel);
#else
strcpy(range.szLabel, (const char*)(LPCTSTR)cLabel);
#endif
if (nRange == m_ColorRanges.size())
m_ColorRanges.push_back (range);
else
m_ColorRanges[nRange] = range;
m_pGraph->Invalidate ();
}
void CXGraphAxis::SetTitleFont (LPLOGFONT pLogFont)
{
if (m_TitleFont.m_hObject != NULL)
m_TitleFont.DeleteObject ();
m_TitleFont.CreateFontIndirect (pLogFont);
}
void CXGraphAxis::SetFont (LPLOGFONT pLogFont)
{
if (m_Font.m_hObject != NULL)
m_Font.DeleteObject ();
m_Font.CreateFontIndirect (pLogFont);
}
void CXGraphAxis::SetFont (CString cFontName, int nFontHeight, int nFontStyle)
{
if (m_Font.m_hObject != NULL)
m_Font.DeleteObject ();
m_Font.CreateFont(nFontHeight, 0, 0, 0, nFontStyle, 0, 0, 0, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_CHARACTER_PRECIS, ANTIALIASED_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, cFontName);
}
void CXGraphAxis::SetTitleFont (CString cFontName, int nFontHeight, int nFontStyle)
{
if (m_TitleFont.m_hObject != NULL)
m_TitleFont.DeleteObject ();
m_TitleFont.CreateFont(nFontHeight, 0, 0, 0, nFontStyle, 0, 0, 0, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_CHARACTER_PRECIS, ANTIALIASED_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, cFontName);
}
int CXGraphAxis::GetMaxLabelWidth(CDCEx *pDC)
{
CFontSelector fs(&m_Font, pDC, false);
int nMinWidth, nMaxWidth;
CString cTxt;
if (!m_bDateTime)
{
cTxt.Format (m_cDisplayFmt, m_fCurMin);
nMinWidth = GetTextExtentEx (pDC, cTxt).cx;
cTxt.Format (m_cDisplayFmt, m_fCurMax);
nMaxWidth = GetTextExtentEx (pDC, cTxt).cx;
}
else
{
#ifndef _WIN32_WCE
cTxt = COleDateTime(m_fCurMin).Format (m_cDisplayFmt);
nMinWidth = GetTextExtentEx (pDC, cTxt).cx;
cTxt = COleDateTime(m_fCurMax).Format (m_cDisplayFmt);
nMaxWidth = GetTextExtentEx (pDC, cTxt).cx;
#else
cTxt = COleDateTime(m_fCurMin).Format ();
nMinWidth = GetTextExtentEx (pDC, cTxt).cx;
cTxt = COleDateTime(m_fCurMax).Format ();
nMaxWidth = GetTextExtentEx (pDC, cTxt).cx;
#endif
}
return max(nMinWidth + m_nTickSize, nMaxWidth + m_nTickSize);
}
int CXGraphAxis::GetMaxLabelHeight(CDCEx *pDC)
{
CFontSelector fs(&m_Font, pDC, false);
int nHeight;
CString cTxt;
if (!m_bDateTime)
cTxt.Format (m_cDisplayFmt, m_fMin);
else
#ifndef _WIN32_WCE
cTxt = COleDateTime(m_fMin).Format (m_cDisplayFmt);
#else
cTxt = COleDateTime(m_fMin).Format ();
#endif
nHeight = GetTextExtentEx (pDC, cTxt).cy;
return nHeight + m_nTickSize;
}
CSize CXGraphAxis::GetTitleSize(CDCEx *pDC)
{
CFontSelector fs(&m_TitleFont, pDC, false);
return GetTextExtentEx (pDC, m_cLabel);
}
void CXGraphAxis::DrawMarker(CDCEx *pDC, CPoint point, int nMarker, int nSize, COLORREF crColor, bool bSymbol)
{
if (bSymbol)
{
m_pGraph->m_pDrawFn[nMarker](point, nSize, crColor, false, pDC);
return;
}
CRect clMarker(point.x, point.y, point.x + nSize, point.y + nSize);
if (pDC->m_bMono)
pDC->FillSolidRect(clMarker, 0L);
else
pDC->FillSolidRect(clMarker, crColor);
CQuickFont font(_T("Arial"), nSize, FW_THIN);
CFontSelector fs(&font, pDC);
CString cMarker;
cMarker.Format(_T("%d"), nMarker + 1);
COLORREF crText;
if (!pDC->m_bMono)
{
int nLuminance = max (GetRValue(crColor), GetGValue(crColor));
nLuminance = max(nLuminance, GetBValue(crColor) / 2);
if (nLuminance > 128)
crText = 0L;
else
crText = RGB(0xff,0xff,0xff);
}
else
crText = RGB(255,255,255);
COLORREF crOldText = pDC->GetTextColor();
pDC->SetTextColor (crText);
pDC->DrawText(cMarker, clMarker, DT_CENTER);
pDC->SetTextColor (crOldText);
}
void CXGraphAxis::DrawArc(CDCEx *pDC, CPoint point, EDirection direction, int nSize)
{
switch (direction)
{
case up :
{
int x = 0;
for (int y = point.y; y < (point.y + nSize); y++, x++)
{
pDC->MoveTo(point.x - x, y);
pDC->LineTo(point.x + x, y);
}
break;
}
case down :
{
int x = nSize;
for (int y = point.y; y < (point.y + nSize); y++, x--)
{
pDC->MoveTo(point.x - x, y);
pDC->LineTo(point.x + x, y);
}
break;
}
case left :
{
int y = 0;
for (int x = point.x; x < (point.x + nSize); x++, y++)
{
pDC->MoveTo(x,point.y - y);
pDC->LineTo(x,point.y + y);
}
break;
}
case right :
{
int y = nSize;
for (int x = (point.x - nSize); x < point.x; x++, y--)
{
pDC->MoveTo(x,point.y - y);
pDC->LineTo(x,point.y + y);
}
break;
}
}
}
int CXGraphAxis::DrawCurveMarkers(CDCEx *pDC, bool bDraw)
{
if (!m_bShowMarker)
return 0;
if (m_AxisKind == yAxis)
{
int nHeight = 0;
int nWidth = 0;
int nMarker = 0;
for (int i = 0; i < m_pGraph->m_Data.size(); i++)
{
CXGraphDataSerie& serie = m_pGraph->m_Data[i];
if (serie.m_bVisible && serie.m_nYAxis == m_pGraph->GetAxisIndex(this))
{
CPoint point;
if (m_Placement == apRight)
point = CPoint(m_nLeft - m_nMarkerSize / 2 + nWidth, m_clChart.top + nHeight);
else
point = CPoint(m_nLeft - m_nMarkerSize / 2 - nWidth, m_clChart.top + nHeight);
if (bDraw)
DrawMarker(pDC, point, serie.m_nMarkerType == 0 ? i : serie.m_nMarker, m_nMarkerSize, serie.m_crColor, serie.m_nMarkerType == 1);
nMarker++;
if (!(nMarker % 3))
{
nHeight += m_nMarkerSize;
nWidth = 0;
}
else
nWidth += m_nMarkerSize;
}
}
if ((nMarker % 3))
nHeight += m_nMarkerSize;
return nHeight;
}
else
{
int nWidth = m_nMarkerSize;
int nHeight = 0;
int nMarker = 0;
for (int i = 0; i < m_pGraph->m_Data.size(); i++)
{
CXGraphDataSerie& serie = m_pGraph->m_Data[i];
if (serie.m_bVisible && serie.m_nXAxis == m_pGraph->GetAxisIndex(this))
{
CPoint point (m_pGraph->m_clInnerRect.right - nWidth, m_nTop - m_nMarkerSize / 2 + nHeight);
if (bDraw)
DrawMarker(pDC, point, serie.m_nMarkerType == 0 ? i : serie.m_nMarker, m_nMarkerSize, serie.m_crColor, serie.m_nMarkerType == 1);
nMarker++;
if (!(nMarker % 2))
{
nWidth += m_nMarkerSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -