深入浅出CChart 每日一课——快乐高四第六课 二丫的青梅,返璞归真之普通窗体多区域画图
有好些朋友给我反映,就是一个窗体中加入好几个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对象都处理一遍就能够了。
好了,如今下课喽。
最新文章
- Python3基础 列表乘一个整数 扩增列表
- java视频教程 Java自学视频整理(持续更新中...)
- VS2013快捷键大全
- session如何保存在专门的StateServer服务器中
- ubuntu14.04下配置使用openCV3.0
- Java操作Wrod文档的工具类
- #pragma pack(push,1)与#pragma pack(pop)
- day26 面向对象 单例模式总结
- 不支持iframe框架?出来吧pdf
- javascript 字符串与正则
- 移动端 去除onclick点击事件出现的背景色框
- Log4j的扩展RollingFileAppender、DailyRollingFileAppender
- 力扣(LeetCode)258. 各位相加
- bootstraptable学习(2)分页
- ActiveMQ demo
- Python 驱动 MongoDB 示例(PyMongo)
- 第三百七十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapyd部署scrapy项目
- 怎么查看CI,codeigniter的版本信息?想看某个项目中使用的CI具体是哪个版本,怎么查看?
- Golang教程:switch 语句
- java实现屏幕共享的小程序
热门文章
- [ Python - 15 ] win7安装paramiko问题总汇
- HDU-3374
- SQLAlchemy技术文档(中文版)-下
- hdu 5170(数学)
- 关于docker swarm有满满干货的一篇文章,讲了如何用service来作nginx负责proxy已级无缝升级策略
- [BZOJ4553][Tjoi2016&;Heoi2016]序列 cdp分治+dp
- .NET Core Runtime ARM32 builds now available
- C++指针和数组的区别(不能混用的情况)
- 大数据DMP画像系统(转载 简介-龙果学院)
- Linux查看内核信息或系统信息