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

📄 chart.cpp

📁 vc代用matcom编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	return TRUE ;

}
BOOL CChart::SetXYValueB(double x, double y, int index, int iSerieIdx)
{
	if(!bIsSerieAllocated ) return FALSE ;
	if (iSerieIdx > (nSerieCount-1)) return FALSE ;

	// Prevent writting to unallocated buffer 
	if(index >= nPointCount ) return FALSE ;
	
	// Clip the ploting area if it exceed ranged .
	if(x > dRangeX[MAX] ) x = dRangeX[MAX] ;
	if(x < dRangeX[MIN] ) x = dRangeX[MIN] ;
	if(y > dRangeY[MAX] ) y = dRangeY[MAX] ;
	if(y < dRangeY[MIN] ) y = dRangeY[MIN];

	for( int i = 0  ; i < iSerieIdx ; i++)
	{	
		mpSerie[i].FreeSerie() ;
		mpSerieC[i].FreeSerie() ;
		mpSerieD[i].FreeSerie() ;
	}

	mpSerieB[iSerieIdx].dValueX[index] = x ;
	mpSerieB[iSerieIdx].dValueY[index] = y ;
	mpSerieB[iSerieIdx].bIsPlotAvailable = TRUE ;

	nPlotIndex = index ;
	return TRUE ;

}

//////////////////////////////////////////////////
// Set chart title
void CChart::SetChartTitle(CString str)
{
	strChartTitle = str ;
	bBkNeedToUpdate = TRUE ; // Background need to be re-draw
}

////////////////////////////////////////////////////
// Set number of grids on x axis and y axis
void CChart::SetGridXYNumber(int gridx, int gridy)
{
	nGridX = gridx ;
	nGridY = gridy ;
	bBkNeedToUpdate = TRUE ;
}

//////////////////////////////////////////////////////
// Create desired fonts for draw legend in x axis and 
// y axis .
void CChart::CreateFont()
{
	//Create system font ..
	LOGFONT d_lf ;
	
	// Init desired font
	memset(&d_lf, 0, sizeof(LOGFONT));
	lstrcpy(d_lf.lfFaceName, "Times New Roman") ;

	// Initial font size 
	// Get a screen DC 
	CWindowDC wdc(NULL) ;
	const int cyPixels = wdc.GetDeviceCaps(LOGPIXELSY);
	d_lf.lfHeight = -1 * MulDiv(7, cyPixels, 72);

	// Create a new font 7 pts.
	pLegendFontY = new CFont() ;
	pLegendFontY->CreateFontIndirect(&d_lf);

	d_lf.lfHeight = -1 * MulDiv(12, cyPixels, 72);
	d_lf.lfWeight = FW_BOLD ;
	pTitleFont = new CFont();
	pTitleFont->CreateFontIndirect(&d_lf);


	d_lf.lfWeight = 0 ;
	d_lf.lfOrientation = 900 ; // Rotate font 90 degree for x axis
	d_lf.lfEscapement = 900 ;  
	d_lf.lfHeight = -1 * MulDiv(7, cyPixels, 72);
	pLegendFontX = new CFont() ;
	pLegendFontX->CreateFontIndirect(&d_lf);

}

void CChart::DrawGridLabel(CDC *pDC)
{
	CFont *oldFont ;
	

	oldFont = pDC->SelectObject(pLegendFontY);

	int i ;
	double res , y  ; 
	CPoint cal_pt ;
	CSize txtSize ;
	CString str,strpoint ;
    
	
	res = (dRangeY[MAX] - dRangeY[MIN]) / nGridY ;
	pDC->SetTextAlign(TA_RIGHT);
	pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(RGB(80,80,80));
	for ( i = 0 ; i <= nGridY ; i++)
	{
		y = dRangeY[MIN] + (res * (double)i) ;
		cal_pt = Corrdinate(dRangeX[MIN],y) ;
		str.Format("%5.1f",y) ;

		txtSize = pDC->GetTextExtent(str) ;
		cal_pt.x -= 5 ;
		cal_pt.y -= txtSize.cy/2 ;

		pDC->TextOut(cal_pt.x,cal_pt.y,str) ;
	}

	txtSize = pDC->GetTextExtent(strLabelX);
	cal_pt.x = m_ctlRect.CenterPoint().x + (txtSize.cx/2) ;
	cal_pt.y = m_ctlRect.bottom - txtSize.cy - 5;
	pDC->TextOut(cal_pt.x,cal_pt.y,strLabelX);

	pDC->SelectObject(pLegendFontX);

	res = (dRangeX[MAX] - dRangeX[MIN]) / nGridX ;
	for ( i = 0 ; i <= nGridX ; i ++ )
	{
		y = dRangeX[MIN] + ( res * (double)i);
		cal_pt = Corrdinate(y,dRangeY[MIN]);
		str.Format("%5.1f",y);

		txtSize = pDC->GetTextExtent(str) ;
		cal_pt.x -= txtSize.cy/2 ;
		cal_pt.y += 5 ;
		pDC->TextOut(cal_pt.x,cal_pt.y,str);
	
	}
	txtSize = pDC->GetTextExtent(strLabelY);
	cal_pt.x = m_ctlRect.left + (txtSize.cy/2) ;
	cal_pt.y = m_ctlRect.CenterPoint().y  - (txtSize.cx/2) ;
	pDC->TextOut(cal_pt.x,cal_pt.y,strLabelY);	
    pDC->SelectObject(oldFont);

}

void CChart::ClearChart()
{
	nPlotIndex = 0 ;
	InvalidateRect(m_clientRect);
}

void CChart::PrintChart(CDC *pDC,int x , int y)
{
	
	int xPixel ;
	int yPixel  ;
	int oldmapmode ;

	CDC *dc = GetDC();
	
	xPixel = pDC->GetDeviceCaps(LOGPIXELSX);
	yPixel = pDC->GetDeviceCaps(LOGPIXELSY);
	
	//Calculate ratio to be zoomed.
	xPixel =  xPixel /dc->GetDeviceCaps(LOGPIXELSX);
	yPixel =  yPixel /dc->GetDeviceCaps(LOGPIXELSY);
	ReleaseDC(dc);
	
	oldmapmode = pDC->SetMapMode(MM_ANISOTROPIC);
	pDC->SetViewportExt(xPixel,yPixel);
	pDC->SetViewportOrg(x,y);

	DrawBorder(pDC);
	pDC->DrawEdge(m_ctlRect,BDR_SUNKENINNER|BDR_SUNKENOUTER, BF_RECT);
	DrawChartTitle(pDC);
	if ( bLogScale )
	   DrawLogGrid(pDC);
	DrawGrid(pDC);
	
	DrawAxis(pDC) ;
	DrawGridLabel(pDC);
	PlotA(pDC) ;
	PlotB(pDC) ;
	PlotC(pDC) ;
	PlotD(pDC) ;

	pDC->SetMapMode(oldmapmode);
}

void CChart::SetChartLabel(CString strX, CString strY)
{
	strLabelX = strX ;
	strLabelY = strY ;
}


void CChart::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	CDC memPlotDC ;
	CBitmap *oldBitmap ;
	CBitmap m_plotBitmap ;
	
	// Check if background need to be redrawn
	if (bBkNeedToUpdate){
		DrawBackGround(&dc);
		bBkNeedToUpdate = FALSE ;
	}
	memPlotDC.CreateCompatibleDC(&dc) ;
	m_plotBitmap.CreateCompatibleBitmap(&dc,
		m_clientRect.Width(), m_clientRect.Height());
	oldBitmap = (CBitmap*)memPlotDC.SelectObject(&m_plotBitmap);
	
	// BitBlt background .
	memPlotDC.BitBlt(0,0, m_clientRect.Width(), m_clientRect.Height(),
		&memBkDC,0,0,SRCCOPY);
	if(m_num==1)
	{
		PlotA(&memPlotDC); 
	}
	if(m_num==2)
	{
		PlotA(&memPlotDC); 
		PlotB(&memPlotDC);
	}
	if(m_num==3)
	{
		PlotA(&memPlotDC); 
		PlotB(&memPlotDC);
		PlotC(&memPlotDC); 
	}
	if(m_num==4)
	{
		PlotA(&memPlotDC); 
		PlotB(&memPlotDC);
		PlotC(&memPlotDC); 
		PlotD(&memPlotDC);
	}
	dc.BitBlt(0,0, m_clientRect.Width(), m_clientRect.Height(),
		&memPlotDC,0,0,SRCCOPY);
	memPlotDC.SelectObject(oldBitmap);
	memPlotDC.DeleteDC();

}

void CChart::DrawBackGround(CDC *pDC)
{		
	if(memBkDC.GetSafeHdc() == NULL) {
		memBkDC.CreateCompatibleDC(pDC);
		m_BkBitmap.CreateCompatibleBitmap(pDC,
			m_clientRect.Width(), m_clientRect.Height());
	}   
	m_pOldBkBitmap = (CBitmap*)memBkDC.SelectObject(&m_BkBitmap) ;
	DrawBorder(&memBkDC);
	DrawAxis(&memBkDC);
	DrawGrid(&memBkDC);
	if(bLogScale)
		DrawLogGrid(&memBkDC);
	DrawGridLabel(&memBkDC);
	DrawChartTitle(&memBkDC);
}

void CChart::Invalidate(BOOL bErase )
{
	if ( bErase )
		bBkNeedToUpdate = TRUE ;

	CWnd::Invalidate(bErase) ;
}



////////////////////////////////////////////////////
// Source of CPlotSerie 

CPlotSerie::CPlotSerie() 
{
		dValueX = NULL ;
		dValueY = NULL ;
		bIsPlotAvailable = FALSE ;
		bBufferAllocated = FALSE ;
		m_plotColor = RGB(0,0,0);
}

BOOL CPlotSerie::AllocSerie(UINT nPoint)
{
	dValueX = (double*)malloc(nPoint * sizeof (double) ) ;
	dValueY = (double*)malloc(nPoint * sizeof (double) ) ;
	if ( (dValueX == NULL) || (dValueY == NULL) ) 
		return FALSE ;
	bBufferAllocated = TRUE ;
	return TRUE ;
}

BOOL CPlotSerie::FreeSerie()
{
	if ( bBufferAllocated ) {
		free(dValueX) ;
		free(dValueY) ;
	}
	bBufferAllocated = FALSE ;
	return TRUE ;
}



BOOL CChart::SetXYValueC(double x, double y, int index, int iSerieIdx)
{
	if(!bIsSerieAllocated ) return FALSE ;
	if (iSerieIdx > (nSerieCount-1)) return FALSE ;

	// Prevent writting to unallocated buffer 
	if(index >= nPointCount ) return FALSE ;
	
	// Clip the ploting area if it exceed ranged .
	if(x > dRangeX[MAX] ) x = dRangeX[MAX] ;
	if(x < dRangeX[MIN] ) x = dRangeX[MIN] ;
	if(y > dRangeY[MAX] ) y = dRangeY[MAX] ;
	if(y < dRangeY[MIN] ) y = dRangeY[MIN];

	for( int i = 0  ; i < iSerieIdx ; i++)
	{	
		mpSerieB[i].FreeSerie() ;
		mpSerie[i].FreeSerie() ;
		mpSerieD[i].FreeSerie() ;
	}

	mpSerieC[iSerieIdx].dValueX[index] = x ;
	mpSerieC[iSerieIdx].dValueY[index] = y ;
	mpSerieC[iSerieIdx].bIsPlotAvailable = TRUE ;

	nPlotIndex = index ;
	return TRUE ;
}
void CChart::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	CMenu menu;
	menu.LoadMenu(IDR_MENU_CHART);
	menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this);
}
BOOL CChart::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{

	return CWnd::OnSetCursor(pWnd, nHitTest, message); 
}
void CChart::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	if (Is_GetData&&m_axisRect.left<=m_Point.x&&m_axisRect.right>=m_Point.x&&m_axisRect.top<=m_Point.y&&m_axisRect.bottom>=m_Point.y)
	{
		::SetCursor(::LoadCursor(NULL,IDC_CROSS));
	}
	Invalidate(TRUE);
	CWnd::OnLButtonDown(nFlags, point);
}
void CChart::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default	
	m_Point=point;
	if (m_axisRect.PtInRect(point))
	{
		if (Is_GetData&&m_axisRect.left<=m_Point.x&&m_axisRect.right>=m_Point.x&&m_axisRect.top<=m_Point.y&&m_axisRect.bottom>=m_Point.y)	//读数功能
		{			
			::SetCursor(::LoadCursor(NULL,IDC_CROSS));
			m_PointX=point.x;
			m_PointY=point.y;
		}
	}
	Invalidate(TRUE);
	CWnd::OnLButtonDown(nFlags, point);

}

void CChart::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default

}

void CChart::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if (m_axisRect.PtInRect(point))
	{
		
		if (Is_GetData)
		{
			::SetCursor(::LoadCursor(NULL,IDC_CROSS));			
		}
		
	}	
    Invalidate();
	CWnd::OnMouseMove(nFlags, point);
}
void CChart::OnReadPoint()
{	
	Is_GetData=true;
}
void CChart::OnBack()
{	
	Is_GetData=FALSE;
	Invalidate(TRUE);
}
BOOL CChart::SetXYValueD(double x, double y, int index, int iSerieIdx)
{
	if(!bIsSerieAllocated ) return FALSE ;
	if (iSerieIdx > (nSerieCount-1)) return FALSE ;

	// Prevent writting to unallocated buffer 
	if(index >= nPointCount ) return FALSE ;
	
	// Clip the ploting area if it exceed ranged .
	if(x > dRangeX[MAX] ) x = dRangeX[MAX] ;
	if(x < dRangeX[MIN] ) x = dRangeX[MIN] ;
	if(y > dRangeY[MAX] ) y = dRangeY[MAX] ;
	if(y < dRangeY[MIN] ) y = dRangeY[MIN];

	for( int i = 0  ; i < iSerieIdx ; i++)
	{	
		mpSerieB[i].FreeSerie() ;
		mpSerieC[i].FreeSerie() ;
		mpSerie[i].FreeSerie() ;
	}
	mpSerieD[iSerieIdx].dValueX[index] = x ;
	mpSerieD[iSerieIdx].dValueY[index] = y ;
	mpSerieD[iSerieIdx].bIsPlotAvailable = TRUE ;

	nPlotIndex = index ;
	return TRUE ;
}

void CChart::PlotC(CDC *pDC)
{
	if ( !nPlotIndex ) return ;
		
	CPen *old , *pen ;

	
	CPoint pt ;
	int i;
	
	for( i = 0 ; i < nSerieCount ; i++) {
		// Create the new pen as the color of serie 
		pen = new CPen(PS_SOLID,0,mpSerieC[i].m_plotColor);
		old = pDC->SelectObject(pen);
		// calculate the corrdinate of ploting point.
		pt = Corrdinate(mpSerieC[i].dValueX[0],mpSerieC[i].dValueY[0]) ;
		pDC->MoveTo(pt);
		//Start plot all available data .
		for(int index = 1 ; index <= nPlotIndex ; index++){
			pt = Corrdinate(mpSerieC[i].dValueX[index],
						mpSerieC[i].dValueY[index]) ;
		pDC->LineTo(pt) ;		
		}
		pDC->SelectObject(old);
		delete pen ;
	}
}
void CChart::PlotD(CDC *pDC)
{
	if ( !nPlotIndex ) return ;
		
	CPen *old , *pen ;

	
	CPoint pt ;
	int i;
	
	for( i = 0 ; i < nSerieCount ; i++) {
		// Create the new pen as the color of serie 
		pen = new CPen(PS_SOLID,0,mpSerieD[i].m_plotColor);
		old = pDC->SelectObject(pen);
		// calculate the corrdinate of ploting point.
		pt = Corrdinate(mpSerieD[i].dValueX[0],mpSerieD[i].dValueY[0]) ;
		pDC->MoveTo(pt);
		//Start plot all available data .
		for(int index = 1 ; index <= nPlotIndex ; index++){
			pt = Corrdinate(mpSerieD[i].dValueX[index],
						mpSerieD[i].dValueY[index]) ;
		pDC->LineTo(pt) ;		
		}
		pDC->SelectObject(old);
		delete pen ;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -