绘图控件TeeChart应用——绘制2D、3D实时曲线

原创|使用教程|编辑:龚雪|2015-06-12 10:33:36.000|阅读 2663 次

概述:网上的TeeChart控件部分文档资料十分零碎,且很多不全面,代码难以使用。作者苦寻数周在外国一些网站上寻到了一些有用的信息,把相关的可运行的代码示例贴在文中,希望能帮到后来者。

# 聚惠初夏 ·DevExpress、Aspose、MyEclipse等知名产品 送技术支持/VIP资源/无门槛优惠券 >>

相关链接:

最近接手了一个项目,其中涉及到MFC和实时曲线显示的问题,由于我之前从未接触过此类技术,现学现搞,把其间用到的觉得对初学者有用的东西,总结一下。

尤其是关于TeeChart控件部分,网上资料零碎,且很多不全面,代码难以使用。我苦寻数周在外国一些网站上寻到了一些有用的信息,把相关的可运行的代码示例贴在文中,希望能帮到后来者。

MFC部分:

一、分割窗体

新建一个单文档的MFC工程(注意在向导中设置窗口最大化和分割窗口支持)。

新建两个对话框,用于分割窗口。

【注意】对话框的样式(Style)属性改为下层(Child),边框(Border)属性改为None,最开始没有改这个,程序运行的时候报错了。

【注意】将两个对话框生成从CFormView派生的类。

在CMainFrame的OnCreateClient中添加

【例1】把框架分割成两列,右边的一列和对话框绑定。

m_SplitterWnd.CreateStatic(this,1,2)); //把此框架窗口分割成1行2列。  
m_SplitterWnd.SetColumnInfo(0, 200, 0) ; //设置第0列的最大宽度为200,最小宽度为0 (此句话非常重要)  
CRect rect;  
GetClientRect(&rect);  
   
   //第1行第1列的窗口与CMyView绑定。其宽度为框架宽度的3/4.高度与框架的高度一致  
if(!m_SplitterWnd.CreateView(0,0,RUNTIME_CLASS(CMyView),CSize(rect.Width()/4*3,rect.Height()),pContext)||  
   //第1行第2列的窗口与我们的对话框CMyDlg绑定。其宽度为框架宽度的1/4.  
  !m_SplitterWnd.CreateView(0,1,RUNTIME_CLASS(CMyDlg),  
                         CSize(rect.Width()/4,rect.Height()),pContext))  
{    
   return FALSE;  
}  
   
return TRUE; 

【例2】在分割后的子窗口上继续分割

在CMainFrame中添加两个成员变量,类型为CSplitterWnd,如下所示

CSplitterWnd m_splitterWnd1;

CSplitterWnd m_splitterWnd2;

添加虚函数virtualBOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);

程序代码修改部分如下:

BOOLCMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)  
{  
   //创建一个静态分栏窗口,分为一行二列  
   if(m_splitterWnd1.CreateStatic(this,1,2)==NULL)  
        return FALSE;  
   
   //设置分割窗口的大小***  
   m_splitterWnd1.SetColumnInfo(0, 200, 0) ; //设置第0列的最大宽度为200,最小宽度为0  
   
   //将CCSplitterWndView连接到0行0列窗格上  
   m_splitterWnd1.CreateView(0,0,RUNTIME_CLASS(CsplitterwndView),CSize(600,500),pContext);  
   
   //将第0行1列再分开2行1列  
   if(m_splitterWnd2.CreateStatic(&m_splitterWnd1,2,1,WS_CHILD|WS_VISIBLE,  
       m_splitterWnd1.IdFromRowCol(0, 1))==NULL)  
       return FALSE;  
   
   //将FormView1类连接到第二个分栏对象的0行0列  
   m_splitterWnd2.CreateView(0,0,RUNTIME_CLASS(CForm1),CSize(0,300),pContext);//因为是上下分割,故系统不关注宽度,只看高度,故宽度可以为0  
   
   //将FormView2类连接到第二个分栏对象的1行0列  
   m_splitterWnd2.CreateView(1,0,RUNTIME_CLASS(CForm2),CSize(0,0),pContext);  //此高度为0,意为分割后剩下的高度 就是它的了。  
   return TRUE;  
}  
//CsplitterwndView、CForm1、CForm2都是我们自定义的类,可以把他们换成对话框或表单等。  

//初始左右分割框架,要调用函数SetColumnInfo来设定分割线位置。

对分割出来的一列再进行分割,则是由CreateView中CSize的高度来确定分割线位置。

*总结:

* 给框架窗口添加静态拆分视图的过程如下:

*  1. 给框架窗口类添加一个CsplitterWnd数据成员。  

*  2. 覆盖框架窗口的OnCreateClient函数,并调用CsplitterWnd::CreateStatic来创建静态拆分视图。        

*  3. 使用CsplitterWnd::CreateView在每个静态拆分窗口的窗格中创建视图

*  使用静态拆分窗口的一个优点是由于您自己给窗格添加视图,所以可以控制放入视图的种类

二、添加自定义消息响应

1、在Resource.h中添加

#define WM_MY_MESSAGE (WM_USER+100)

2、在CMyView的定义中添加:     //CMyView是要响应自定义消息的我们的视图类

//{{AFX_MSG(CMyView)

afx_msg LRESULT OnMyMsg(WPARAM, LPARAM) ;

DECLARE_MESSAGE_MAP()

//}}AFX_MSG

3、在CMyView的实现cpp文件中添加

BEGIN_MESSAGE_MAP(CMyView, CFormView)

   //{{AFX_MSG_MAP(CMyView)

   ON_MESSAGE(WM_MY_MESSAGE, OnMyMsg) //添加消息映射

   //}}AFX_MSG_MAP

END_MESSAGE_MAP()

4、实现消息映射函数LRESULT CMyView::OnMyMsg(WPARAM wParam, LPARAM lParam)

5、发送消息,触发消息响应函数

pMyView->PostMessage(WM_MY_MESSAGE,0, 0);    //至于PostMessage和SendMessage的区别 请百度之。

 //pMyView是CMyView类对象的指针。

TeeChart部分

(以VC++6.0  TeeChart8.0为例)

至于如何获取TeeChart控件,如何注册控件,请百度之,网上有很多。

在相应的源文件中添加TeeChart的头文件 (有需要的自己再添加)

#include "tchart.h"

#include "series.h"

#include "valuelist.h"

#include "axes.h"

#include "axis.h"

#include "pen.h"

#include "axislabels.h"

#include "teefont.h"

#include "axistitle.h"

#include "aspect.h"

#include "fastlineseries.h"

#include "titles.h"

#include "fastlineseries.h"

#include "panel.h"

#include "legend.h"

#include "annotationtool.h"

#include "page.h"

#include "strings.h"

#include "gradient.h"

#include "IsoSurfaceSeries.h"

 

一、在视图类中动态添加TeeChart控件

(解决手工拖动添加控件,编译报”Debug Assertion Failed” 错的问题)

我们添加对话框资源让其继承自CFromView。首先手工静态把控件拖到对话框上,然后建立类向导,生成一个对象m_chart。

在主框架CMainFrame::OnCreateClient()或OnCreate()中【看在哪个函数中分割窗口 产生视图】

   RecalcLayout();           //这一句很重要,没有它,会报错。

   pView->OnInitialUpdate(); //pView是我们分割窗口得到的CMyDlgView视图的指针。

在视图类CMyDlgView中添加OnInitialUpdate()函数

   CRect rect;

   GetClientRect(&rect);  

   m_chart.MoveWindow(&rect, TRUE);

在视图类CMyDlgView中添加WM_CREATE消息响应函数OnCreate()在其中添加

       m_chart.Create("",WS_VISIBLE, CRect(0, 0, 0, 0), this, 1234) ;//动态生成控件

       m_chart.AddSeries(0);//操作控件

       m_chart.Series(0).FillSampleValues(50);

//m_chart是我们的控件TeeChart

即可。

//但此为动态添加的控件,所有设置操作都得通过代码操作。

 

二、绘制2D曲线

这个在网上有很多资料了。我在这里再简单总结一下其过程。

A、初始化部分:

在TeeChart控件所在的视图类的OnCreate函数中,进行TeeChart控件的初始化工作。

m_chart.Create("",WS_VISIBLE, CRect(0, 0, 0, 0), this, 1234) ; //动态创建TeeChart控件  
m_chart.GetLegend().SetVisible(false);//隐藏图例  
m_chart.GetAspect().SetView3D(FALSE);  //取消3D显示  
  
//设置图标标题  
m_chart.GetHeader().GetText().SetItem(0,COleVariant("传感器实时数据曲线"));  
//设置纵轴标题  
m_chart.GetAxis().GetLeft().GetTitle().SetCaption("数值");  
  
//设置渐变背景  
m_chart.GetPanel().GetGradient().SetVisible(true);  
m_chart.GetPanel().GetGradient().SetStartColor(RGB(192,192,192));  
m_chart.GetPanel().GetGradient().SetEndColor(RGB(255,255,255));  
  
//添加曲线  
m_chart.AddSeries(0);  
  
//设置曲线属性  
m_chart.Series(0).SetColor(RGB(255,0,0));//颜色  
m_chart.Series(0).GetAsLine().GetLinePen().SetWidth(2); //线型宽度  
  
//设置x轴的取值范围  
m_chart.GetAxis().GetBottom().SetMinMax(0,100);  
//设置x轴上值的格式  
m_chart.GetAxis().GetBottom().GetLabels().SetValueFormat("0.0");  

B、绘制部分:

在TeeChart控件所在的视图类的自定义消息响应函数OnMyMsg中,或是在定时器中,添加:

COleDateTimeCurTime = COleDateTime::GetCurrentTime();  
COleDateTimeSpantmSpan = COleDateTimeSpan(0,0,1,0); //1s  
CStringcsTime ;  
csTime= CurTime.Format("%H:%M:%S"); //获取当前时间  
  
//在CMyView中画曲线  
m_chart.Series(0).Add(yVal, csTime,RGB(255,0,0)); //第一个参数是y轴值,第二个参数是对应的x轴的标签值(此为当前时间字符串),第三个参数是所绘点的颜色。  
CurTime+= tmSpan;  
  
m_chart.Series(0).RefreshSeries();  
if(m_chart.Series(0).GetCount() > 100)  
{  
  m_chart.GetAxis().GetBottom().Scroll(1.0,true); //x坐标轴一次移动1格  
} 

 

由于TeeChart绘制曲线点的函数Add,每调用一次才绘制一次,故需要有外部消息激发消息响应函数,才能把曲线动态绘制出来。

可以用设置定时器和自定义消息响应函数的方式来实现。(定时器比较简单,消息响应函数上面MFC部分已经讲过)

teechart教程

三、绘制3D曲线

解决TeeChart8中绘制3D图形报”Invalid class typecast” 错的问题。

A、在承载TeeChart的对话框类Dlg的类定义中,添加:VARIANT SeriesIndex;

B、在类的相关方法中绘制,添加代码:

m_chart.RemoveAllSeries();

//下面的设置很重要(没有的话,会出错)

SeriesIndex.vt=VT_INT;

SeriesIndex.intVal=m_chart.AddSeries(scWaterfall);//scWaterfall=33瀑布图的编号

m_chart.Series(0).GetAsWaterfall().SetIrregularGrid(true);

m_chart.Series(0).GetAsWaterfall().AddXYZ(x,y, z, NULL, RGB(255,0,0));

 

(TeeChart的3D图有很多种,上面是以瀑布图为例的,其他图种的编号如下:)

const unsigned long scLine = 0;

const unsigned long scBar = 1;

const unsigned long scHorizBar = 2;

const unsigned long scArea = 3;

const unsigned long scPoint = 4;

const unsigned long scPie = 5;

const unsigned long scFastLine = 6;

const unsigned long scShape = 7;

const unsigned long scGantt = 8;

const unsigned long scBubble = 9;

const unsigned long scArrow = 10;

const unsigned long scCandle = 11;

const unsigned long scPolar = 12;

const unsigned long scSurface = 13;

const unsigned long scVolume = 14;

const unsigned long scErrorBar = 15;

const unsigned long scBezier = 16;

const unsigned long scContour = 17;

const unsigned long scError = 18;

const unsigned long scPoint3D = 19;

const unsigned long scRadar = 20;

const unsigned long scClock = 21;

const unsigned long scWindRose= 22; 

const unsigned long scBar3D = 23; 

const unsigned long scImageBar = 24; 

const unsigned long scDonut = 25;

const unsigned long scTriSurface = 26;

const unsigned long scBox = 27;

const unsigned long scHorizBox = 28;

const unsigned long scHistogram = 29;

const unsigned long scColorGrid = 30;

const unsigned long scBarJoin = 31;

const unsigned long scHighLow = 32;

const unsigned long scWaterfall = 33;

const unsigned long scSmith = 34;

const unsigned long scPyramid = 35;

const unsigned long scMap = 36;

const unsigned long scHorizLine = 37;

const unsigned long scFunnel = 38;

const unsigned long scCalendar = 39;

const unsigned long scHorizArea = 40;

const unsigned long scPointFigure = 41;

const unsigned long scGauge = 42;

const unsigned long scVector3D = 43;

const unsigned long scTower = 44;

const unsigned long scPolarBar = 45;

const unsigned long scBubble3D = 46;

const unsigned long scHorizHistogram = 47;

const unsigned long scVolumePipe = 48;

const unsigned long scIsoSurface = 49;

const unsigned long scDarvas = 50;

const unsigned long scHighLowLine = 51;

const unsigned long scPolarGrid = 52;

const unsigned long scDeltaPoint = 53;

const unsigned long scImagePoint = 54;

const unsigned long scOrganizational = 55;

const unsigned long scWorld = 56;

const unsigned long scTagCloud = 57;

const unsigned long scKagi = 58;

const unsigned long scRenko = 59;

const unsigned long scNumericGauge = 60;

const unsigned long scLinearGauge = 61;

const unsigned long scCircularGauge = 62;

const unsigned long scBigCandle = 63;

const unsigned long scLinePoint = 64;

 

//如需要相关图种,只需把上面代码

SeriesIndex.intVal= m_chart.AddSeries(scWaterfall);//把scWaterfall改为你所需图种的编号

m_chart.Series(0).GetAsWaterfall().SetIrregularGrid(true);// GetAsWaterfall改为你所需图种的相关函数名

----------------

一个完整的例子:

A、在CMyView(承载TeeChart的对话框视图)的定义中,添加VARIANTSeriesIndex;

B、在int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)函数中:  

int CMyView::OnCreate(LPCREATESTRUCTlpCreateStruct)  
{  
       if(CFormView::OnCreate(lpCreateStruct) == -1)  
              return-1;  
        
       //TODO: Add your specialized creation code here  
       m_chart.Create("",WS_VISIBLE, CRect(0, 0, 0, 0), this, 1234) ;  
       m_chart.GetLegend().SetVisible(false);//隐藏图例  
       m_chart.GetAspect().SetView3D(true);  //3D显示  
   
       m_chart.GetAxis().GetDepth().SetVisible(TRUE);  //显示Z轴  
       m_chart.GetAxis().GetDepth().GetLabels().SetVisible(TRUE);  //显示Z轴上的坐标  
       m_chart.GetAxis().GetDepth().GetLabels().SetStyle(0);  //设置显示坐标的风格  
   
       //设置渐变背景  
       m_chart.GetPanel().GetGradient().SetVisible(true);  
       m_chart.GetPanel().GetGradient().SetStartColor(RGB(192,192,192));  
       m_chart.GetPanel().GetGradient().SetEndColor(RGB(255,255,255));  
   
       //设置图标标题  
       m_chart.GetHeader().GetText().SetItem(0,COleVariant("瀑布图"));  
   
       //开始绘制3D  
       m_chart.RemoveAllSeries();  
   
       SeriesIndex.vt=VT_INT;  
       SeriesIndex.intVal=m_chart.AddSeries(49);// 49号图种,IsoSurface类型3D  
   
       m_chart.Series(0).GetAsIsoSurface().SetIrregularGrid(true);  
   
       //设置曲线颜色  
       m_chart.Series(0).SetColor(RGB(255,0,0));  
   
       m_chart.GetAxis().GetBottom().SetMinMax(0,100);  
       m_chart.GetAxis().GetBottom().GetLabels().SetValueFormat("0.0");  
   
       m_chart.GetAspect().SetChart3DPercent(30);//调整3D纵深比  
        
       return0;  
}  
 

C、在自定义的消息处理函数中:

LRESULT CMyView::OnMyMsg(WPARAM wParam,LPARAM lParam)  
{  
       staticdouble xVal = .0 ;  
       doubleyVal = .0 ;  
       CTSDoc* pDoc =  (CTSDoc*)(this->GetDocument()) ;  
       yVal= pDoc->clientDataBuff[0] ;  
   
       for(int zVal=0; zVal<50; zVal++)  
       m_chart.Series(0).GetAsIsoSurface().AddXYZ(xVal,yVal, (double)zVal,  
                                                NULL,RGB(255,(int)(yVal*30)+160,0));  
       m_chart.Series(0).RefreshSeries();  
       if(m_chart.Series(0).GetCount() > 100)  
       {  
         m_chart.GetAxis().GetBottom().Scroll(1.0,true); //坐标轴一次移动1格  
       }  
   
       xVal++;  
       return0 ;  
}  

   

teechart教程

四、用AddArray一次把数组中的值绘制出来

1、先在TeeChart所在的类中 添加:

COleSafeArray XValues;

COleSafeArray YValues;

 

2、再在TeeChart的初始化设置函数添加:

DWORD numElements[] = {200000};  
   
// Create the safe-arrays...  
XValues.Create(VT_R8, 1, numElements);YValues.Create(VT_R8,1, numElements);  
   
// Initialize them with values...  
long index;  
for(index=0; index<200000; index++) {  
   double val = (double)index;  
   XValues.PutElement(&index, &val);  
};  
          
for(index=0; index<200000; index++) {  
   double val = rand()%100;  
   YValues.PutElement(&index, &val);  
};

3、在相应的位置添加:

m_chart.Series(0).AddArray(200000,YValues,XValues);

菜鸟的自留地


标签: teechart

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问

2.2 Sketch视频教程:创建、保存和管理文档

SOLIDWORKS中运用“远程载荷”功能简化零部件| 操作视频

报表控件Wyn Enterprise使用教程:折线图和面积图使用详解

TeeChart Pro VCL/FMX自动数据导入

TeeChart for .NET绘制开发人员图

如何使用Teechart和MySQL从Delphi绘制折线图?

相关产品
  • 产品类型:控件
  • 产品功能:图表
  • 源 码:非开源
  • 产品编号:10607
  • 当前版本: v2024.0.4.18 [销售以商家最新版为准,如需其他版本,请来电咨询]
  • 开 发 商: Steema 正式授权
  • ">TeeChart Pro ActiveX

    交互性强的轻量级ActiveX图表控件,能高效生成多任务仪表板

  • 产品类型:控件
  • 产品功能:图表
  • 源 码:非开源
  • 产品编号:10608
  • 当前版本: v2024.40.24 [销售以商家最新版为准,如需其他版本,请来电咨询]
  • 开 发 商: Steema 正式授权
  • ">TeeChart Pro VCL/FMX

    支持RAD Studio,Delphi和C ++ Builder以及FireMonkey的图表制作工具

  • 产品类型:控件
  • 产品功能:图表
  • 源 码:非开源
  • 产品编号:11142
  • 当前版本: v3.2021.0804 [销售以商家最新版为准,如需其他版本,请来电咨询]
  • 开 发 商: Steema 正式授权
  • ">TeeChart for Java

    适用于所有主流Java编程环境的TeeChart图表库

  • 产品类型:控件
  • 产品功能:图表
  • 源 码:非开源
  • 产品编号:12009
  • 当前版本: 2019.12.04.000 [销售以商家最新版为准,如需其他版本,请来电咨询]
  • 开 发 商: Steema 正式授权
  • ">TeeChart for PHP

    一款含100%的PHP源代码并支持PHP5及更高的版本的图表开发工具

  • 产品类型:控件
  • 产品功能:图表
  • 源 码:非开源
  • 产品编号:12551
  • 当前版本: v2024.3.15 [销售以商家最新版为准,如需其他版本,请来电咨询]
  • 开 发 商: Steema 正式授权
  • ">TeeChart for .NET

    优秀的工业4.0 WinForm图表控件,官方独家授权汉化,集功能全面、性能稳定、价格实惠等优势于一体

    最新文章 MORE
    • 1 TeeChart for .NET图表控件教程二:填充数据系列
    • 2 图表控件TeeChart for .NET系列教程四:轴控制(中)
    • 3 图表控件TeeChart Pro ActiveX v2023发布|附新版下载
    • 4 图表控件TeeChart for .NET系列教程六:将数据添加到系列中(使用系列)
    • 5 TeeChart图表控件许可常见问题解答
    相关文章 MORE
    • 「Java开发指南」如何使用Spring注释器实现Spring控制器?(二)
    • DevExpress WPF中文教程:Grid - 如何将更改发布到数据库(设计时)?
    • 「Qt Widget中文示例指南」如何实现一个滑动条(一)
    • 「实战应用」如何用DHTMLX将上下文菜单集成到JavaScript甘特图中(一)
    • 「实战应用」如何用图表控件LightningChart JS创建SQL仪表板应用(二)
    title
    title
    业务系统定制
    
    在线咨询
    联系我们

    客服热线
    023-68661681

    QQ客服

    意见反馈


    添加微信获专业服务

    TOP
    在线客服系统
    live chat

    聚圣源武汉宝宝起名财起名字好意义的起名成语银三角是哪三个国家诗词词大全起名字魔兽版本转换器1.26烧烤店免费起名折服的意思华夏起名网服装公司起名有内涵的饰品起名店家生产管理软件环保工程有限公司起名起个园林公司名称聊斋传奇psv仙境传说关闭休眠indeed.com萨满图腾任务程潇身高他比晚风还温柔正能量句子念你插翅难飞欧阳男孩起名2020年林姓起名哪里有免费起名字的雷蛇鼠标垫2014属马的女孩起什么名字白羊座武侠开端淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费

    聚圣源 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化