深入浅出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对象都处理一遍就能够了。
好了,如今下课喽。
深入浅出CChart 每日一课——快乐高四第六课 二丫的青梅,返璞归真之普通窗体多区域画图的更多相关文章
- 深入浅出CChart 每日一课——快乐高四第九课 于无声处,CChart内置功能介绍之数据存取篇
笨笨长期以来一直使用Origin软件画图和处理数据,但Origin软件没有编程语言的接口.笨笨开发CChart的一个潜在的目标.是想实现Origin软件的功能.当然这是一个不可能达到的目标.Origi ...
- NeHe OpenGL教程 第四十六课:全屏反走样
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- 深入浅出CChart 每日一课——第十六课 实习之旅,百年老店之新锐WTL
上节课笨笨给大家介绍了CChart在微软MFC框架下的应用,本节课的内容仍然和百年老店微软相关,只不过主角换成WTL了. 不了解WTL的同学可以先找度娘温习一下.度娘在怀,今生何求.郎君啊,你是不是闷 ...
- 深入浅出CChart 每日一课——第十八课 女神的套娃,玩转对话框
前面笨笨已经给大家展示了CChart编程的N个例子.这些例子中,我们的CChart图像都是绘制在程序的主窗口中的. 在很多情况下,我们面对的情形不是这样的.这节课笨笨就给大家介绍一下怎样在对话框中用C ...
- 第四十六课:MVC和MVVM的开发区别
实现MVC的目的就是为了让M和V相分离.前端的MVC无法做到View和Model的相分离,而MVVM可以. 我们先来看一个用MVC模式开发的经典例子:(一定要深入了解这种开发的思想,而不是看懂代码) ...
- 潭州课堂25班:Ph201805201 django 项目 第四十六课 查错 补缺 (课堂笔记
从讲项目开始,查找错误,完善笔记,尽可能 翻译没一句代码(以后台为主), 本项目亮点,也是重点 Django ORM中对数据查询的优化(only.defer.select_related) redis ...
- python第四十六课——函数重写
3.函数重写(override) 前提:必须有继承性 原因: 父类中的功能(函数),子类需要用,但是父类中函数的函数体内容和我现在要执行的逻辑还不相符 那么可以将函数名保留(功能还是此功能),但是将函 ...
- JAVA学习第四十六课 — 其它对象API(二)Date类 & Calendar类(重点掌握)
Date类(重点) 开发时,会时常遇见时间显示的情况,所以必须熟练Date的应用 <span style="font-family:KaiTi_GB2312;font-size:18p ...
- NeHe OpenGL教程 第四十二课:多重视口
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
随机推荐
- Mysql启动服务提示系统找不到指定的文件
Mysql启动服务: C:\Windows\system32>net start mysql发生系统错误 2. 系统找不到指定的文件. 怎么还是报这个错?难道不是由于配置的原因?对,不是由于上面 ...
- Java 原子性引用 AtomicReference
http://www.jianshu.com/p/882d0e2c3ea6 实现 原子操作 使用场景: 一个线程使用student对象,另一个线程负责定时读表,更新这个对象.那么就可以用AtomicR ...
- python接口自动化11-post传data参数案例【转载】
前言: 前面登录博客园的是传json参数,有些登录不是传json的,如jenkins的登录,本篇以jenkins登录为案例,传data参数. 一.登录jenkins抓包 1.登录jenkins,输入账 ...
- mysql 保留点
例子如下: 在ticket表中先删除trainID=868的数据,设置一个保留点,然后插入一行数据,发现在插入数据插错了,这个时候我们的保留点就可以排上用场了,即rollback到保留点,而不是直接r ...
- System Center VMM请注意不同语言版本的差异
在私有云的项目中,经常需要判断System Center一些组件的连接是否OK. 我这里有开发,和测试两个环境,开发是英文版的System Center VMM,测试用的是中文版的System Cen ...
- 如何在Android Studio中创建jniLib和asset文件夹 2
1.创建asset文件夹 如图进行操作 2.创建jniLib文件夹 —打开app下面的gradle文件(不是project的gradle) —在gradle文件的Android标签里面添加 sourc ...
- Don't Be a Subsequence
问题 F: Don't Be a Subsequence 时间限制: 1 Sec 内存限制: 128 MB提交: 33 解决: 2[提交] [状态] [讨论版] [命题人:] 题目描述 A sub ...
- [BZOJ1095]捉迷藏
点了动态点分治的科技树,这道题是树形态不变的动态点分治,形态变化的话...待会补 考虑点分治过程中的这样一种结构:按递归层次把当前层的重心与上层重心互相连接,这就是点分治树,容易看出它的树高只有$O( ...
- 【分块】bzoj1858 [Scoi2010]序列操作
分块 Or 线段树 分块的登峰造极之题 每块维护8个值: 包括左端点在内的最长1段: 包括右端点在内的最长1段: 该块内的最长1段: 该块内1的个数: 包括左端点在内的最长0段://这四个是因为可能有 ...
- 【树状数组】bzoj2789 [Poi2012]Letters
处理数组A,A[i]表示字符串a的第i个字符排序后应去的位置,队列可. 对于多次出现的字符,其在a中的顺序和在b中的顺序应该是一一对应的. #include<cstdio> #includ ...