有好些朋友给我反映,就是一个窗体中加入好几个CChartWnd之后。工作不正常。这个的确是这样,CChartWnd会接管原来窗体的消息循环,加入多个CChartWnd之后,就相当于出租房转手好几道,消息循环乱套了。尽管道理上能够给二房东立规矩。但笨笨尚未想到一个万全之策,所以在眼下的状况下。请大家不要在一个窗体上Attach多个CChartWnd。

(笨笨注:上述描写叙述已经是老黄历了,新版本号的CChart已经实现了在一个窗体上多次Attach。只是这里的方法仍然很具有參考价值。

可是不是就不能在一个窗体的多个区域同一时候画图呢?非也非也。请不要忘了,CChartWnd的基础是CChart类,往往越是原始的东西功能就越强大。

以下笨笨就给大家简单示范一下利用CChart在单窗体的多个区域画图。计划分三种情况,即普通窗体,对话框窗体,duilib窗体。供大伙參考。

本课先介绍在普通窗体下分区域画图。

笨笨已经提供了一种分裂视图。实际就是一种分区域画图的方式。

但眼下分裂视图的各个子视图的类型是一样的。假设想在一个子视图画曲线图。还有一个子视图画饼图,笨笨仅仅能说抱歉了。

本课介绍的分区域画图能够克服这个缺点。

笨笨新近在CChart中添加了一种画图类型,就是等高线图和云图的合体版,顺便在本课一起介绍了。

本课的演示样例代码将在一个MFC窗体中分两块区域画图,一块绘制饼图,一块绘制等高线云图。

如今開始。

仍然以实例的形式。

第一步。打开VC。建立一个基于MFC AppWizard(exe)向导的项目LessonA06,向导中不做不论什么更改,直接点Finish。

第二步。拷贝库文件到LessonA06目录。

第三步,在VC中打开LessonA06View.h文件。在其头部加入例如以下代码。

#include "Chart.h"
#ifdef _DEBUG
# if defined(_UNICODE) || defined(UNICODE)
# pragma comment(lib, "PlotDll_ud.lib")
# else
# pragma comment(lib, "PlotDll_d.lib")
# endif
#else
# if defined(_UNICODE) || defined(UNICODE)
# pragma comment(lib, "PlotDll_u.lib")
# else
# pragma comment(lib, "PlotDll.lib")
# endif
#endif

第四步,在LessonA06View.h文件里,给CLessonA06View类加入两个CChart变量。

CChart m_Chart1, m_Chart2;

第五步,利用ClassWizard给CLessonA06View类加入OnCreate消息处理函数。并改动OnCreate函数例如以下。

int CLessonA06View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1; // TODO: Add your specialized creation code here
m_Chart1.SetType(kTypePie);
m_Chart1.AddPie(4, "王菲");
m_Chart1.AddPie(3, "张柏芝");
m_Chart1.AddPie(2, "Irene"); m_Chart2.SetType(kTypeContour);
m_Chart2.SetContourByPoints();
m_Chart2.AddContourPoint(-1, -1, 5);
m_Chart2.AddContourPoint(-1, 1, 5);
m_Chart2.AddContourPoint(1, -1, 5);
m_Chart2.AddContourPoint(1, 1, 5);
m_Chart2.AddContourPoint(-1, 0, -5);
m_Chart2.AddContourPoint(0, -1, -5);
m_Chart2.AddContourPoint(1, 0, -5);
m_Chart2.AddContourPoint(0, 1, -5);
m_Chart2.AddContourPoint(0, 0, 10);
m_Chart2.SetPlotRange(-1.5, 1.5, -1.5, 1.5);
m_Chart2.SetContourPrecision(8);
m_Chart2.SetContourLineNum(20);
m_Chart2.SetUseLegend(false); return 0;
}

这里请大家注意等高线云图的使用方法。

首先。它的代码是kTypeContour。

其次,画等高线云图和等高线图、云图一样,须要一个原型为double f(double x, double y);的场函数。

因为好几位朋友问到,他们仅仅有数据点,能不能画等高线图。一直在道理上都是能够的,就是须要编写一个场函数,在场函数里面用数据点插值即可。但这个可能比較麻烦。近期笨笨在CChart中内置了插值函数。採用双线性的方式插值。精度可能没有二次以上的方式的高,但够用即可吧。

注意到这一行了吗。

m_Chart2.SetContourByPoints();

这就是表示等高线採用笨笨内置的插值函数绘制,不须要再提供场函数。但须要提供数据点。提供数据点的函数例如以下。

void	CChart::AddContourPoint(double x, double y, double h);

当中x,y就是坐标,h是高度。

以下这个函数表示等高线的绘制范围。

void	CChart::SetPlotRange(double xl, double xu, double yl, double yu);

以下这个函数表示等高线的绘制精度,在曾经的课程中已经介绍了。

void	CChart:: SetContourPrecision (int precision);

以下这个函数表示等高线的绘制时的高度数,在曾经的课程中也已经出现了。

void	CChart::SetContourLineNum(int num);

等高线的新功能介绍就结束了。

第六步,重载OnSize函数例如以下。

void CLessonA06View::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here
CRect rect;
GetClientRect(&rect);
CRect rt1, rt2;
rt1 = rect;
rt1.right = (rect.left + rect.right)/2;
m_Chart1.SetConfineRect(rt1);
rt2 = rect;
rt2.left = (rect.left + rect.right)/2;
m_Chart2.SetConfineRect(rt2);
}

这里就是分配各个视图所占的窗体区域。在本例中。m_Chart1占领窗体的左半。m_Chart2占领窗体的右半。

主要须要利用到这个函数。

void CChart::SetConfineRect(RECT rect);

第七步。改动OnDraw例如以下。

void CLessonA06View::OnDraw(CDC* pDC)
{
CLessonA06Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
m_Chart1.OnDraw(pDC->m_hDC);
m_Chart2.OnDraw(pDC->m_hDC);
}

如今能够执行了,效果例如以下。

刚启动的时候可能有点慢。由于须要初始化等高线。

有同学要问了,鼠标没有反应呀?我们这里没有採用CChartWnd,所以须要自己处理消息。

第八步,重载OnLButtonDown,OnLButtonUp,OnLButtonDblClk。OnMouseMove,OnContextMenu,OnEraseBkgnd这几个函数,并改动例如以下。

void CLessonA06View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_Chart1.OnLButtonDownR(m_hWnd, point, nFlags);
m_Chart2.OnLButtonDownR(m_hWnd, point, nFlags);
} void CLessonA06View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_Chart1.OnLButtonUpR(m_hWnd, point, nFlags);
m_Chart2.OnLButtonUpR(m_hWnd, point, nFlags);
} void CLessonA06View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_Chart1.OnLButtonDblClkR(m_hWnd, point, nFlags);
m_Chart2.OnLButtonDblClkR(m_hWnd, point, nFlags);
} void CLessonA06View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_Chart1.OnMouseMoveR(m_hWnd, point, nFlags);
m_Chart2.OnMouseMoveR(m_hWnd, point, nFlags);
} void CLessonA06View::OnContextMenu(CWnd* pWnd, CPoint point)
{
// TODO: Add your message handler code here
m_Chart1.OnContextMenuR(NULL, m_hWnd, point);
m_Chart2.OnContextMenuR(NULL, m_hWnd, point);
} BOOL CLessonA06View::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
//return CView::OnEraseBkgnd(pDC);
}

消息响应回来了。!

大家能够比較一下这里和第15课里面消息响应代码的异同。

实际上。就是在各个消息的响应代码里面,把每一个CChart对象都处理一遍就能够了。

好了,如今下课喽。

最新文章

  1. Python3基础 列表乘一个整数 扩增列表
  2. java视频教程 Java自学视频整理(持续更新中...)
  3. VS2013快捷键大全
  4. session如何保存在专门的StateServer服务器中
  5. ubuntu14.04下配置使用openCV3.0
  6. Java操作Wrod文档的工具类
  7. #pragma pack(push,1)与#pragma pack(pop)
  8. day26 面向对象 单例模式总结
  9. 不支持iframe框架?出来吧pdf
  10. javascript 字符串与正则
  11. 移动端 去除onclick点击事件出现的背景色框
  12. Log4j的扩展RollingFileAppender、DailyRollingFileAppender
  13. 力扣(LeetCode)258. 各位相加
  14. bootstraptable学习(2)分页
  15. ActiveMQ demo
  16. Python 驱动 MongoDB 示例(PyMongo)
  17. 第三百七十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapyd部署scrapy项目
  18. 怎么查看CI,codeigniter的版本信息?想看某个项目中使用的CI具体是哪个版本,怎么查看?
  19. Golang教程:switch 语句
  20. java实现屏幕共享的小程序

热门文章

  1. [ Python - 15 ] win7安装paramiko问题总汇
  2. HDU-3374
  3. SQLAlchemy技术文档(中文版)-下
  4. hdu 5170(数学)
  5. 关于docker swarm有满满干货的一篇文章,讲了如何用service来作nginx负责proxy已级无缝升级策略
  6. [BZOJ4553][Tjoi2016&Heoi2016]序列 cdp分治+dp
  7. .NET Core Runtime ARM32 builds now available
  8. C++指针和数组的区别(不能混用的情况)
  9. 大数据DMP画像系统(转载 简介-龙果学院)
  10. Linux查看内核信息或系统信息