📄 xgraphdataserie.cpp
字号:
// XGraphDataSerie.cpp: Implementierung der Klasse CXGraphDataSerie.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XGraphDataSerie.h"
#include "XGraph.h"
#include "GfxUtils.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
IMPLEMENT_SERIAL( CXGraphDataSerie, CXGraphObject, 1 )
//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////
CXGraphDataSerie::CXGraphDataSerie()
{
m_bAutoDelete = false;
m_bVisible = true;
m_bShowMarker = false;
m_bFillBeneath = false;
m_bFillTransparent = true;
m_pGraph = NULL;
m_pData = NULL;
m_nLineStyle = PS_SOLID;
m_nFillStyle = 6;
m_nLineSize = 1;
m_gtType = gtLine;
m_nFirstVisible = 0;
m_nLastVisible = 0;
m_cLabel = _T(" ");
m_nMarkerType = 0;
m_nMarker = 0;
m_nMarkerSize = 10;
m_nXAxis = 0;
m_nYAxis = 0;
m_crColor = 0L;
m_nCount = 0;
m_nIndex = 0;
m_nFillCurve = 1;
m_crFillColor = RGB(255, 255, 255);
}
CXGraphDataSerie::CXGraphDataSerie(const CXGraphDataSerie& copy)
{
m_pData = NULL;
*this = copy;
}
CXGraphDataSerie& CXGraphDataSerie::operator =(const CXGraphDataSerie& copy)
{
m_bVisible = copy.m_bVisible;
m_bShowMarker = copy.m_bShowMarker;
m_bFillBeneath = copy.m_bFillBeneath;
m_pGraph = copy.m_pGraph;
m_nLineStyle = copy.m_nLineStyle;
m_nLineSize = copy.m_nLineSize;
m_gtType = copy.m_gtType;
m_nXAxis = copy.m_nXAxis;
m_nYAxis = copy.m_nYAxis;
m_crColor = copy.m_crColor;
m_nFillStyle = copy.m_nFillStyle;
m_nFirstVisible = copy.m_nFirstVisible;
m_nLastVisible = copy.m_nLastVisible;
m_bFillTransparent = copy.m_bFillTransparent;
m_CurveRegions = copy.m_CurveRegions;
m_nMarkerType = copy.m_nMarkerType;
m_nMarker = copy.m_nMarker;
m_nMarkerSize = copy.m_nMarkerSize;
m_bAutoDelete = copy.m_bAutoDelete;
m_nCount = copy.m_nCount;
m_nIndex = copy.m_nIndex;
m_cLabel = copy.m_cLabel;
m_PS = copy.m_PS;
m_nFillCurve = copy.m_nFillCurve;
m_crFillColor = copy.m_crFillColor;
if (copy.m_bAutoDelete && copy.m_pData)
{
m_pData = new TDataPoint[copy.m_nCount];
memcpy(m_pData, copy.m_pData, sizeof(TDataPoint) * copy.m_nCount);
}
else
m_pData = copy.m_pData;
return *this;
}
CXGraphDataSerie::~CXGraphDataSerie()
{
if (m_bAutoDelete)
delete[] m_pData;
}
void CXGraphDataSerie::PrepareClipboard(CFDATASERIE& serie)
{
serie.nCount = m_nCount;
serie.nFirstVisible = m_nFirstVisible;
serie.nLastVisible = m_nLastVisible;
serie.nXAxis = m_nXAxis;
serie.nYAxis = m_nYAxis;
serie.nIndex = m_nIndex;
serie.nLineSize = m_nLineSize;
serie.nFillStyle = m_nFillStyle;
serie.nMarkerType = m_nMarkerType;
serie.nMarker = m_nMarker;
serie.nMarkerSize = m_nMarkerSize;
serie.nLineStyle = m_nLineStyle;
serie.bAutoDelete = true;
serie.bShowMarker = m_bShowMarker;
serie.bFillBeneath = m_bFillBeneath;
serie.nFillCurve = m_nFillCurve;
serie.bFillTransparent = m_bFillTransparent;
serie.crFillColor = m_crFillColor;
serie.gtType = m_gtType;
#ifndef _WIN32_WCE
_tcscpy(serie.cLabel, m_cLabel);
#else
strcpy(serie.cLabel, (const char*)(LPCTSTR) m_cLabel);
#endif
}
void CXGraphDataSerie::DrawMarker(CDCEx *pDC)
{
CPoint point;
int nWidth = m_pGraph->m_clInnerRect.Width() / m_nMarkerSize / 4;
int nMarkerCount = 2;
if (nWidth > 0)
nMarkerCount = m_nCount / nWidth;
if (nMarkerCount <= 0)
nMarkerCount = 2;
if (m_pGraph->m_opOperation == CXGraph::opEditCurve)
nMarkerCount = 1;
CXGraphAxis& yaxis = m_pGraph->GetYAxis(m_nYAxis);
CXGraphAxis& xaxis = m_pGraph->GetXAxis(m_nXAxis);
for (int i = 0; i < m_nCount; i += nMarkerCount)
{
CPoint point;
point.x = xaxis.GetPointForValue(&m_pData[i]).x - (m_nMarkerSize / 2);
point.y = yaxis.GetPointForValue(&m_pData[i]).y - (m_nMarkerSize / 2);
int nMarker = m_nMarkerType == 0 ? m_pGraph->GetCurveIndex(this) : m_nMarker;
yaxis.DrawMarker (pDC, point, nMarker, m_nMarkerSize , pDC->m_bMono ? 0L : m_crColor, m_nMarkerType == 1 );
}
}
void CXGraphDataSerie::CreateCurveGripRgn(CPoint oldPoint, CPoint point)
{
HITTEST ht;
ht.p1 = oldPoint;
ht.p2 = point;
m_CurveRegions.push_back (ht);
}
void CXGraphDataSerie::Draw(CDCEx *pDC)
{
static CPoint oldPoint(-1,-1);
CPoint point;
int i = 0;
POINT* pPoly;
COLORREF crInverted = RGB(255 - GetRValue(m_crColor),
255 - GetGValue(m_crColor),
255 - GetBValue(m_crColor));
CPenSelector ps(pDC->m_bMono ? 0L : (m_bSelected ? crInverted : m_crColor), m_nLineSize, pDC, m_nLineStyle);
point.x = m_pGraph->GetXAxis(m_nXAxis).GetPointForValue(&m_pData[i]).x;
point.y = m_pGraph->GetYAxis(m_nYAxis).GetPointForValue(&m_pData[i]).y;
if (m_bFillBeneath)
{
if (m_nFillCurve != -1)
{
CXGraphDataSerie& ds = GetGraph()->GetCurve (m_nFillCurve);
long nCount = ds.GetCount () ;
pPoly = new POINT[m_nCount + nCount];
}
else
{
pPoly = new POINT[m_nCount + 2];
}
pPoly[0].x = point.x;
pPoly[0].y = point.y;
}
oldPoint = point;
CXGraphAxis& yaxis = m_pGraph->GetYAxis(m_nYAxis);
CXGraphAxis& xaxis = m_pGraph->GetXAxis(m_nXAxis);
if (m_gtType == gtLine)
pDC->MoveTo(point);
if (m_gtType == gtScatter)
pDC->Ellipse (point.x-m_nLineSize, point.y-m_nLineSize,point.x+m_nLineSize, point.y+m_nLineSize);
m_CurveRegions.clear ();
int nPoint = 1;
for (i = 1; i < m_nCount; i++)
{
point.x = xaxis.GetPointForValue(&m_pData[i]).x;
point.y = yaxis.GetPointForValue(&m_pData[i]).y;
if (point.x != oldPoint.x )
{
if ((m_pGraph->m_clInnerRect.PtInRect (point) || m_pGraph->m_clInnerRect.PtInRect (oldPoint)))
CreateCurveGripRgn(oldPoint, point);
if (m_gtType == gtLine)
pDC->LineTo(point);
if (m_gtType == gtScatter)
pDC->Ellipse (point.x-m_nLineSize, point.y-m_nLineSize,point.x+m_nLineSize, point.y+m_nLineSize);
if (m_bFillBeneath)
{
pPoly[nPoint].x = point.x;
pPoly[nPoint++].y = point.y;
}
oldPoint = point;
}
}
if (m_bFillBeneath)
{
if (m_nFillCurve != -1)
{
CXGraphDataSerie& ds = GetGraph()->GetCurve (m_nFillCurve);
CXGraphAxis& yaxis = GetGraph()->GetYAxis (ds.GetYAxis());
CXGraphAxis& xaxis = GetGraph()->GetXAxis (ds.GetXAxis());
for (long nFC = ds.GetCount () - 1; nFC >= 0; nFC--)
{
point.x = xaxis.GetPointForValue(&ds.m_pData[nFC]).x;
point.y = yaxis.GetPointForValue(&ds.m_pData[nFC]).y;
pPoly[nPoint].x = point.x;
pPoly[nPoint++].y = point.y;
}
}
else
{
pPoly[nPoint++] = CPoint(oldPoint.x, m_pGraph->m_clInnerRect.bottom) ;
pPoly[nPoint++] = CPoint(pPoly[0].x, m_pGraph->m_clInnerRect.bottom) ;
}
int nOldBkMode = pDC->GetBkMode ();
pDC->SetBkMode(m_bFillTransparent ? TRANSPARENT : OPAQUE);
int nOldROP2 = R2_COPYPEN;
if (m_bFillTransparent)
nOldROP2 = pDC->SetROP2 (R2_NOTXORPEN);
// Make shure the polygon's outline is invisible
CPenSelector ps(0, 0, pDC, PS_NULL);
if (m_nFillStyle == HS_SOLID)
{
// Solid
CBrushSelector bs(pDC->m_bMono ? 0L : m_crFillColor, pDC);
pDC->Polygon (pPoly, nPoint);
}
#ifndef _WIN32_WCE
else
{
// Hatched
CBrushSelector bs(pDC->m_bMono ? 0L : m_crFillColor, m_nFillStyle, pDC);
pDC->Polygon (pPoly, nPoint);
}
#endif
pDC->SetBkMode(nOldBkMode);
pDC->SetROP2 (nOldROP2);
delete pPoly;
}
}
void CXGraphDataSerie::ResetVisibleRange()
{
m_nFirstVisible = 0;
m_nLastVisible = m_nCount - 1;
}
TDataPoint* CXGraphDataSerie::GetLinearTrend(long nPoints)
{
TDataPoint* pData;
pData = new TDataPoint[m_nCount + nPoints];
double fYSum = 0.0,
fTYSum = 0.0,
fTSum = 0.0,
fT2Sum = 0.0;
for (long i = 0; i < m_nCount; i ++)
{
fYSum += m_pData[i].fYVal;
fTYSum += (m_pData[i].fYVal * (i+1));
fTSum += (i+1);
fT2Sum += ((i+1)*(i+1));
}
double fDiff = m_pData[1].fXVal - m_pData[0].fXVal;
for (i = 0; i < (m_nCount + nPoints); i ++)
{
if (i < m_nCount)
pData[i].fXVal = m_pData[i].fXVal;
else
pData[i].fXVal = pData[i-1].fXVal + fDiff;
double fB = (m_nCount * fTYSum - fTSum * fYSum) / (m_nCount * fT2Sum - (fTSum * fTSum));
double fA = (fYSum - fB * fTSum) / m_nCount;
pData[i].fYVal = fA + fB * (i+1);
}
return pData;
}
TDataPoint* CXGraphDataSerie::GetCubicTrend(long nPoints)
{
TDataPoint* pData;
pData = new TDataPoint[m_nCount + nPoints];
double fTY3Sum = 0.0,
fT6Sum = 0.0;
for (long i = 0; i < m_nCount; i ++)
{
fTY3Sum += (m_pData[i].fYVal * pow(i+1, 3));
fT6Sum += (pow (i+1, 6));
}
double fDiff = m_pData[1].fXVal - m_pData[0].fXVal;
for (i = 0; i < (m_nCount + nPoints); i ++)
{
if (i < m_nCount)
pData[i].fXVal = m_pData[i].fXVal;
else
pData[i].fXVal = pData[i-1].fXVal + fDiff;
pData[i].fYVal = (fTY3Sum/fT6Sum) * pow (i+1,3);
}
return pData;
}
TDataPoint* CXGraphDataSerie::GetPolynomialTrend(int nDegree, int nPoints)
{
TDataPoint* pData;
pData = new TDataPoint[m_nCount + nPoints];
m_PS.m_nGlobalO = nDegree;
if (!m_PS.Polyfit (m_nCount, nDegree, m_pData))
{
delete pData;
return NULL;
}
for ( int i = 0; i < (m_nCount + nPoints); i++ )
{
if (i < m_nCount)
pData[i].fXVal = m_pData[i].fXVal;
else
pData[i].fXVal = pData[i-1].fXVal + (pData[i-1].fXVal - pData[i-2].fXVal);
pData[i].fYVal = m_PS.GetValue (pData[i].fXVal);
}
return pData;
}
TDataPoint* CXGraphDataSerie::GetSimpleMovingAverage(int span)
{
int p;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -