📄 realtime.cpp
字号:
//y axis
pDC->BitBlt(m_drawRect.left, m_drawRect.top, m_assistLRect.Width(), m_assistLRect.Height(), &m_dc,
0, 0, SRCCOPY);
//curve graph
pDC->BitBlt(m_plotRect.left, m_plotRect.top, m_plotRect.Width(), m_plotRect.Height(), &m_dc,
m_assistTRect.left, m_assistTRect.bottom, SRCCOPY);
//x axis
pDC->BitBlt(m_plotRect.left, m_plotRect.bottom + 1, m_assistBRect.Width(), m_assistBRect.Height(), &m_dc,
m_assistBRect.left, m_assistBRect.top, SRCCOPY);
}
void CRealTime::RefreshGraph(CDC* pDC)
{
DWORD pageSpan, tickSpan;
tickSpan = (DWORD)(1000 / m_nCyclesPerSec + 0.5);
pageSpan = m_nXTicks * tickSpan;
if(m_bRealTime)
{
if (m_pCurLine->GetCounter() == 1)
{
//当前收到的采样数据为所在曲线中的第一个采样数据
if(m_nMaxTime == 0)
{
//此时暂无其它曲线的采样数据到来
m_nCursorTime = 0;
m_nMaxTime = m_pCurLine->m_nInterval;
m_nOffset = m_nTick = 0;
m_nPage = 1;
m_nMaxPages = 2;
m_X = m_plotRect.Width();
m_bControl = false;
}
}
else
{
//当前采样数据对应的采样时间(初始采样时间为0)
DWORD pTime = m_pCurLine->m_nInterval * (m_pCurLine->GetCounter() - 1);
if(pTime > m_nCursorTime)
{
//曲线图可能需要滚动
m_nCursorTime = pTime;
m_nMaxTime = m_nCursorTime + m_pCurLine->m_nInterval;
m_nOffset = 0;
if(m_nCursorTime > m_scale.xmax)
{
//曲线图需要滚动
DWORD interval;
interval = m_nCursorTime - (DWORD)(m_scale.xmax);
m_nOffset = interval / tickSpan + ((interval % tickSpan) ? 1 : 0);
m_scale.xmin += tickSpan * m_nOffset;
m_scale.xmax += tickSpan * m_nOffset;
m_nPage = (int)((DWORD)(m_scale.xmax) / pageSpan);
m_nMaxPages = m_nPage + 1;
m_nTick = (int)(((DWORD)(m_scale.xmax) % pageSpan) / tickSpan);
m_X += (tickSpan * m_nOffset) / m_scale.dx;
}
}
}
}//m_bRealTime
else
{
if (m_bForward)
{
//向前滚动查看曲线图
m_scale.xmin += tickSpan * m_nOffset;
m_scale.xmax += tickSpan * m_nOffset;
// m_nPage = (int)((DWORD)(m_scale.xmax) / pageSpan);
// m_nTick = (int)(((DWORD)(m_scale.xmax) % pageSpan) / tickSpan);
}
else
{
//向后滚动查看曲线图
m_scale.xmin -= tickSpan * m_nOffset;
m_scale.xmax -= tickSpan * m_nOffset;
// m_nPage = (int)((DWORD)(m_scale.xmax) / pageSpan);
// m_nTick = (int)(((DWORD)(m_scale.xmax) % pageSpan) / tickSpan);
}
if(m_nYOffset)
{
double dYOffset = m_nYOffset * m_nUnitsPerCycle;
if((m_nYOffset < 0 && m_scale.ymin == m_dYMin) || (m_nYOffset > 0 && m_scale.ymin == m_dYMax))
{
m_dYMin += dYOffset;
m_dYMax += dYOffset;
}
m_scale.ymin += dYOffset;
m_scale.ymax += dYOffset;
}
}
// XAxis(pDC);
// pDC->Rectangle(m_plotRect);
DrawFrame(pDC);
DrawSplineCurve(pDC);
}
void CRealTime::DrawSplineCurve(CDC* pDC, bool bFlag)
{
//绘制曲线
if(m_bRealTime)
{
//实时绘制,采用辅助图法
if(m_X > m_plotRect.Width() * 2)m_X %= (m_plotRect.Width() * 2);
if(m_nOffset >= m_nXTicks)
{
DrawBkGround(&m_dc, m_assistRect1);
DrawBkGround(&m_dc, m_assistRect2);
};
if(m_nOffset > 0)
{
if(m_X > m_plotRect.Width())
{
if(! m_bControl)
{
DrawBkGround(&m_dc, m_assistRect2);
m_bControl = true;
}
}
else
{
if(m_bControl)
{
DrawBkGround(&m_dc, m_assistRect1);
m_bControl = false;
}
}
}
int index = m_pCurLine->GetCounter() - 1;
if(index < 1)return;
double dx1, dy1, dx2, dy2;
dx2 = index * m_pCurLine->m_nInterval;
bool flag = true;
if(dx2 <= m_scale.xmin)flag = false;
int x1, y1, x2, y2;
if(flag && CalPoint(index - 1, dx1, dy1, dx2, dy2))
{
x1 = (int)((dx1 - m_scale.xmin) / m_scale.dx);
y1 = (int)((m_scale.ymax - dy1) / m_scale.dy);
x2 = (int)((dx2 - m_scale.xmin) / m_scale.dx);
y2 = (int)((m_scale.ymax - dy2) / m_scale.dy);
}
else
flag = false;
CPen pen;
pen.CreatePen(m_pCurLine->m_nLineStyle, m_pCurLine->m_nLineWidth, m_pCurLine->m_nColor);
CPen *pOldPen = m_dc.SelectObject(&pen);
if(m_X < m_plotRect.Width())
{
int mid = m_assistRect1.Width() - m_X;
if(flag)
{
if(x2 <= mid)
{
m_dc.MoveTo(m_assistRect2.right - mid + 1 + x1, m_assistRect2.top + y1);
m_dc.LineTo(m_assistRect2.right - mid + 1 + x2, m_assistRect2.top + y2);
}
else
if(x1 >= mid)
{
m_dc.MoveTo(m_assistRect1.left + x1 - mid, m_assistRect1.top + y1);
m_dc.LineTo(m_assistRect1.left + x2 - mid, m_assistRect1.top + y2);
}
else
{
int y = (y2 - y1) * (mid - x1) / (x2 - x1) + y1;
m_dc.MoveTo(m_assistRect2.right - mid + 1 + x1, m_assistRect2.top + y1);
m_dc.LineTo(m_assistRect2.right, m_assistRect2.top + y);
m_dc.MoveTo(m_assistRect1.left, m_assistRect1.top + y);
m_dc.LineTo(m_assistRect1.left + x2 - mid, m_assistRect1.top + y2);
}
}
pDC->BitBlt(m_plotRect.left, m_plotRect.top, mid, m_plotRect.Height(), &m_dc,
m_assistRect2.right - mid + 1, m_tM, SRCAND);
pDC->BitBlt(m_plotRect.left + mid, m_plotRect.top, m_plotRect.Width() - mid, m_plotRect.Height(), &m_dc,
m_assistRect1.left, m_tM, SRCAND);
}
else
{
if(flag)
{
m_dc.MoveTo(m_assistRect1.left + m_X - m_plotRect.Width() + 1 + x1, m_assistRect1.top + y1);
m_dc.LineTo(m_assistRect1.left + m_X - m_plotRect.Width() + 1 + x2, m_assistRect1.top + y2);
}
pDC->BitBlt(m_plotRect.left, m_plotRect.top, m_plotRect.Width(), m_plotRect.Height(), &m_dc,
m_assistRect1.left + m_X - m_plotRect.Width() + 1, m_tM, SRCAND);
}
m_dc.SelectObject(pOldPen);
}//realtime
else
{
int nLines;
nLines = (int)(m_cLines.GetCount());
CRect rect;
if(bFlag)
rect.SetRect(m_lM, m_tM, m_plotRect.Width() + m_lM - 1, m_plotRect.Height() + m_tM - 1);
else
rect.SetRect(m_assistRect1.left, m_assistRect1.top, m_assistRect2.right, m_assistRect2.bottom);
DrawBkGround(&m_dc, rect);
//非实时绘制,不采用辅助图法
for(int i = 0; i < nLines; i++)
{
m_pCurLine = &(m_cLines[i]);
CPen pen;
pen.CreatePen(m_pCurLine->m_nLineStyle, m_pCurLine->m_nLineWidth, m_pCurLine->m_nColor);
CPen *pOldPen = m_dc.SelectObject(&pen);
CBrush brush(m_pCurLine->m_nColor);
CBrush *pOldBrush = m_dc.SelectObject(&brush);
int nF, nT;
double dx1, dy1, dx2, dy2;
nF = (int)(m_scale.xmin / m_pCurLine->m_nInterval);
nT = (int)(m_scale.xmax / m_pCurLine->m_nInterval);
if(nT >= m_pCurLine->GetCounter() - 1)nT = m_pCurLine->GetCounter() - 2;
int x, y;
for(int j = nF; j < nT + 1; j++)
{
if(bFlag && i == GetEditCurve())
{
dx1 = j * m_pCurLine->m_nInterval;
dy1 = (*m_pCurLine)[j].value;
if(dx1 >= m_scale.xmin && dx1 <= m_scale.xmax && dy1 >= m_scale.ymin && dy1 <= m_scale.ymax)
{
x = (int)((dx1 - m_scale.xmin) / m_scale.dx) + m_lM;
y = m_tM + (int)((m_scale.ymax - dy1) / m_scale.dy);
m_dc.Ellipse(CRect(x - 3, y - 3, x + 3, y + 3));
}
}
if(CalPoint(j, dx1, dy1, dx2, dy2))
{
//当前曲线中连接第j个采样点与第j+1个采样点的线段有部分落在坐标平面区域中,则绘制该部分
x = (int)((dx1 - m_scale.xmin) / m_scale.dx) + m_lM;
if(! bFlag)x += m_plotRect.Width() + m_rM;
y = m_tM + (int)((m_scale.ymax - dy1) / m_scale.dy);
m_dc.MoveTo(x, y);
x = (int)((dx2 - m_scale.xmin) / m_scale.dx) + m_lM;
if(! bFlag)x += m_plotRect.Width() + m_rM;
y = m_tM + (int)((m_scale.ymax - dy2) / m_scale.dy);
m_dc.LineTo(x, y);
}
}
if(bFlag && (nT + 1) >= 0 && i == GetEditCurve())
{
dx1 = (nT + 1) * m_pCurLine->m_nInterval;
dy1 = (*m_pCurLine)[nT + 1].value;
if(dx1 >= m_scale.xmin && dx1 <= m_scale.xmax && dy1 >= m_scale.ymin && dy1 <= m_scale.ymax)
{
x = (int)((dx1 - m_scale.xmin) / m_scale.dx) + m_lM;
y = m_tM + (int)((m_scale.ymax - dy1) / m_scale.dy);
m_dc.Ellipse(CRect(x - 3, y - 3, x + 3, y + 3));
}
}
m_dc.SelectObject(pOldBrush);
m_dc.SelectObject(pOldPen);
}
if(bFlag)
pDC->BitBlt(m_plotRect.left, m_plotRect.top, m_plotRect.Width(), m_plotRect.Height(), &m_dc,
m_lM, m_tM, SRCAND);//SRCINVERT);//SRCPAINT);//SRCCOPY);
}
}
bool CRealTime::CalPoint(int index, double& x1, double& y1, double& x2, double& y2)
{
//索引值无效
if(index < 0 || index > m_pCurLine->GetCounter() - 2)return false;
x1 = index * m_pCurLine->m_nInterval;
y1 = (*m_pCurLine)[index].value;
x2 = (index + 1) * m_pCurLine->m_nInterval;
y2 = (*m_pCurLine)[index + 1].value;
if(x1 >= m_scale.xmin && x2 <= m_scale.xmax && y1 >= m_scale.ymin && y1 <= m_scale.ymax
&& y2 >= m_scale.ymin && y2 <= m_scale.ymax)return true;
//此处必存在x2 > x1
if(y2 == y1)
{
if(y1 > m_scale.ymax || y1 < m_scale.ymin)return false;
return Correct(m_scale.xmin, y1, m_scale.xmax, y1, x1, y1, x2, y2);
}
else
{
double ax[2], ay[2];
int i = 0;
//求与x = m_scale.xmin的交点
ax[i] = m_scale.xmin;
ay[i] = (y2 - y1) * (ax[i] - x1) / (x2 - x1) + y1;
if(ay[i] >= m_scale.ymin && ay[i] <= m_scale.ymax)i++;
ax[i] = m_scale.xmax;
ay[i] = (y2 - y1) * (ax[i] - x1) / (x2 - x1) + y1;
if(ay[i] >= m_scale.ymin && ay[i] <= m_scale.ymax)
{
i++;
if(i > 1)return Correct(ax[0], ay[0], ax[1], ay[1], x1, y1, x2, y2);
}
ay[i] = m_scale.ymin;
ax[i] = (x2 - x1) * (ay[i] - y1) / (y2 - y1) + x1;
if(ax[i] >= m_scale.xmin && ax[i] <= m_scale.xmax)
{
i++;
if(i > 1)return Correct(ax[0], ay[0], ax[1], ay[1], x1, y1, x2, y2);
}
ay[i] = m_scale.ymax;
ax[i] = (x2 - x1) * (ay[i] - y1) / (y2 - y1) + x1;
if(ax[i] >= m_scale.xmin && ax[i] <= m_scale.xmax)
{
i++;
if(i > 1)return Correct(ax[0], ay[0], ax[1], ay[1], x1, y1, x2, y2);
}
return false;
}
}
bool CRealTime::Correct(double ax1, double ay1, double ax2, double ay2,
double& x1, double& y1, double& x2, double& y2)
{
if(ax1 > ax2)
{
double temp;
temp = ax1;
ax1 = ax2;
ax2 = temp;
temp = ay1;
ay1 = ay2;
ay2 = temp;
}
if(x1 < ax1)
{
x1 = ax1;
y1 = ay1;
}
if(x2 > ax2)
{
x2 = ax2;
y2 = ay2;
}
if(x2 < x1)
return false;
else
return true;
}
void CRealTime::AddLine(const CString sName, DWORD nInterval, COLORREF nColor, const CString sDes, const CString sUnit,
double dLow, double dHigh, int nStyle, int nWidth)
{
m_pCurLine = new CALine();
m_pCurLine->m_sName = sName;
m_pCurLine->m_nInterval = nInterval;
m_pCurLine->m_nColor = nColor;
m_pCurLine->m_sDescription = sDes;
m_pCurLine->m_sUnit = sUnit;
m_pCurLine->m_dNowValue = 0;
m_pCurLine->m_dScaleLow = dLow;
m_pCurLine->m_dScaleHigh = dHigh;
m_pCurLine->m_nLineStyle = nStyle;
m_pCurLine->m_nLineWidth = nWidth;
m_cLines.Add(*m_pCurLine);
}
void CRealTime::AddValue(int i, double dValue)//SPLINEDATA pkg)
{
m_pCurLine = &(m_cLines[i]);
SPLINEDATA data = { dValue };
m_pCurLine->AddValue(data);
if(m_nMaxTime == 0)
m_dTotalYMin = m_dTotalYMax = dValue;
else
{
if(dValue < m_dTotalYMin)m_dTotalYMin = dValue;
if(dValue > m_dTotalYMax)m_dTotalYMax = dValue;
}
}
void CRealTime::RestoreRealDraw()
{
if(m_nCursorTime > 0)
{
DWORD pageSpan, tickSpan, sec;
tickSpan = (DWORD)(1000 / m_nCyclesPerSec + 0.5);
pageSpan = m_nXTicks * tickSpan;
sec = (m_nCursorTime / tickSpan ) * tickSpan;
if(sec < m_nCursorTime)sec += tickSpan;
if(sec < pageSpan)sec = pageSpan;
SetXRange(sec - pageSpan, sec);
m_nPage = m_nMaxPages - 1;
m_nTick = (sec % pageSpan) / tickSpan;
DrawSplineCurve(NULL, false);
}
m_X = m_plotRect.Width();
m_bControl = false;
m_bRealTime = true;
m_nOffset = 0;
}
void CRealTime::EndRealDraw()
{
m_bRealTime = false;
m_nOffset = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -