自会控件曲线图坐标系如何加入网格

时间:2021-08-19 18:05:27
大神的图片
自会控件曲线图坐标系如何加入网格 


要实现的
自会控件曲线图坐标系如何加入网格

自己做的
自会控件曲线图坐标系如何加入网格

源码
void CGraphView::DrawCoordinate(CDC* pDC, CRect rectCoord) //绘制坐标
{
CString strCoord;
CRect rectTemp;
int i, nSection, nOffset;
CSize szText, szUnit;
double dbTemp, dbTempStartY, dbTempStartX,
dbRangX = m_dbEndX - m_dbStartX,
dbRangY = m_dbEndY - m_dbStartY;

dbTempStartX = m_dbStartX;
dbTempStartY = m_dbStartY;

pDC->FillSolidRect(rectCoord, m_clrCoordBkg);
nOffset = 2;
for (i = 0; i <= m_nDivisionX; i++)
{
dbTemp = dbTempStartX + dbRangX*i / m_nDivisionX;
strCoord.Format(_T("%g"), dbTemp);

nSection = rectCoord.Width()*i / m_nDivisionX;
szText = pDC->GetTextExtent(strCoord, strCoord.GetLength());

rectTemp.SetRect(rectCoord.left + nSection - szText.cx / 2, rectCoord.bottom + nOffset, rectCoord.left + nSection + szText.cx / 2, rectCoord.bottom + szText.cy + nOffset);
pDC->MoveTo(rectCoord.left + nSection, rectCoord.top);
pDC->LineTo(rectCoord.left + nSection, rectCoord.bottom);
pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_CENTER);
}

nOffset = 2;
for (i = 0; i <= m_nDivisionY; i++)
{
dbTemp = dbTempStartY + dbRangY*i / m_nDivisionY; //显示数字
strCoord.Format(_T("%g"), dbTemp);

nSection = rectCoord.Height()*i / m_nDivisionY;
szText = pDC->GetTextExtent(strCoord, strCoord.GetLength());

rectTemp.SetRect(rectCoord.left - szText.cx - nOffset, rectCoord.bottom - nSection - szText.cy * 2 / 3, rectCoord.left - nOffset, rectCoord.bottom - nSection + szText.cy / 3);
pDC->MoveTo(rectCoord.left, rectCoord.top + nSection);
pDC->LineTo(rectCoord.right + 1, rectCoord.top + nSection);
pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_RIGHT);
}



nOffset = 4;
rectTemp.SetRect(rectCoord.left + nOffset, rectCoord.top + 1, rectCoord.right, rectCoord.bottom - nOffset);
pDC->FillSolidRect(rectTemp, m_clrCoordBkg);
}


用  LineTo画的网格线会被 控件空白区覆盖 

5 个解决方案

#1


画线之前选入一个画笔


  CString    strCoord;
  CRect    rectTemp;
  int        i, nSection, nOffset;
  CSize    szText, szUnit;
  double    dbTemp, dbTempStartY, dbTempStartX,
    dbRangX = m_dbEndX - m_dbStartX,
    dbRangY = m_dbEndY - m_dbStartY;
  
  dbTempStartX = m_dbStartX;
  dbTempStartY = m_dbStartY;
  
  pDC->FillSolidRect(rectCoord, m_clrCoordBkg);

  //字体背景透明
  int nBackMode = pDC->SetBkMode(TRANSPARENT);
  //设置字体颜色
  COLORREF txColor = pDC->SetTextColor(m_rcText);
  
  //创建和选入画笔
  CPen penLine(PS_DOT, 1, m_crCoordinate);
  CPen *pOldPen = pDC->SelectObject(&penLine);

  nOffset = 2;
  for (i = 0; i <= m_nDivisionX; i++)
  {
    dbTemp = dbTempStartX + dbRangX*i / m_nDivisionX;
    strCoord.Format(_T("%g"), dbTemp);
    
    nSection = rectCoord.Width()*i / m_nDivisionX;
    szText = pDC->GetTextExtent(strCoord, strCoord.GetLength());
    
    rectTemp.SetRect(rectCoord.left + nSection - szText.cx / 2, rectCoord.bottom + nOffset, rectCoord.left + nSection + szText.cx / 2, rectCoord.bottom + szText.cy + nOffset);
    pDC->MoveTo(rectCoord.left + nSection, rectCoord.top);
    pDC->LineTo(rectCoord.left + nSection, rectCoord.bottom);
    pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_CENTER);
  }
  
  nOffset = 2;
  for (i = 0; i <= m_nDivisionY; i++)
  {
    dbTemp = dbTempStartY + dbRangY*i / m_nDivisionY; //显示数字
    strCoord.Format(_T("%g"), dbTemp);
    
    nSection = rectCoord.Height()*i / m_nDivisionY;
    szText = pDC->GetTextExtent(strCoord, strCoord.GetLength());
    
    rectTemp.SetRect(rectCoord.left - szText.cx - nOffset, rectCoord.bottom - nSection - szText.cy * 2 / 3, rectCoord.left - nOffset, rectCoord.bottom - nSection + szText.cy / 3);
    pDC->MoveTo(rectCoord.left, rectCoord.top + nSection);
    pDC->LineTo(rectCoord.right + 1, rectCoord.top + nSection);
    pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_RIGHT);
  }
  
  //恢复字体颜色
  pDC->SetTextColor(txColor);
  //恢复背景模式
  pDC->SetBkMode(nBackMode);
  //恢复画笔
  pDC->SelectObject(pOldPen); 

#2


是的,你没有选入CPen。。。

#3


这不是我的控件么
网格功能当年我也是做过的,就是moveto、lineto画就是了
你的问题主要是顺序的问题
先调用DrawCoordinate绘制基础坐标系
然后调用DrawGraphy绘制图谱
最后画网格
网格简单,都是直线

#4


引用 3 楼 xianglitian 的回复:
这不是我的控件么
网格功能当年我也是做过的,就是moveto、lineto画就是了
你的问题主要是顺序的问题
先调用DrawCoordinate绘制基础坐标系
然后调用DrawGraphy绘制图谱
最后画网格
网格简单,都是直线


就是大神的控件,受教了,已经按您说的搞好了!!! 自会控件曲线图坐标系如何加入网格

#5


引用 3 楼 xianglitian 的回复:
这不是我的控件么
网格功能当年我也是做过的,就是moveto、lineto画就是了
你的问题主要是顺序的问题
先调用DrawCoordinate绘制基础坐标系
然后调用DrawGraphy绘制图谱
最后画网格
网格简单,都是直线


void CGraphView::DrawGraphy(CDC *pDC, CRect rectCoord)
{
CRect rectView;
CRgn rgnTemp, rgnView;
CPen penLine, *pOldPen;
INT_PTR nCount = m_dataGraph.GetCount();

if (nCount == 0)
return;

double dbData;
int nOffsetX, nOffsetY;
int nRangX = abs(int((m_dbEndX - m_dbStartX)*m_dbResolutionX)),
nRangY = abs(int((m_dbEndY - m_dbStartY)*m_dbResolutionY));
int nCoordWith = rectCoord.Width(),
nCoordHeight = rectCoord.Height(),
nOriginX = rectCoord.left - int(m_dbStartX*nCoordWith / nRangX),
nOriginY = rectCoord.bottom + int(m_dbStartY*nCoordHeight / nRangY);


rgnTemp.CreateRectRgnIndirect(rectCoord);
pDC->SelectObject(rgnTemp);
penLine.CreatePen(PS_SOLID, 1, m_clrWave);
pOldPen = pDC->SelectObject(&penLine);

dbData = m_dataGraph.ElementAt(0);
nOffsetY = int(nCoordHeight*dbData / nRangY);
pDC->MoveTo(nOriginX, nOriginY - nOffsetY);

for (int i = 1; i<nCount; i++)
{
dbData = m_dataGraph.ElementAt(i);
nOffsetX = int(nCoordWith*(i + 1) / nRangX);
nOffsetY = int(nCoordHeight*dbData / nRangY);

pDC->LineTo(nOriginX + nOffsetX, nOriginY - nOffsetY);
}
pDC->SelectObject(pOldPen);
GetClientRect(rectView);
rgnView.CreateRectRgnIndirect(rectView);
pDC->SelectObject(rgnView);
}



自会控件曲线图坐标系如何加入网格

大神这是我用您写的控件做的曲线图,可是有一个问题,当值是0 的时候 ,曲线图怎么显示出来    坐标轴上显现不出来 0.。。。
求大神赐教

自会控件曲线图坐标系如何加入网格




#1


画线之前选入一个画笔


  CString    strCoord;
  CRect    rectTemp;
  int        i, nSection, nOffset;
  CSize    szText, szUnit;
  double    dbTemp, dbTempStartY, dbTempStartX,
    dbRangX = m_dbEndX - m_dbStartX,
    dbRangY = m_dbEndY - m_dbStartY;
  
  dbTempStartX = m_dbStartX;
  dbTempStartY = m_dbStartY;
  
  pDC->FillSolidRect(rectCoord, m_clrCoordBkg);

  //字体背景透明
  int nBackMode = pDC->SetBkMode(TRANSPARENT);
  //设置字体颜色
  COLORREF txColor = pDC->SetTextColor(m_rcText);
  
  //创建和选入画笔
  CPen penLine(PS_DOT, 1, m_crCoordinate);
  CPen *pOldPen = pDC->SelectObject(&penLine);

  nOffset = 2;
  for (i = 0; i <= m_nDivisionX; i++)
  {
    dbTemp = dbTempStartX + dbRangX*i / m_nDivisionX;
    strCoord.Format(_T("%g"), dbTemp);
    
    nSection = rectCoord.Width()*i / m_nDivisionX;
    szText = pDC->GetTextExtent(strCoord, strCoord.GetLength());
    
    rectTemp.SetRect(rectCoord.left + nSection - szText.cx / 2, rectCoord.bottom + nOffset, rectCoord.left + nSection + szText.cx / 2, rectCoord.bottom + szText.cy + nOffset);
    pDC->MoveTo(rectCoord.left + nSection, rectCoord.top);
    pDC->LineTo(rectCoord.left + nSection, rectCoord.bottom);
    pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_CENTER);
  }
  
  nOffset = 2;
  for (i = 0; i <= m_nDivisionY; i++)
  {
    dbTemp = dbTempStartY + dbRangY*i / m_nDivisionY; //显示数字
    strCoord.Format(_T("%g"), dbTemp);
    
    nSection = rectCoord.Height()*i / m_nDivisionY;
    szText = pDC->GetTextExtent(strCoord, strCoord.GetLength());
    
    rectTemp.SetRect(rectCoord.left - szText.cx - nOffset, rectCoord.bottom - nSection - szText.cy * 2 / 3, rectCoord.left - nOffset, rectCoord.bottom - nSection + szText.cy / 3);
    pDC->MoveTo(rectCoord.left, rectCoord.top + nSection);
    pDC->LineTo(rectCoord.right + 1, rectCoord.top + nSection);
    pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_RIGHT);
  }
  
  //恢复字体颜色
  pDC->SetTextColor(txColor);
  //恢复背景模式
  pDC->SetBkMode(nBackMode);
  //恢复画笔
  pDC->SelectObject(pOldPen); 

#2


是的,你没有选入CPen。。。

#3


这不是我的控件么
网格功能当年我也是做过的,就是moveto、lineto画就是了
你的问题主要是顺序的问题
先调用DrawCoordinate绘制基础坐标系
然后调用DrawGraphy绘制图谱
最后画网格
网格简单,都是直线

#4


引用 3 楼 xianglitian 的回复:
这不是我的控件么
网格功能当年我也是做过的,就是moveto、lineto画就是了
你的问题主要是顺序的问题
先调用DrawCoordinate绘制基础坐标系
然后调用DrawGraphy绘制图谱
最后画网格
网格简单,都是直线


就是大神的控件,受教了,已经按您说的搞好了!!! 自会控件曲线图坐标系如何加入网格

#5


引用 3 楼 xianglitian 的回复:
这不是我的控件么
网格功能当年我也是做过的,就是moveto、lineto画就是了
你的问题主要是顺序的问题
先调用DrawCoordinate绘制基础坐标系
然后调用DrawGraphy绘制图谱
最后画网格
网格简单,都是直线


void CGraphView::DrawGraphy(CDC *pDC, CRect rectCoord)
{
CRect rectView;
CRgn rgnTemp, rgnView;
CPen penLine, *pOldPen;
INT_PTR nCount = m_dataGraph.GetCount();

if (nCount == 0)
return;

double dbData;
int nOffsetX, nOffsetY;
int nRangX = abs(int((m_dbEndX - m_dbStartX)*m_dbResolutionX)),
nRangY = abs(int((m_dbEndY - m_dbStartY)*m_dbResolutionY));
int nCoordWith = rectCoord.Width(),
nCoordHeight = rectCoord.Height(),
nOriginX = rectCoord.left - int(m_dbStartX*nCoordWith / nRangX),
nOriginY = rectCoord.bottom + int(m_dbStartY*nCoordHeight / nRangY);


rgnTemp.CreateRectRgnIndirect(rectCoord);
pDC->SelectObject(rgnTemp);
penLine.CreatePen(PS_SOLID, 1, m_clrWave);
pOldPen = pDC->SelectObject(&penLine);

dbData = m_dataGraph.ElementAt(0);
nOffsetY = int(nCoordHeight*dbData / nRangY);
pDC->MoveTo(nOriginX, nOriginY - nOffsetY);

for (int i = 1; i<nCount; i++)
{
dbData = m_dataGraph.ElementAt(i);
nOffsetX = int(nCoordWith*(i + 1) / nRangX);
nOffsetY = int(nCoordHeight*dbData / nRangY);

pDC->LineTo(nOriginX + nOffsetX, nOriginY - nOffsetY);
}
pDC->SelectObject(pOldPen);
GetClientRect(rectView);
rgnView.CreateRectRgnIndirect(rectView);
pDC->SelectObject(rgnView);
}



自会控件曲线图坐标系如何加入网格

大神这是我用您写的控件做的曲线图,可是有一个问题,当值是0 的时候 ,曲线图怎么显示出来    坐标轴上显现不出来 0.。。。
求大神赐教

自会控件曲线图坐标系如何加入网格