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

📄 realtime.cpp

📁 一个多线程的网络数据采集系统(客户端)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	//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 + -