📄 clplot.cpp
字号:
COLORREF oldbkcolor=dc->SetBkColor(m_ctlBkColor);//刻度字符的背景色
COLORREF oldtxtcolor=dc->SetTextColor(m_txtColor);//刻度字符的颜色
while(yGrid <= m_leftaxis.maxrange)
{
double yy=(yGrid-m_leftaxis.minrange)/m_leftaxis.m_dValuePrPixel;
int y= m_plotRect.bottom-(int)yy;
if(m_bYThickGrid)//横向的粗线
{
if(yGrid > m_leftaxis.minrange && yGrid<m_leftaxis.maxrange)
{
dc->MoveTo(CPoint(m_plotRect.left+1,y));
dc->LineTo(CPoint(m_plotRect.right-1,y));//横向的粗线(栅格)
}
}
//标左边Y轴坐标刻度值
char b[100];
sprintf(b, "%.0f", yGrid);
if(y==m_plotRect.bottom)//最下端坐标刻度上移
dc->DrawText(b, CRect(m_clientRect.left, y-m_TextHeight,m_plotRect.left-off,y), DT_RIGHT|DT_BOTTOM);
else
if(y==m_plotRect.top)//最上端坐标刻度下移
dc->DrawText(b, CRect(m_clientRect.left, y,m_plotRect.left-off,y+m_TextHeight), DT_RIGHT|DT_BOTTOM);
else
dc->DrawText(b, CRect(m_clientRect.left, y-m_TextHeight/2,m_plotRect.left-off,y+m_TextHeight/2), DT_RIGHT|DT_BOTTOM);
if(m_bUseRightYAxis)
{
//标右边Y轴坐标刻度值
double yr = (m_plotRect.bottom - yy) * m_rightaxis.m_dValuePrPixel + m_rightaxis.minrange;
sprintf(b, "%.0f", yr);
//dc->DrawText(b, CRect(m_plotRect.right+5, y-m_TextHeight/2,m_clientRect.right,y+m_TextHeight/2), DT_LEFT|DT_BOTTOM);
dc->TextOut(m_plotRect.right+5, y-m_TextHeight/2,b);
}
yGrid += delta;
}
//标Y轴名称及单位
CSize size=dc->GetTextExtent(m_leftaxis.szTitle);
int x=m_plotRect.left-size.cx/2;
if(x<0)
x=m_ctlRect.left+5;
if(m_bDispYTitle)//是否显示Y轴名称
//dc->DrawText(m_leftaxis.szTitle,CRect(m_plotRect.left-size.cx/2,m_plotRect.top-size.cy-6,m_plotRect.left+size.cx/2,m_plotRect.top-6), DT_RIGHT|DT_BOTTOM);
dc->TextOut(x,m_plotRect.top-size.cy-6,m_leftaxis.szTitle);
dc->SetTextColor(oldtxtcolor);////恢复为字符的原背景色
dc->SetBkColor(oldbkcolor);////恢复为字符的原背景色
dc->SelectObject(oldpen);
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawLegendShadow(CDC * dc)
{
if(m_blegendBorder){
CPen pen(PS_SOLID, 1, RGB(127,127,127));
CPen *oPen = dc->SelectObject(&pen);
CBrush *oBrush , brush(RGB(127,127,127));
oBrush = dc->SelectObject(&brush);
dc->Rectangle(CRect(m_legendRect.left+5,m_legendRect.top+5,m_legendRect.right+5, m_legendRect.bottom+5));
dc->SelectObject(oBrush);
dc->SelectObject(oPen);
}
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawLegend(CDC * dc)
{
if(m_blegendBorder){
CPen pen(PS_SOLID, 1, RGB(0,0,0));
CPen *oPen = dc->SelectObject(&pen);
CBrush *oBrush , brush(m_legendBkColor);
oBrush = dc->SelectObject(&brush);
dc->Rectangle(m_legendRect);
dc->SelectObject(oBrush);
dc->SelectObject(oPen);
}
int y = m_legendRect.top + 5;
int dx = m_legendRect.left + (2*m_TextHeight);
int mh = m_TextHeight/2;
for(int x = 0; x< MAXLEGENDS;x++){
if(m_primarylegends[x].m_bIAmInUse){
CRect lRect( dx + 5, y, m_legendRect.right - 5, y + m_TextHeight);
CPen pen(m_primarylegends[x].m_istyle, 1, m_primarylegends[x].m_color);
CPen *oPen = dc->SelectObject(&pen);
dc->MoveTo(CPoint(m_legendRect.left+5, y + mh));
dc->LineTo(CPoint(dx, y+mh));
dc->SelectObject(oPen);
//dc->DrawText(m_primarylegends[x].m_szTitle, lRect, DT_LEFT);
dc->TextOut( lRect.left,lRect.top,m_primarylegends[x].m_szTitle);
y+=m_TextHeight+1;
}
}
}
//*******************************************************************************************************/
//* Function: clPlot::AddPoint
//*******************************************************************************************************/
BOOL clPlot::AddPoint(int serie, long &valuetime, double &value)
{
//if(m_series[serie].m_lNoValues < m_lMaxDataPrSerie)
{
m_series[serie].AddPoint(valuetime, value);//将新数据存入数组中
long span =m_timeaxis.m_maxtime - m_timeaxis.m_mintime;
if(m_bAutoScrollX )
{
//此处的处理是使当前点距离右轴span*m_dMarginPercentOfCurrentPointToRightY距离,
//便于看到后面要达到的理想值
long maxtime=valuetime+(long)(span*m_dMarginPercentOfCurrentPointToRightY);//此处的处理是使当前点距离右轴span/3距离,便于看到后面要达到的理想值
long mintime = maxtime - span;
SetBXRange(mintime,maxtime );//调整X轴的起止位置对应的实际值(时间)
}
return TRUE;
}
return FALSE;
}
//调整坐标图上当前点距离右轴占整个X轴长度的百分比,这样做便于看到
//后面曲线的期望值
void clPlot::SetMarginPercentOfCurrentToRightY(double setpercent)
{
if(setpercent>=0&&setpercent<1)
m_dMarginPercentOfCurrentPointToRightY=setpercent;
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::SetBXRange(long &fromtime, long &totime, BOOL bMove)
{
if(fromtime<0||totime<=0) return;
m_timeaxis.m_mintime = fromtime;
m_timeaxis.m_maxtime = totime;
if(!bMove)//只有为固定显示时,才调整横轴坐标比例。在动态显示时,
//由于坐标自动调整,会使每次的显示比例不一致,这不是我们想要的。
{
m_timeaxis.m_dMilliSecondsPrPixel = ((double)(m_timeaxis.m_maxtime - m_timeaxis.m_mintime+1)) / (double)m_plotRect.Width();
}
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::SetLYRange(double &minrange, double &maxrange)
{
//m_leftaxis.minrange=minrange;m_leftaxis.maxrange=maxrange;// left axis
m_dLeftYSetMinRange=minrange;m_dLeftYSetMaxRange=maxrange;// left axis
m_leftaxis.minrange=minrange;
m_leftaxis.maxrange=maxrange;// left axis
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::SetRYRange(double &minrange, double &maxrange)
{
m_rightaxis.minrange=minrange;m_rightaxis.maxrange=maxrange;// right axis
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::SetBXTitle(const char *title)
{
m_timeaxis.m_szTitle=title; // X axis(time)
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::SetLYTitle(const char *title)
{
m_leftaxis.szTitle=title; // left Y axis
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::SetRYTitle(const char *title)
{
m_rightaxis.szTitle=title; // right Y axis
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::Reset()
//将cplot一切状态复位回首次进入测试的状态(包括释放分配数据存储区,指针回位,重置即使起点等)
{
long fromtime,totime;
GetXFromToTime(fromtime,totime);//得到当前图上的X轴起始时间
//fromtime=0;totime=30000;//ms
totime-=fromtime;fromtime=0;//ms
SetBXRange(fromtime,totime);
for(int s=0;s<MAXSERIES;s++)
{
if(m_series[s].m_bIAmInUse)
{
m_series[s].Reset();//依次复位各条曲线的数据
}
}
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::SetSerie(int s, int style, COLORREF color, double minrange, double maxrange, const char *szTitle, BOOL Rightalign)
{
m_series[s].m_bIAmInUse = TRUE;
m_series[s].m_color = color;
m_series[s].m_iLineStyle = style;
m_series[s].m_bRightAxisAlign = Rightalign;
m_leftaxis.szTitle=szTitle;
if(!s)
{
m_leftaxis.minrange=minrange;
m_leftaxis.maxrange=maxrange;// left axis
m_dLeftYSetMinRange=minrange;
m_dLeftYSetMaxRange=maxrange;// left axis
}
else
{
m_rightaxis.minrange=minrange;
m_rightaxis.maxrange=maxrange;// right axis
}
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::MoveWindow(CRect & Rect)
{
m_ctlRect = Rect;
GetParent()->ClientToScreen(m_ctlRect);
ScreenToClient(m_ctlRect);
ComputeRects(TRUE);
CWnd::MoveWindow(Rect);
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::SetLegend(int l, int style, COLORREF color, const char *text)
{
m_primarylegends[l].m_bIAmInUse = TRUE;
m_primarylegends[l].m_color = color;
m_primarylegends[l].m_istyle = style;
m_primarylegends[l].m_szTitle = text;
CClientDC dc(this);
CFont *oFont=NULL,newfont;
if(newfont.CreateFontIndirect(&m_zoomFont))
oFont = dc.SelectObject(&newfont);
//oFont = dc.SelectObject(&m_font);
int w = 0;
int n=0;
for(int x = 0; x< MAXLEGENDS;x++){
if(m_primarylegends[x].m_bIAmInUse){
n++;
CSize z=dc.GetTextExtent(CString(m_primarylegends[x].m_szTitle));
if(z.cx > w )
w=z.cx;
// m_TextHeight = z.cy;
}
}
m_legendRect.right = m_legendRect.left + 10+(2*m_TextHeight) + w;
m_legendRect.bottom = m_legendRect.top + 10 + (m_TextHeight*n);
if(oFont!=NULL)
dc.SelectObject(oFont);
}
void clPlot::SetXThickGridDisp(BOOL set)//set=true,draw;otherwise,not draw.
{
m_bXThickGrid=set; //是否画X轴粗网格
}
void clPlot::SetXThinGridDisp(BOOL set)//set=true,draw;otherwise,not draw.
{
m_bXThinGrid=set; //是否画X轴细网格
}
void clPlot::SetYThickGridDisp(BOOL set)//set=true,draw;otherwise,not draw.
{
m_bYThickGrid=set; //是否画Y轴粗网格
}
void clPlot::SetYThinGridDisp(BOOL set)//set=true,draw;otherwise,not draw.
{
m_bYThinGrid=set; //是否画Y轴细网格
}
void clPlot::SetLegendDraw(BOOL set) //是否显示图例(默认不显示)
{
m_bDrawLegend=set; //是否显示图例(默认不显示)
}
void clPlot::SetXTitleDisp(BOOL set) //是否显示X轴名称(默认显示)
{
m_bDispXTitle=set;
}
void clPlot::SetYTitleDisp(BOOL set) //是否显示Y轴名称(默认显示)
{
m_bDispYTitle=set;
}
void clPlot::SetLeftYAutoAdjust(BOOL set)//Y轴坐标是否自动调整(默认自动)
{
m_bLeftYAutoAdjust=set;
}
void clPlot::SetPlotBkColor(COLORREF newcolor)//设置曲线区的背景色
{
m_plotBkColor=newcolor; // plot bacground color
}
void clPlot::SetCtlBkColor(COLORREF newcolor)//设置图全部区域的背景色
{
m_ctlBkColor=newcolor; // control background color
}
void clPlot::SetGridColor(COLORREF newcolor)//设置主网格线的颜色
{
m_gridColor=newcolor; // grid line color
}
void clPlot::SetDiagramRect(CRect newrect,CDC *printerDC)//设置图的大小(父窗口中的逻辑坐标)
{
m_ctlRect=newrect;//父窗口中的逻辑坐标
GetParent()->ClientToScreen(m_ctlRect);
ScreenToClient(m_ctlRect);//本窗口中的逻辑坐标
ComputeRects(TRUE,printerDC);
}
void clPlot::GetDiagramRect(CRect &rect)//得到图的大小((父窗口中的逻辑坐标)
{
rect=m_ctlRect;
ClientToScreen(rect);
GetParent()->ScreenToClient(rect);
}
void clPlot::GetXFromToTime(long &fromtime,long &totime)//得到当前图上的X轴起始时间
{
fromtime=m_timeaxis.m_mintime;//当前X坐标原点表示的时间值(ms)
totime=m_timeaxis.m_maxtime;//当前X坐标最右点表示的时间值(ms)
}
BOOL clPlot::StoreToFile()
{
//CFileException fe;
CFileDialog fd(false,"AsmDat","asmfile",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"*.AsmDat");
if(fd.DoModal()!=IDOK)
return false;
CString lpszPathName=fd.GetPathName();
CFile pFile;
if(!pFile.Open(lpszPathName,CFile::modeCreate |CFile::modeReadWrite| CFile::shareExclusive))
return FALSE;
CArchive saveArchive(&pFile, CArchive::store | CArchive::bNoFlushOnDelete);
saveArchive.m_pDocument = NULL;
TRY
{
CWaitCursor wait;
Serialize(saveArchive); // save me
saveArchive.Close();
pFile.Close();
}
CATCH_ALL(e)
{
pFile.Abort();
return FALSE;
}
END_CATCH_ALL
return TRUE; // success
}
BOOL clPlot::LoadFromFile()
{
CFileDialog fd(true,"AsmDat","asmfile",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"*.AsmDat");
if(fd.DoModal()!=IDOK)
return false;
CString lpszPathName=fd.GetPathName();
CFile pFile;
if(!pFile.Open(lpszPathName,CFile::modeReadWrite| CFile::shareExclusive))
return FALSE;
CArchive loadArchive(&pFile, CArchive::load|CArchive::bNoFlushOnDelete);
TRY
{
CWaitCursor wait;
Serialize(loadArchive); // load
loadArchive.Close();
pFile.Close();
}
CATCH_ALL(e)
{
pFile.Abort();
return FALSE;
}
END_CATCH_ALL
Invalidate();
return TRUE; // success
}
void clPlot::Serialize(CArchive& ar)
{
for(int s=0;s<MAXSERIES;s++)
{
if(m_series[s].m_bIAmInUse)
m_series[s].Serialize(ar);//依次存各条曲线的采样值(时间:ms,速度:km/h)
}
if (ar.IsStoring())
{ // storing code
}
else
{ // loading code
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -