📄 chart.cpp
字号:
//Remap scale to 0 - nGridY
SetRange(dRangeX[MIN],dRangeX[MAX],0,nGridY);
old = pDC->SelectObject(&pen);
for( j = (int)dRangeY[MIN] ; j < (int)dRangeY[MAX] ; j ++) {
y = (double)j;
// step = (pow(10,y+1) - pow(10,y)) /(double)FINE_SCALE ;
for(i = 0 ; i < FINE_SCALE ; i++ )
{
// y = log10(pow(10,y) + step) ;
m_start = Corrdinate(dRangeX[MIN],y) ;
m_stop = Corrdinate(dRangeX[MAX],y) ;
pDC->MoveTo(m_start);
pDC->LineTo(m_stop);
}
}
SetRange(dRangeX[MIN],dRangeX[MAX],Ymin,Ymax ) ;
pDC->SelectObject(old);
}
////////////////////////////////////////
// Allocate memory for plotting
BOOL CChart::AllocSerie(int nSerie)
{
if( !bIsSerieAllocated )
{
for(int i = 0 ; i < nSerieCount ; i++ ) {
if ( !mpSerie[i].AllocSerie(nSerie)) {
AfxMessageBox("Can not allocate serie") ;
return FALSE ;
}
}
}
nPointCount = nSerie ;
bIsSerieAllocated = TRUE ;
return TRUE ;
}
BOOL CChart::SetXYValue(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];
mpSerie[iSerieIdx].dValueX[index] = x ;
mpSerie[iSerieIdx].dValueY[index] = y ;
mpSerie[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, "Verdana") ;
// Initial font size
// Get a screen DC
CWindowDC wdc(NULL) ;
const int cyPixels = wdc.GetDeviceCaps(LOGPIXELSY);
d_lf.lfHeight = -1 * MulDiv(9, cyPixels, 72);
// Create a new font 7 pts.
pLegendFontY = new CFont() ;
pLegendFontY->CreateFontIndirect(&d_lf);
d_lf.lfHeight = -1 * MulDiv(9, 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(9, 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 ;
res = (dRangeY[MAX] - dRangeY[MIN]) / nGridY ;
pDC->SetTextAlign(TA_RIGHT);
pDC->SetBkMode(TRANSPARENT);
for ( i = 0 ; i <= nGridY ; i++)
{
y = dRangeY[MIN] + (res * (double)i) ;
cal_pt = Corrdinate(dRangeX[MIN],y) ;
str.Format("%5.2f",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);
Plot(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);
Plot(&memPlotDC);
dc.BitBlt(0,0, m_clientRect.Width(), m_clientRect.Height(),
&memPlotDC,0,0,SRCCOPY);
memPlotDC.SelectObject(oldBitmap);
}
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 ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -