⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clplot.cpp

📁 实时曲线类的改进增加功能: 1)采样数据存盘和加载 2)演示程序中可以实现图形的打印预览和打印功能,曲线从原点开始
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -