Teechart动态设计方法
以前搞Qt或者MFC,不明白为何大牛做界面时不用工具箱生成和设计控件,反而要花大量的精力用代码动态生成。经过一段时间的编程体验后,会发现动态生成更好控制,更好的根据开发人员的意愿在代码修改属性,而且不容易出一些莫名其妙的bug。但是也并不就是说工具箱可不用,工具箱自然是最简单,最方便的使用方式,如果窗体的控件变化不大,大可以拖来拖去设置属性。
本篇笔记将总结Teechart绘图工具的动态创建和设计方法。介绍其中几个常见功能的动态设计方法,希望能达到举一反三的效果。
一、准备工作
1.新建一个MFC基于dialog的工程TeechartTest。
2.为工程添加一个类,选择来自Typelib的MFC 类,选择TeeChart ActiveX ControlV5,将下面左右的类全部添加进来。(本例中需要用哪个就Include哪个为了学习方便,这样会导致工程比较大。在实际开发时需要用哪个添加哪个。)
3.在TeechartTestDlg.cpp中的初始化函数OnInitDialog里新建个函数TeechartSetup,用来写我们的动态代码。
4.在TeechartTestDlg.h中声明该函数,在TeechartTestDlg.cpp中定义该函数TeechartSetup。
二、动态创建一个Tchart
1.右键工程添加类,与添加其他Teechart类不同,此处选择ActiveX控件中的MFC类。
2.选择TeeChart Pro ActiveXControl V5<1.0>,发现只有一个ITchart,将它添加进来,在工程中多了一个CTChart0类。
3.在Dlg.h中添加#include"CTChart0.h",声明一个对象该类的对象CTChart0 m_tchart;
4.在dlg.cpp中的TeechartSetup里调用Create函数创建表格。我们可以在.h文件中在定义一个CTChart0 m_tchart1,生成两个表格。
CRect rect;
GetClientRect(&rect);
m_tchart.Create(NULL,WS_CHILD|WS_VISIBLE,CRect(0,0,rect.Width(),rect.Height()/2),this,1000);
m_tchart1.Create(NULL,WS_CHILD|WS_VISIBLE,CRect(0,rect.Height()/2,rect.Width(),rect.Height()),this,1001);
三、表格属性设置
1.默认是三维的,想把它改成二维的。在.h文件中添加#include"CAspect.h",在TeechartSetup函数里获取该Aspect,设置View3D为False。
/*设置D/3D显示*/
CAspect m_aspect = m_tchart.get_Aspect(); //得到表体
m_aspect.put_View3D(FALSE); //设置D关闭
2.设置表格标题内容。获取标题需要用到Ctitles和CStrings这两个类。自然先Include这两个头文件。原理是先用chart的get_header获取一个Ctitles对象,再用其成员函数得到其CStrings,通过CStrings设置其内容。注意Add函数变量是variant类型,可以用_variant_t转化即可。
/*设置表格标题内容*/
CTitles m_title = m_tchart.get_Header(); //得到标题
CStrings m_titlestring = m_title.get_Text(); //得到标题内容
m_titlestring.Clear(); //先清除
m_titlestring.Add(_variant_t("MyTest")); //添加新标题
3.设置标题样式。获取其标题Font,用到CTeeFont类。
/*设置表格标题字体样式*/
CTeeFont m_titleFont = m_title.get_Font(); //得到样式
m_titleFont.put_Bold(TRUE); //加粗
m_titleFont.put_Color(RGB(0,0,255)); //颜色
m_titleFont.put_Size(14); //字号
四、动态添加曲线Series
1.添加Series类头文件#include"CSeries.h"
2.调用AddSeries添加曲线。其参数ESeriesClass是曲线类型,见sc宏定义
ESeriesClass
{
scLine = 0,
scBar = 1,
scHorizBar = 2,
scArea = 3,
scPoint = 4,
scPie = 5,
scFastLine = 6,
scShape = 7,
scGantt = 8,
scBubble = 9,
scArrow = 10,
scCandle = 11,
scPolar = 12,
scSurface = 13,
scVolume = 14,
scErrorBar = 15,
scBezier = 16,
scContour = 17,
scError = 18,
scPoint3D = 19,
scRadar = 20,
scClock = 21,
scWindRose = 22,
scBar3D = 23,
scImageBar = 24,
scDonut = 25,
scTriSurface = 26,
scBox = 27,
scHorizBox = 28,
scHistogram = 29,
scColorGrid = 30,
scBarJoin = 31,
scHighLow = 32,
scWaterfall = 33,
scSmith = 34,
scPyramid = 35,
scMap = 36,
scHorizLine = 37,
scFunnel = 38,
scCalendar = 39
3.用CSeries获取曲线对象,调用AddXY添加数据。
/*动态添加曲线Series,并添加数据源进行显示*/
m_teechart.AddSeries(scFastLine); //SC宏定义
CSeries m_series = m_teechart.Series(0);
for (int i=0; i<100; i++)
{
m_series.AddXY(i,rand()%50,NULL,RGB(255,0,0));
}
五、举一反三
是时候举一反三了。
如果你是新手,你应该不知道设置某一个控件需要获取哪些对象(句柄),怎么获得,获得了又该怎么设置。
一个很好的突破口就是Teechart自带的帮助文档,就像所有其他工具的帮助文档一样。打开开始菜单中的teechart tutorials.lnk,也即打开了Teechart的面纱。
那么帮助文档怎么用呢?举个例子:
目的:我们想设置下表格的坐标轴。
我们大概可以直到坐标轴应该累属于表格,也就是说表格类CTChart0应该有其对应的获取函数。模型一般都是get_hanshu。我们可以在CTChart0下找其成员函数,很快就会发现get_Axis,会点英文应该大概直到这跟获取坐标轴对象有关。
我们可以在帮助文档的索引中输入Axis,双击ITchart,可以看到一个鲜活的示例。
可以看到Tchart的确有个Axis对象,也就是有对应的类,而要获取纵轴,它还调用了Left。如果你有点好奇心你肯定点开了property Axis:IAxes看了。
这时,你应该明白了怎么写代码了。如果你还是不知道调用哪个函数。你可以在搜索中输入Axis,点开tutorial 15看看,应该很明确了吧。
按照这个思路,整理代码如下:
/*动态设置坐标轴*/
CAxes m_Axis = m_tchart.get_Axis(); //得到坐标轴
CAxis m_left = m_Axis.get_Left(); //得到纵轴
CAxis m_bottom = m_Axis.get_Bottom(); //得到横轴
m_left.put_Automatic(FALSE); //设置不自动适应
m_left.put_Minimum(0); //设置纵轴起始值
m_left.put_Maximum(100); //设置纵轴结束值
m_left.put_Increment(20); //设置增量
m_left.put_StartPosition(20); //设置起始位置%
m_left.put_EndPosition(80); //设置结束位置%
CAxisTitle m_AxisLeftTitle = m_left.get_Title(); //得到纵轴标题
m_AxisLeftTitle.put_Caption(_T("随机数"));//设置纵轴标题
CAxisTitle m_AxisBottomTitle = m_bottom.get_Title(); //得到横轴标题
m_AxisBottomTitle.put_Caption(_T("时刻")); //设置横轴标题
CTeeFont m_LeftTitleFont = m_AxisLeftTitle.get_Font(); //得到坐标轴样式
m_LeftTitleFont.put_Size(14);
m_LeftTitleFont.put_Bold(TRUE);
CTeeFont m_BottomTitleFont = m_AxisBottomTitle.get_Font(); //得到坐标轴样式
m_BottomTitleFont.put_Size(14);
m_BottomTitleFont.put_Bold(TRUE);
六、还有个方法
找到安装目录下的.\Utilities\New VC Classes文件夹,里面是对应的C++源码。只要把所有文件拷贝到建立的公工程下,并把这些文件添加到工程里,在应用的.h文件里添加你需要的头文件,如#include"tchart.h"。这样在具体设置时就可以直接用“.”了,而且成员函数比较好找。例如:
m_tchart.GetHeader().GetText().Clear();
m_tchart.GetHeader().GetText().Add(_variant_t("MyTest"));
m_tchart.GetHeader().GetFont().SetBold(TRUE);
m_tchart.GetHeader().GetFont().SetSize(20);
但是我觉得这样显得工程比较大。而且比如上面的getfont之后,如果须设置多项,还得重新从头“点”一遍,执行的时候也是从新获取一遍,觉得有点浪费资源。而且从代码长度看也没简便到哪去,可能好的一点就是不用去管get到的是个啥类型的变量了。