MFC画折线图,基于x64系统

news2024/11/19 18:18:37

由于项目的需要,需要画一个折线图。

传统的Teechart、MSChart、HighSpeedChart一般是只能配置在x86系统下,等到使用x64系统下运行就是会报出不知名的错误,这个地方让人很苦恼。

我在进行配置的过程之中,使用Teechart将x86配置好了,可以正常使用,但是嫁接到x64系统下就不可以使用了。HighSpeedChart也是同样在x64系统下使用会出现如下错误,并且在进行设置x轴的时候,x轴类型只能是int类型,贼其难用。配置了半天结果x64位用不了,x64系统真的不建议使用上述控件方式。

经过长时间的思索,还是直接用代码画一个吧,配置环境过于困难。

首先拉出一个Picture Control控件,然后将其ID进行更改为IDC_PIC_CTRL

在自己的.h文件之中进行定义变量

    CStatic m_PicCtrl2;
    CRect m_rect;

然后在相应的按钮下进行功能的定义(以依次修改按钮为例)

// TODO: 在此添加控件通知处理程序代码
int click = 6;
std::vector<CString> use;
std::vector<std::string> xAxisLabels = { "0"};
std::vector<double> yAxisValues = { 0 };




void CMFCApplication2Dlg::OnBnClickedButton5()
{
	
	CPaintDC dc(this); // 使用设备上下文绘制

					   // 清空窗口
	CRect rect;
	GetClientRect(&rect); // 获取绘制区域大小
	dc.FillSolidRect(rect, RGB(255, 255, 255)); // 填充白色背景

												// 绘制图形的代码
												// ...
	CWnd* pWnd = GetDlgItem(IDC_PIC_CTRL); // 获取Picture Control的指针
	pWnd->GetClientRect(&rect); // 获取绘制区域大小

	CDC* pDC = pWnd->GetDC(); // 获取绘图设备上下文

							  // 绘制背景
	pDC->FillSolidRect(rect, RGB(255, 255, 255));


	// 设置坐标轴参数
	int marginX = rect.Width() / 8.0;
	int marginY = rect.Height() / 8.0;


	time_t now = time(0);
	tm* localTime = localtime(&now);
	char buffer[80];
	strftime(buffer, 80, "%Y-%m-%d 仰角角度测量试验", localTime);
	CString cstringTime(buffer);

	CString chartTitle = (cstringTime) ;

	
	CString xAxisTitle = _T("时间(时:分:秒)");
	CString yAxisTitle = _T("角度(°)");
	// 绘制横轴线和纵轴线
	pDC->MoveTo(rect.left + marginX + 3, rect.bottom - marginY * 1.5);
	pDC->LineTo(rect.right - marginX, rect.bottom - marginY * 1.5);
	pDC->MoveTo(rect.left + marginX, rect.top + marginY * 1.5);
	pDC->LineTo(rect.left + marginX, rect.bottom - marginY * 1.5 - 3);


	// 绘制箭头线
	/*
	pDC->MoveTo(rect.right - marginX, rect.bottom - marginY * 1.5);
	pDC->LineTo(rect.right - marginX - 6.0, rect.bottom - marginY * 1.5 - 6.0);
	pDC->MoveTo(rect.right - marginX, rect.bottom - marginY * 1.5);
	pDC->LineTo(rect.right - marginX - 6.0, rect.bottom - marginY * 1.5 + 6.0 );
	*/
	

	
	
	

	// 绘制坐标轴标题
	pDC->SetBkMode(TRANSPARENT);

	// 设置大标题文本颜色
	pDC->SetTextColor(RGB(0, 0, 255)); // 深蓝色
	// 设置大标题文本粗细
	CFont font;
	font.CreateFont(16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("Arial")); // 创建一个16像素的粗体Arial字体

	pDC->SelectObject(&font); // 设置字体


	pDC->TextOut(rect.Width() / 2, rect.bottom - marginY * 0.5, chartTitle);//大标题

	// 设置大标题文本颜色
	pDC->SetTextColor(RGB(0, 0, 0)); // 黑色
	pDC->TextOut(rect.left + (double)marginX * 7.2, rect.bottom - marginY * 1.6, xAxisTitle);//x轴标题
	pDC->TextOut(rect.left + marginX - 30, rect.top + marginY / 2, yAxisTitle);//Y轴标题


	//std::vector<std::string> xAxisLabels = { "0","北京", "上海", "南京" };
	//std::vector<double> yAxisValues = { 0,0.2, 0.5, 1.8 };
	std::string currentTime = getCurrentTimeAsString();
	//点击次数增加
	if (yAxisValues.size() == 1)
	{
		xAxisLabels.push_back(currentTime);
		
		
			
		yAxisValues.push_back(2.2);
	}
	else if (yAxisValues.size() == 2)
	{
		xAxisLabels.push_back(currentTime);
		yAxisValues.push_back(4.2);
	}
	else if (yAxisValues.size() == 3)
	{
		xAxisLabels.push_back(currentTime);
		yAxisValues.push_back(1.2);

	}
	else if (yAxisValues.size() == 4)
	{
		xAxisLabels.push_back(currentTime);
		yAxisValues.push_back(2.2);
	}
	else if (yAxisValues.size() == 5)
	{
		xAxisLabels.push_back(currentTime);
		yAxisValues.push_back(6.2);
	}
	else if (yAxisValues.size() == 6)
	{
		xAxisLabels.push_back(currentTime);
		yAxisValues.push_back(5.2);
	}
	else
	{
		//当点击次数大于六次
		xAxisLabels.erase(xAxisLabels.begin());
		yAxisValues.erase(yAxisValues.begin());
		xAxisLabels.push_back(currentTime);
		yAxisValues.push_back(8.2);
	}

	int numPoints = yAxisValues.size();
	int xInterval = (rect.Width() - 2 * marginX) / (numPoints - 1);//x轴间隔
	int yInterval = (rect.Height() - 2 * marginY) / (13 - 1);//y轴间隔   这个地方的是纵轴的最大数量

	// 绘制横轴标签刻度
	for (int i = 0; i < numPoints; i++)
	{
		int x = rect.left + marginX + i * xInterval;
		CPen pen;
		pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 210)); // 创建一个红色的实线画笔
		pDC->SelectObject(&pen); // 设置画笔
		
		pDC->MoveTo(x, rect.bottom - marginY * 1.5); //横轴小标记
		pDC->LineTo(x, rect.bottom - marginY * 1.5 + 5);
		pDC->TextOut(x - 10, rect.bottom - marginY * 1.5 + 10, CString(xAxisLabels[i].c_str()));
	}

	//将最大的值进行/12操作,
	for (int i = 0; i < 13; i++)//重新绘制纵轴  这个地方的8是最大值
	{
		// 寻找最大值的迭代器
		auto maxIt = std::max_element(yAxisValues.begin(), yAxisValues.end());

		double maxValue;
		// 如果找到了最大值,则打印它
		if (maxIt != yAxisValues.end())
		{
			maxValue = *maxIt;
		}
		CPen pen;
		pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 210)); // 创建一个红色的实线画笔
		pDC->SelectObject(&pen); // 设置画笔

		double y = (double)(rect.bottom) - (double)marginY * 1.5 - ((double)10.0 / (double)12.0 * (double)i) * (double)yInterval; //根据实际大小进行设定  这个地方需要注意yInterval变量与
		pDC->MoveTo(rect.left + marginX, y);     //纵轴小标记
		pDC->LineTo(rect.left + marginX - 5, y);

		double value = (maxValue / (double)12.0) * (double)i; // 假设i是一个整数变量
		std::stringstream ss;
		ss << std::fixed << std::setprecision(4) << value;
		std::string strValue = ss.str();
		CString cstrValue(strValue.c_str());

		pDC->TextOut(rect.left + marginX * 0.8 - 30, y - 5, cstrValue);
	}

	// 绘制折线
	for (int i = 0; i < numPoints - 1; i++)
	{
		int x1 = rect.left + marginX + i * xInterval;
		int y1 = rect.bottom - marginY * 1.5 - (yAxisValues[i]*12.0/10.0) * yInterval;
		int x2 = rect.left + marginX + (i + 1) * xInterval;
		int y2 = rect.bottom - marginY * 1.5 - (yAxisValues[i + 1]*12.0/10.0) * yInterval;
		CPen pen;
		pen.CreatePen(PS_SOLID, 1, RGB(125, 0, 0)); // 创建一个红色的实线画笔
		pDC->SelectObject(&pen); // 设置画笔
		pDC->MoveTo(x1, y1);
		pDC->LineTo(x2, y2);
		pDC->SetTextColor(RGB(255, 0, 0)); // 深蓝色
		//绘制数值
		pDC->TextOut(x2 - 8, y2 - 20, CString(std::to_string(yAxisValues[i+1]).c_str()));//这个地方的标记需要变成4个小数点
	}

	


	pWnd->ReleaseDC(pDC);
}

在使用上述代码的时候需要进行头文件的引入


#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <atlstr.h>

#include <iostream>
#include <ctime>
#include <cstring>

#include <iostream>
#include <sstream>
#include <chrono>
using namespace std;

最后测试的展示情况是如下所示:

上述的依次添加按钮是按下一次,添加一个折现,只是个示例的过程,也可以改为实时动态的过程,只要添加个定时器就可以了,比较简单。关于界面部分,自己进行修改修改,进行美化一下就可以使用了。上述代码比较通俗易懂,按照自己的逻辑写的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1313448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

让测试效率起飞的8款浏览器兼容性测试工具,你get了吗?

浏览器的兼容性问题&#xff0c;是指不同浏览器使用内核及所支持的 HTML 等网页语言标准不同&#xff0c;用户客户端的环境不同造成的显示效果不能达到理想效果。 对于用户而言&#xff0c;无论使用哪款浏览器&#xff0c;期望看到的效果是正常的统一的。市面上发布的浏览器版…

CentOS 防火墙管理及使用的redis基本常用命令

文章目录 防火墙管理使用systemctl管理防火墙启动、关闭使用firewalld-cmd配置访问防火墙策略firewalld配置文件修改限制来源IP docker使用 redis 防火墙管理 需要关闭防火墙或者开启对应端口 使用systemctl管理防火墙启动、关闭 启动防火墙&#xff1a; systemctl start fi…

微服务实战系列之ZooKeeper(上)

前言 历经1个多月的创作和总结&#xff0c;纵观博主微服务系列博文&#xff0c;大致脉络覆盖了以下几个方面&#xff1a; 数据方面&#xff08;缓存&安全&#xff09; 比如Redis、MemCache、Ehcache、J2cache&#xff08;两级缓存框架&#xff09;、RSA加密、Sign签名…传…

【LSM tree 】Log-structured merge-tree 一种分层、有序、面向磁盘的数据结构

文章目录 前言基本原理读写流程写流程读流程 写放大、读放大和空间放大优化 前言 LSM Tree 全称是Log-structured merge-tree, 是一种分层&#xff0c;有序&#xff0c;面向磁盘的数据结构。其核心原理是磁盘批量顺序写比随机写性能高很多&#xff0c;可以通过围绕这一原理进行…

Redis 的常见使用场景

01 缓存 作为 Key-Value 形态的内存数据库&#xff0c;Redis 最先会被想到的应用场景便是作为数据缓存。而使用 Redis 缓存数据非常简单&#xff0c;只需要通过 string 类型将序列化后的对象存起来即可&#xff0c;不过也有一些需要注意的地方&#xff1a; 必须保证不同对象的…

面对.mkp病毒:专业咨询,文件恢复,帮您应对.mkp病毒

引言&#xff1a; 近期&#xff0c;网络上出现了一种新型的勒索病毒&#xff0c;被称为.halo。这种威胁采用高度复杂的加密算法&#xff0c;将用户的数据文件锁定&#xff0c;并要求支付赎金以解锁。本文将介绍.halo勒索病毒的特征、应对方法&#xff0c;以及如何预防此类攻击…

RabbitMQ插件详解:rabbitmq_web_stomp【RabbitMQ 六】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 《RabbitMQ Web STOMP&#xff1a;打破界限的消息传递之舞》 前言STOMP协议简介STOMP&#xff08;Simple Text Oriented Messaging Protocol&#xff09;协议简介STOMP与WebSocket的关系 WebSocket和R…

云原生之深入解析Kubernetes中服务的性能

一、Pyroscope 简介 ① 什么是 Pyroscope&#xff1f; 开发人员通常需要查看生产应用程序中的性能瓶颈以确定问题的原因&#xff0c;为此通常需要可以通过日志和代码工具收集的信息。不幸的是&#xff0c;这种方法通常很耗时&#xff0c;并且不能提供有关潜在问题的足够详细信…

PR模板,漂亮的文字帖子视频模板,方形标题PR项目工程文件下载

Premiere Pro模板&#xff0c;具有6个方形设计PR视频帖子标题文字PR项目工程文件。使用附带的颜色控制器调整和修改颜色&#xff0c;与您自己的品牌相匹配。使用这些效果来增强视频画面。包括视频教程。 适用软件&#xff1a;PR2019 | 分辨率&#xff1a;10801080&#xff08;方…

Android APP 常见概念与 adb 命令

adb 的概念 adb 即 Android Debug Bridge 。在窗口输入 adb 即可显示帮助文档。adb 实际上就是在后台开启一个 server&#xff0c;会接收 adb 的命令然后帮助管理&#xff0c;控制&#xff0c;查看设备的状态、信息等&#xff0c;是开发、测试 Android 相关程序的最常用手段。…

第P7周:咖啡豆识别(VGG-16复现)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](https://mp.weixin.qq.com/s/rbOOmire8OocQ90QM78DRA) 中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制](https://mtyjkh.blog.csdn.net/)** 一、前期工作 import …

Linux 常用命令----mktemp 命令

文章目录 基本用法实例演示高级用法注意事项 mktemp 命令用于创建一个临时文件或目录&#xff0c;这在需要处理临时数据或进行安全性测试时非常有用。使用 mktemp 可以保证文件名的唯一性&#xff0c;避免因文件名冲突而导致的问题。 基本用法 创建临时文件: 命令 mktemp 默认…

【IC验证】perl脚本——分析前/后仿用例回归情况

目录 1 脚本名称 2 脚本使用说明 3 nocare_list文件示例 4 脚本执行方法 5 postsim_result.log文件示例 6 脚本代码 1 脚本名称 post_analysis 2 脚本使用说明 help&#xff1a;打印脚本说明信息 命令&#xff1a;post_analysis help 前/后仿结束后&#xff0c;首先填…

餐饮品牌小红书探店怎么做?建议收藏

对于餐饮行业来说&#xff0c;消费者的口味和选择越来越多样化&#xff0c;如何在众多竞争者中脱颖而出&#xff0c;成为消费者的心头好&#xff0c;探店活动便应运而生。小红书作为国内知名的社交电商平台&#xff0c;拥有庞大的用户群体&#xff0c;特别是年轻人和美食爱好者…

多域名https证书购买选择

多域名https证书是一种特殊的SSL证书&#xff0c;它允许一个证书同时保护多个域名&#xff0c;并且不限制域名的类型&#xff0c;可以保护多个域名和子域名&#xff0c;确保网站传输信息时不被窃取、篡改。那么我们该怎么选择符合需求的多域名https证书呢&#xff1f;今天就随S…

Python神器:快速删除文本文件中指定行的方法

1. 简介 文件操作是编程中的重要方面。Python作为强大的编程语言&#xff0c;提供了处理文件的能力。删除特定行是文件处理中常见的需求。 2. 打开文件和读取内容 当打开文件并读取其内容时&#xff0c;open()函数和with语句是Python中常用的工具。以下是展示如何使用它们的…

由@EnableWebMvc注解引发的Jackson解析异常

同事合了代码到开发分支&#xff0c;并没有涉及到改动的类却报错。错误信息如下&#xff1a; Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.conv…

第1章:企业级研发测试流程

通过实际&#xff08;自研互联网&#xff09;企业的研发流程一览图。 我们发现分为9个阶段&#xff0c;当然每个公司细节并不一样。 所以我希望你能理解这句话&#xff1a; 一切的流程、行为、结果都是围绕“产品质量”这4个字开展活动。而作为测试&#xff0c;你该考虑的是如何…

数据结构与算法—查找算法(线性查找、二分查找、插值查找、斐波那契查找)

查找算法 文章目录 查找算法1. 线性查找算法2. 二分查找算法2.1 二分查找思路分析2.2 应用实例 3. 插值查找3.1 基本原理3.2 应用实例 4. 斐波那契4.1 基本原理4.2 应用实例 5. 查找总结 在java中&#xff0c;常用的查找有四种&#xff1a; 顺序(线性)查找二分查找/折半查找插值…

JS基本语法

JS基本语法 变量数据类型原始数据类型 函数定义第一种方式第二种方式 JS 对象ArrayStringJavaScript 自定义对象JSONDOMBOM JS 事件事件监听事件绑定常见事件 变量 数据类型 原始数据类型 函数定义 第一种方式 第二种方式 JS 对象 Array String JavaScript 自定义对象 JSON …