深入浅出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管线 ...
随机推荐
- JavaScript的数组详解
#转载请留言联系 创建数组 1.通过new Array()进行创建 var arr1=new Array(); 2.通过中括号进行创建 var arr2=[]; 计算数组的长度 var arr3=[' ...
- python多线程实现多任务
#转载请联系 1.什么是线程? 进程是操作系统分配程序执行资源的单位,而线程是进程的一个实体,是CPU调度和分配的单位.一个进程肯定有一个主线程,我们可以在一个进程里创建多个线程来实现多任务. --- ...
- KVM(三)I/O 全虚拟化和准虚拟化
在 QEMU/KVM 中,客户机可以使用的设备大致可分为三类: 1. 模拟设备:完全由 QEMU 纯软件模拟的设备. 2. Virtio 设备:实现 VIRTIO API 的半虚拟化设备. 3. PC ...
- 转载 Ofbiz 入门教程
1.Ofbiz 介绍: Ofbiz(http://www.ofbiz.org) 是 Open Source 的商务软件系统,充分利用了各优秀的的Open Source 项目,像 Tomcat, Ant ...
- 从dao层查出的数据到页面时数值都是零的异常
异常问题: IllegalArgumentException: argument type mismatch at cn.tedu.utils.BeanListHandler.handle(BeanL ...
- 通过Cookie来记住用户名出现乱码问题(URL编码)
在登录时,提交一个中文名的用户名到服务器并返回到客户端的Cookie中时, 这个过程会后台会报 java.lang.IllegalArgumentException (非法数据异常) -->在给 ...
- flutter演示项目:游侠客户端
使用flutter实现的游侠客户端. 还有一些页面没写,最主要的问题是无法解析html富文本. https://github.com/axel10/flutter_ali213_client_demo
- 洛谷——P1495 曹冲养猪
题目描述 自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把.举个例子,假如有 ...
- [Codeforces 15E] Triangle
Brief Introduction: 求从N出发,回到N且不包含任何黑色三角的路径数 Algorithm:假设从N点到第二层中间的节点M的路径数为k,易知总路径数为(k*k+1)*2 而从第第四层开 ...
- SD 一轮集训 day1 carcar
可以发现每条边只能选一次或者两次,并且最后每个点的度数(∑邻接边选的次数和)都是偶数(代表有欧拉回路). 然后根据题意列一个 n 行 m+1 列的01矩阵,每一行代表一个异或方程组(每个点的度数是偶数 ...