各位同学,好久不见,我可想死你们了!!!咦,那位不是巩叔吗?不好意思,侵权了,请多担待@_@。
前面的课程呢,拓展的内容比较多,最近笨笨想聚焦在CChart本身的使用上,进行一些介绍。
本节课主要想介绍CChart的辅助图形绘制,主要包括三方面内容:1、页面注释(题注和脚注);2、标签注释;3、辅助图元(直线、矩形、椭圆、正圆)。
会用Microsoft Word的人,对题注和脚注应该不陌生,大体如下,也就是在文档的顶部和底部显示一些简单的信息。
有时候画曲线的时候可能也需要题注和脚注。实际上,CChart的题注和脚注功能是多年以前一位朋友提出的需求,当时就实现了这项功能。
标签注释是在图像中间显示一些信息,这些信息既可以是文字标签,也可以是图片标签。
辅助图元的用途很多。举个最简单的应用场景,一些测量数据需要标出关键位置,用一条直线标注一下就非常直观了。
如图,这是笨笨最近编写的一个小程序,里面既有标签注释,也画了辅助线,可见,利用这些小功能,可以把关注的信息清晰地呈现出来。
请注意,本节课的部分内容需要CChart 4.8.0.1以上版本才能使用,请同学们到QQ群里下载。
下面先简单介绍辅助图形绘制用到的API。
A60.1 页面注释编程API
页注相关的编程接口如下。
// 设置是否显示题注void SetHeadernoteShow(bool bShow, int nPlotIndex=0);// 设置题注信息void SetHeadernoteString(TCHAR *note, int nPlotIndex=0);// 设置题注字体void SetHeadernoteFont(LOGFONT &font, int nPlotIndex=0);// 设置题注颜色void SetHeadernoteColor(COLORREF color, int nPlotIndex=0);// 设置题注对齐格式void SetHeadernoteAlign(int align, int nPlotIndex=0);// 设置是否显示尾注void SetFootnoteShow(bool bShow, int nPlotIndex=0);// 设置尾注信息void SetFootnoteString(TCHAR *note, int nPlotIndex=0);// 设置尾注字体void SetFootnoteFont(LOGFONT &font, int nPlotIndex=0);// 设置尾注颜色void SetFootnoteColor(COLORREF color, int nPlotIndex=0);// 设置尾注对齐格式void SetFootnoteAlign(int align, int nPlotIndex=0);
这些接口分两部分,就是题注(Headernote)和脚注(Footnote),其中题注位于图像顶部,脚注位于图像底部。两部分接口完全对应。
这些接口基本不需要进一步解释,很好理解,只有对齐函数的int align的含义需要稍微介绍一下。这个参数是Win32API的DrawText函数中的格式参数,可以是DT_LEFT、DT_RIGHT、DT_CENTER、DT_VCENTER等值以及它们的组合,具体请参考MSDN中DrawText的内容。
A60.2 标签注释编程API
标注相关的编程接口如下。
// 获得备注的数量int GetCommentsCount(int nPlotIndex=0);// 根据数据值添加备注int AddComment(TCHAR *comment, double x, double y, int nPlotIndex=0);// 设置上一个函数参数中,x,y是否是相对值。相对值的定义,就是本身值减去范围最小值void SetCommentPosRelative(bool relative, int nCommentIndex, int nPlotIndex=0);// 设置备注的位置,用于在AddComment后修改void SetCommentPos(int nCommentIndex, double x, double y, int nPlotIndex=0);// 是指备注边或角的位置void SetCommentCornerEdgePos(int nCommentIndex, double x, double y, int nWhere, int nPlotIndex=0);// 清除全部备注void ClearComments(int nPlotIndex=0);// 清除单个备注void ClearComment(int nCommentIndex, int nPlotIndex=0);
这些接口中,只有SetCommentCornerEdgePos中的nWhere参数需要解释一下。这个参数表示设置的是标签块哪一个边角的位置。具体如下。
enum{kCommentSetLeftTop,kCommentSetLeftBottom,kCommentSetRightTop,kCommentSetRightBottom,kCommentLeftCenter,kCommentBottomCenter,kCommentRightCenter,kCommentTopCenter,kCommentCenterCE,kCommentSetCount};
这个枚举类型在头文件Chart.h的头部,但被注释掉了,但可以到里面查看nWhere的含义。例如nWhere==0表示设置的是标签块的左上角,nWhere==4表示设置的是标签块坐标中点。
A60.3 辅助图元编程API
辅助图元指的是图像上附加的直线、矩形、椭圆、正圆图形。在此功能推出之前,可以在图像上加曲线来模拟这些图形,但总归不太方便。
辅助图元相关的编程接口如下。
// 设置是否显示图元对象void SetMetaGraphShow(bool bShow, int nPlotIndex=0);// 获得图元对象数目int GetMetaGraphCount(int nPlotIndex=0);// 清除所有图元对象void ClearMetaGraphs(int nPlotIndex=0);// 清除单个图元对象void ClearMetaGraph(int nIndex, int nPlotIndex=0);// 添加图元直线bool AddMetaLine(double x1, double y1, double x2, double y2, bool bInf = false, int endAxis = 0, int nLineStyle = PS_SOLID, int nLineWidth = 1, COLORREF crLineColor = RGB(240, 0, 0), int nPlotIndex=0);// 添加矩形图元bool AddMetaRect(double left, double top, double right, double bottom, int nLineStyle = PS_SOLID, int nLineWidth = 1, COLORREF crLineColor = RGB(240, 0, 0), bool bFill = false, COLORREF crFillColor = RGB(228, 228, 0), int nFillAlpha = 255, int nPlotIndex=0 );// 添加椭圆图元bool AddMetaEllipse(double ctx, double cty, double a, double b, int nLineStyle = PS_SOLID, int nLineWidth = 1, COLORREF crLineColor = RGB(240, 0, 0), bool bFill = false, COLORREF crFillColor = RGB(228, 228, 0), int nFillAlpha = 255, int nPlotIndex=0 );// 添加正圆图元bool AddMetaCircle(double ctx, double cty, double radius, bool xdir, int nLineStyle = PS_SOLID, int nLineWidth = 1, COLORREF crLineColor = RGB(240, 0, 0), bool bFill = false, COLORREF crFillColor = RGB(228, 228, 0), int nFillAlpha = 255, int nPlotIndex=0 );
这些接口,有几个参数需要解释一下。
1. AddMetaLine()函数中,bInf和endAxis的含义。
如果bInf为false,表示从数据点(x1,y1)到(x2,y2)画一条直线,这里x1、y1、x2、y2都是数据坐标,并非屏幕坐标。
如果bInf为true,表示从数据点(x1,y1)画一条到坐标轴的直线,此时(x2,y2)不起任何作用。endAxis表示往哪条坐标轴画线,其中0、1、2、3分别表示左轴、下轴、右轴、上轴,另外endAxis还可以是4或5,分别表示过(x1,y1)从左轴画到右轴,从上轴画到下轴。
2. 椭圆和正圆都可以填充,nFillAlpha是不透明度,默认为255,填充色不透明。
3. AddMetaCircle()中有一个参数xdir,表示圆半径radius根据哪个方向的数据进行计算。因X和Y两个方向的比例尺不同,即使两个方向的半径按数据计算一样,画出来的也是椭圆。当xdir为true时,表示按X方向数据来计算半径radius实际是多少像素;当xdir为false时,表示按Y方向数据来计算半径radius实际是多少像素。
A60.4 编程Demo
按照惯例,我们还是编写一个实例程序,演示一些这些功能。
1. 框架程序编写
我们先编写一个利用CChartWnd的简单程序。具体过程不再赘述,前面的课程中已经多次反复讲述。这里还是使用Win32 Application向导生成的框架。
这里本节课最主要的代码如下。
case WM_CREATE:chartWnd.Attach(hWnd);int hl;int i;hl = 50;for(i=-hl; i<=50; ++i){chartWnd.GetChart()->AddPoint2D(i, i*i*i/double(hl*hl*hl));}chartWnd.GetChart()->SetTitle(_T("测试辅助图形"));chartWnd.GetChart()->SetBLAxis();break;
这里就添加了一条曲线。
结果如下。
这里同学们随便画点啥都是可以的。
2. 添加题注和脚注
我们在图像的左上角和右下角,分别加上题注和脚注。
在上述代码的最后,添加如下代码:
chartWnd.GetChart()->SetHeadernoteShow(true);chartWnd.GetChart()->SetHeadernoteString(_T("CChart的题注,2024/02/12"));chartWnd.GetChart()->SetHeadernoteAlign(DT_LEFT);chartWnd.GetChart()->SetFootnoteShow(true);chartWnd.GetChart()->SetFootnoteString(_T("CChart的脚注"));
结果如图。
3. 添加标签注释
我们在数据(0.0, 0.0)位置添加一条标注,注意,这里默认指标签的左上角在(0.0, 0.0)位置。如果想换成其它边角在该位置,可以在添加后,利用SetCommentCornerEdgePos进行修改。
代码如下。
chartWnd.GetChart()->AddComment(_T("这个标注左上角在(0,0)位置"), 0.0, 0.0);
结果如图。
4. 添加辅助图形
我们直接添加直线、矩形、椭圆、正圆各一个,不再详细阐述, 代码如下。
chartWnd.GetChart()->SetMetaGraphShow(true);chartWnd.GetChart()->AddMetaLine(-20.0, (-20.0)*(-20.0)*(-20.0)/double(hl*hl*hl), 0.0, 0.0, true, 1, PS_DASH, 2);chartWnd.GetChart()->AddMetaRect(-40.0, 0.5, -30.0, -0.5);chartWnd.GetChart()->AddMetaEllipse(0.0, 0.0, 10.0, 0.15, PS_SOLID, 2, RGB(240, 240, 0), true, RGB(128, 0, 128), 128);chartWnd.GetChart()->AddMetaCircle(30.0, 0.0, 0.1, false);
结果如图。
由于辅助图形的绘制功能比较简单,上述代码已经较清楚地展示了使用方法。
好了,谢谢同学们的关注。