在数据采集中,有的时候需要将采集数据以曲线的方式显示出来,MFC并没有提供容易使用的曲线显示控件,好在有好心人写了ChartCtrl控件,可以很方便的绘制曲线。其代码公开在CodeProject网站:
https://www.codeproject.com/Articles/14075/High-speed-Charting-Control
由于年代比较久远,使用VC2017的时候会有些警告,但是都不影响使用。接下来我会使用一个示例来说明控件的使用方法,同时也为我自己以后使用的时候能够快速回忆起用法。
老版本的VC使用stdafx.h作为预编译头,VC2017使用pch.h作为预编译头,为了方便,干脆取消掉预编译头:属性->c/c+±>预编译头->不使用预编译头,如下图所示:
在程序中我用到了控件的曲线自适应功能,会根据数据自动的将曲线填满整个空间空间,在静止状态下,可以拉框放大局部曲线。 曲线控件使用Custom Control作为载体,在窗体上放置Custom Control后,需要设置stytle属性为0x52010000,相当于WS_CHILD(0x40000000L) | WS_VISIBLE(0x10000000L) |WS_CLIPCHILDREN(0x02000000L) | WS_TABSTOP(0x00010000L)
值得一提的是WS_CLIPCHILDREN属性,它让控件可以绘制曲线而不至于被窗体默认动作覆盖。
Class属性设置成ChartCtrl,注意此处一定不要写错成类名CChartCtrl,否则对话框会建立失败。Class属性是控件注册时使用的名称,可以在ChartCtrl.cpp中查到:
#define CHARTCTRL_CLASSNAME _T("ChartCtrl") // Window class name
if (!(::GetClassInfo(hInst, CHARTCTRL_CLASSNAME, &wndcls)))
{
memset(&wndcls, 0, sizeof(WNDCLASS));
wndcls.hInstance = hInst;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW);
wndcls.hIcon = 0;
wndcls.lpszMenuName = NULL;
wndcls.hbrBackground = (HBRUSH) ::GetStockObject(WHITE_BRUSH);
wndcls.style = CS_DBLCLKS;
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.lpszClassName = CHARTCTRL_CLASSNAME;
if (!RegisterClass(&wndcls))
{
// AfxThrowResourceException();
return false;
}
设置完毕后属性窗口如下图所示:
然后在窗体控件上右键->添加变量,变量名称设置为_chartCtrl,变量类型CChartCtrl。
初始化曲线控件,此函数在开始的时候调用一次就可以:
void CChartCtrlDemoDlg::InitChart(bool xAutoScale, bool yAutoScale)
{
//设置横坐标轴
//由于下面设置了自动适应曲线,这里设置的最大值和最小值无效
CChartStandardAxis* pBottomAxis =
_chartCtrl.CreateStandardAxis(CChartCtrl::BottomAxis);
pBottomAxis->SetMinMax(0, 10);
pBottomAxis->SetAxisColor(RGB(255, 255, 255));
pBottomAxis->SetTextColor(RGB(255, 255, 255));
//设置纵坐标轴
//由于下面设置了自动适应曲线,这里设置的最大值和最小值无效
CChartStandardAxis* pLeftAxis =
_chartCtrl.CreateStandardAxis(CChartCtrl::LeftAxis);
double minV = -10000, maxV = 10000;
pLeftAxis->SetMinMax(minV, maxV);
//设置坐标轴颜色
pLeftAxis->SetAxisColor(RGB(255, 255, 255));
pLeftAxis->SetTextColor(RGB(255, 255, 255));
//显示曲线图例
_chartCtrl.GetLegend()->SetVisible(true);
//设置坐标自动适应曲线,这可以让曲线随数据大小自动放大缩小。
_chartCtrl.GetLeftAxis()->SetAutomatic(xAutoScale);
_chartCtrl.GetBottomAxis()->SetAutomatic(xAutoScale);
//背景色设置为黑色
_chartCtrl.SetBackColor(0);
}
初始化曲线,这个函数的作用是为了设定曲线图中有几条曲线,增加或者修改曲线条数的时候都要调用此函数,如果整个程序曲线条数是固定的,则在调用InitChart后再调用此函数即可:
void CChartCtrlDemoDlg::InitLine(int lineCnt, int showCodeCnt)
{//初始化曲线设置
_xValue.resize(showCodeCnt);
int i;
for (i = 0; i < showCodeCnt; ++i)
{
_xValue[i] = i;
}
//在先移除全部曲线
_chartCtrl.RemoveAllSeries();
_vLineSerie1.clear();
for (i = 0; i < lineCnt; ++i)
{
//建立一条曲线
CChartLineSerie* p = _chartCtrl.CreateLineSerie();
_vLineSerie1.push_back(p);
_vLineSerie1[i]->SetSeriesOrdering(poNoOrdering);//设置为无序
CString str;
str.Format(_T("曲线%d"), i);
_vLineSerie1[i]->SetName(TChartString(str));
}
}
显示曲线函数比较简单,在数据改变后调用即可:
void CChartCtrlDemoDlg::ShowLine()
{
for (vector<vector<double>>::size_type i = 0; i < _vYValue.size(); ++i) {
_vLineSerie1[i]->SetPoints(&_xValue[0], &_vYValue[i][0], _vYValue[i].size());
}
}
我写的小程序界面如下所示:
在选中暂停后,可以使用鼠标左键从左上向左下拉框放大,右上向右下拉框恢复原状。
本程序使用VS2017编译通过。
程序下载地址:
https://download.csdn.net/download/haohaoganhuo/85774182