📄 clplot.cpp
字号:
//*******************************************************************************************************/
//* FileName: clPlot.cpp
//*
//* Contents: Implementation of clPlot, axis, legend, serie and timeaxis
//*
//* NOTE : Only a minimum of parameter validation is implemented to save time
//* since this plot is time critical.
//* Author: Bill Chen
//*******************************************************************************************************/
//* 20.Jul.04 Implemented flicker free drawing. Thanks to John Kim for providing
//* the MemDC and to Keith Rule, the author of CMemDC.
//*******************************************************************************************************/
#include "stdafx.h"
#include "clPlot.h"
#include "MemDC.h"
#include "malloc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//*******************************************************************************************************/
//* Function: serie::serie
//*******************************************************************************************************/
serie::serie()
{
m_nMinValue = 0;
m_nMaxValue = 0;
m_strTitle = "";
m_color = RGB(0,0,0);
m_iLineStyle = PS_SOLID;
m_lNoValues = 0;
m_lbegin = 0;
m_lend = 0;
}
//*******************************************************************************************************/
//* Function: serie::~serie
//*******************************************************************************************************/
serie::~serie()
{
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void serie::AddPoint(CTime &valuetime , double y)
{
m_pvalues[m_lend].ValueTime = valuetime;
m_pvalues[m_lend].dValue = y;
m_lend = ( m_lend + 1 ) % MAXSIRIEDATA;
m_lNoValues++;
// 空间大小从 0 增加到 MAXSIRIEDATA*sizeof(value)
// 最多能容纳 MAXSIRIEDATA-1 个 value 值
// 然后就当成一个循环链表使用
if ( m_lNoValues >= MAXSIRIEDATA )
{
m_lNoValues = MAXSIRIEDATA;
m_lbegin = ( m_lbegin + 1 ) % MAXSIRIEDATA;
}
}
//*******************************************************************************************************/
//* Function: serie::Reset
//*
//* Description: Reset the serie. Remove data and reset indexes and pointers.
//*
//* Parameters: -none-
//*
//* Return Value: -none-
//*
//* Author: Jan Vidar Berger
//*******************************************************************************************************/
void serie::Reset()
{
m_color = RGB(0,0,0);
m_iLineStyle = PS_SOLID;
m_lNoValues = 0;
m_lbegin = 0;
m_lend = 0;
}
//*******************************************************************************************************/
//*******************************************************************************************************/
clPlot::clPlot( int timespan )
{
m_nSpanTime = timespan * 60;
m_ctlBkColor = RGB(255,255,255);
m_gridColor = RGB(127,127,127);
m_bAutoScrollX = FALSE;
m_dzoom = 1.0;
SetBXRange(CTime::GetCurrentTime()-CTimeSpan(m_nSpanTime), CTime::GetCurrentTime());
m_logFont.lfHeight = -13;
m_logFont.lfWidth = 0;
m_logFont.lfEscapement = 0;
m_logFont.lfOrientation = 0;
m_logFont.lfWeight = 400;
m_logFont.lfItalic = FALSE;
m_logFont.lfUnderline = FALSE;
m_logFont.lfStrikeOut = FALSE;
m_logFont.lfCharSet = ANSI_CHARSET;
m_logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
m_logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
m_logFont.lfQuality = PROOF_QUALITY;
m_logFont.lfPitchAndFamily = DEFAULT_PITCH;
strcpy(m_logFont.lfFaceName, "Ariel");
m_zoomFont.lfHeight = -13;
m_zoomFont.lfWidth = 0;
m_zoomFont.lfEscapement = 0;
m_zoomFont.lfOrientation = 0;
m_zoomFont.lfWeight = 400;
m_zoomFont.lfItalic = FALSE;
m_zoomFont.lfUnderline = FALSE;
m_zoomFont.lfStrikeOut = FALSE;
m_zoomFont.lfCharSet = ANSI_CHARSET;
m_zoomFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
m_zoomFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
m_zoomFont.lfQuality = PROOF_QUALITY;
m_zoomFont.lfPitchAndFamily = DEFAULT_PITCH;
strcpy(m_zoomFont.lfFaceName, "Ariel");
m_font.CreateFontIndirect(&m_zoomFont);
}
//*******************************************************************************************************/
//*******************************************************************************************************/
clPlot::~clPlot()
{
}
//*******************************************************************************************************/
//*******************************************************************************************************/
BEGIN_MESSAGE_MAP(clPlot, CWnd)
//{{AFX_MSG_MAP(clPlot)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//*******************************************************************************************************/
//*******************************************************************************************************/
BOOL clPlot::Create(DWORD dwstyle, CRect &rect, CWnd *pParent, UINT id)
{
// 去掉 WS_BORDER 属性
DWORD style = dwstyle & (~WS_BORDER);
if ( !CWnd::Create(NULL, "", style, rect, pParent, id, NULL))
return FALSE;
m_clientRect = rect;
pParent->ClientToScreen(m_clientRect);
ScreenToClient(m_clientRect);
ComputeRects(TRUE);
return TRUE;
}
//*******************************************************************************************************/
//* Function : clPlot::ComputeRects
//*
//* Description : Compute rects used for internal possitioning of different objects. This function is
//* called when the plot is created or sized.
//*
//* Return type : void
//*
//* Parameter(s) : bInitialization indicate wherever parameters that can be changed abu the user
//* also should be computed.
//*
//* Author : Jan Vidar Berger
//* Modified by : Bill Chen
//*******************************************************************************************************/
void clPlot::ComputeRects(BOOL bInitialization)
{
CClientDC dc(this);
CSize z = dc.GetTextExtent( CString("A") );
m_TextHeight = z.cy;
m_dzoom = ( (double)m_clientRect.Height() / m_TextHeight ) / 25.0;
// 设置字体属性
m_zoomFont.lfWidth = (int)(m_logFont.lfWidth * m_dzoom);
m_zoomFont.lfHeight = (int)(m_logFont.lfHeight * m_dzoom);
m_font.Detach();
m_font.CreateFontIndirect( &m_zoomFont );
CFont *oFont = dc.SelectObject(&m_font);
// 设置四周的空白区域
m_iMtop = m_iMbottom = m_clientRect.Height()/10;
m_iMright = m_clientRect.Width()/20;
m_iMleft = m_iMright + COORWIDTH * SERIENUMBER; // 每个坐标值宽为 35 个象素
// 计算画图区
m_plotRect.left = m_clientRect.left + m_iMleft;
m_plotRect.right = m_clientRect.right - m_iMright;
m_plotRect.top = m_clientRect.top + m_iMtop;
m_plotRect.bottom = m_clientRect.bottom - m_iMbottom;
m_timeaxis.m_dSecondsPrPixel = ((double)(m_timeaxis.m_maxtime.GetTime() - m_timeaxis.m_mintime.GetTime())) / (double)m_plotRect.Width();
dc.SelectObject(oFont);
}
//*******************************************************************************************************/
//* Function: clPlot::OnPaint
//*
//* Description: This function will create a memory image, call Draw to draw the plot on it, and when
//* copy the image into memory.
//*
//* This is fast and provides flicker free plot update.
//*
//* Author: Jan Vidar Berger
//*******************************************************************************************************/
void clPlot::OnPaint()
{
CPaintDC dc(this); // device context for painting
CMemDC pdc(&dc); // non flickering(闪烁的) painting
Draw(&pdc);
// Do not call CWnd::OnPaint() for painting messages
}
BOOL clPlot::OnEraseBkgnd(CDC* pDC)
{
return FALSE;
}
//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::Draw(CDC * dc)
{
CFont *oFont = dc->SelectObject(&m_font);
DrawBasic(dc);
for(int i=0;i<5;i++)
WriteLegend(dc, i);
DrawGrid(dc);
DrawPlot(dc);
dc->SelectObject(oFont);
}
//*******************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -