zoukankan      html  css  js  c++  java
  • 一个用于显示数值曲线的类

      最近在做一个课题,要显示几条数值曲线。不过不想借助其它控件,或其它公司提供的开发包,如MATCOM,用这些的话就太简单不过了。下面是一个自己设计的一个类,用API堆的,这样既可以在基于SDK应用开发应用,又可以在MFC框架中应用。下面几个图是测试时截的。在此声明一下,我是一新手,难免设计的不合理甚至错误百出,敬请见谅!点此下载源代码和示例代码

     



    图1  显示多条曲线


     

    图2 显示坐标提示
    图3 坐标系显示范围缩放
     
         
    类名为CChart,其基类为CChartBase。CChartBase主要用于显示,设置坐标系的一些属性,比如x,y轴可以显示的范围、坐标系边框颜色、背景颜色等;而CChart则用于显示坐标系和多条曲线,曲线颜色、线宽、等凡是可见的属性都可以设定。用法如下:
     
    1. 将DispChart.h和DispChart.cpp包含至用使用该类的Project中,若为基于MFC项目,则在DispChart.cpp中添加#include ”stdafx.h”。
    2. 定义一个该类的变量,CChart chart(hWnd); hWnd是该坐标所在窗口的句柄。
    3. (可选)设置相应的属性。如:
       
                 chart.SetGridColor(RGB(255,0,0));    // 设置网格颜色
                  chart.SetGriddx(10);                 // 设置网格x轴间隔
                  chart.SetClrLabel(RGB(0,0,255));     // 标尺颜色
                  chart.SetXLabel("t/min");            // 轴标文字
                  chart.SetYLabel("V/v");
                  chart.SetRulerXFormat("%.2f");       // x轴标尺显示精度
                  chart.SetGriddy( 0.01);
                  chart.SetXRange( 0, 100);            // x轴可以显示的范围
                 chart.SetYRange( -5, 5); 
     
    4. 添加曲线数据连接,曲线数据必须是vector<double>型的。如:
          std::vector<double> data[3];
          int length = 1000;
       double amp = 5;
       for(int i=0;i<length;i++)
       {
        double t = (20 * 3.1415926 / length) * i;
        double y1 = amp*sin(t);
        double y2 = (amp/2)*cos(t);
        data[0].push_back(t);
        data[1].push_back(y1);
        data[2].push_back(y2);
       }
        chart.AddMCurves(data,3);
        chart.SetCurveColor(0,RGB(0,0,0));

     
    5. 在WM_PAINT消息或其它地方绘制曲线。先设置显示在那个位置,然后绘制。
        
    case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    		// TODO: 在此添加任意绘图代码..
    		RECT rect;
    		GetClientRect(hWnd,&rect);
    
    		chart.SetChartDC(hdc);
     
    		chart.SetChartAndWindowPosition(rect);
    		
    		 chart.ShowCurves();
    
    		EndPaint(hWnd, &ps);
    		break;
     
    6. (可选)若要动态缩放、平移、左键点击显示坐标提示窗口、右键框选缩放,则只需在相应的消息处理处添加相关操作即可。注意:由于我是用该类绘制周期性的曲线的,所以平移和缩放只是x轴的;若要同时平移或缩放,在CChart::OnMouseWheel函数中将ScaleX改变为ScaleCenter即可以完成x,y轴同时缩放,在CChart::OnMouseMove函数中修改Move的第二参数为-(y - m_ptLeftButtonDown.y) * GetYPerPix()即可以完成x,y轴同时移动。
       if( m_ptLeftButtonDown.x != -1)
        {
     Move( -(x - m_ptLeftButtonDown.x) * GetXPerPix() , -(y - m_ptLeftButtonDown.y) * GetYPerPix());
        
     m_ptLeftButtonDown.x = x;
     m_ptLeftButtonDown.y = y;
     
    // 绘制曲线和坐标系
     ShowCurves();
     }
    示例代码:
    case WM_LBUTTONDOWN:
    		
    		chart.OnLeftButtonDown(LOWORD(lParam), HIWORD(lParam));
    		break;
    	case WM_LBUTTONUP:
    		chart.OnLeftButtonUp(LOWORD(lParam), HIWORD(lParam));
    		break;
    	case WM_RBUTTONDOWN:
    		chart.OnRightButtonDown(LOWORD(lParam), HIWORD(lParam));
    		break;
    	case WM_RBUTTONUP:
    		chart.OnRightButtonUp(LOWORD(lParam), HIWORD(lParam));
    		break;
    	case WM_MOUSEMOVE:
    		chart.OnMouseMove(LOWORD(lParam), HIWORD(lParam));
    		break;
    	case 0x020A/*WM_MOUSEWHEEL*/:
    		{
    			POINT pt = { LOWORD(lParam), HIWORD(lParam) };
    			ScreenToClient( hWnd,&pt );
    		    chart.OnMouseWheel(wParam, pt.x, pt.y);
    		}
    		break;
     
     
     头文件定义如下:
    #ifndef _DISPCHART_H
    #define _DISPCHART_H
    #include 
    #include 
    #include 
    
    // 图表基类:用于绘制坐标系和曲线
    class CChartBase
    {
    protected:
    	HDC       m_hChartDC;       // 图表绘制的DC
    	RECT      m_rtWindow;       // 坐标窗口,其中包含图表显示区和坐标标尺,轴标等    
    	RECT      m_rtChart;        // 图标显示区(依赖域m_rtWindow)
    
    	// 坐标显示边界
    	double    m_xStart;         // 实数域内x轴起点
    	double    m_xEnd;           //         x轴终点
    	double    m_yStart;         //         y轴起点
    	double    m_yEnd;           //         y轴终点
    
    	// 显示图表区
    	COLORREF  m_clrChartBg;     // 显示区背景色
    	COLORREF  m_clrChartBorder; //       边框色
    
    	// 网格
    	bool      m_bGridOn;        // 控制网格是否显示
    	double    m_dxGrid;         // 网格单元宽
    	double    m_dyGrid;         // 网格单元高
    	COLORREF  m_clrGrid;        // 网格线颜色
    
    	// 坐标轴,轴标,标尺
    	char      m_xLabel[20];
    	char      m_yLabel[20];
    	bool      m_bxLabelOn; 
    	bool      m_byLabelOn;
    
    	bool      m_bxRulerOn;
    	bool      m_byRulerOn;
    	char      m_szRulerXFormat[128];
    	char      m_szRulerYFormat[128];
    
    	COLORREF  m_clrLabel;      // 轴标文字和刻度文字颜色
    
    	// 文字字体
    	LOGFONT     m_logFont;
    
    	// 曲线数据
    
    public:
    
    	// 辅助函数
    	void SetChartDC(HDC hdc);
    	HDC  GetChartDC() const ;
    	void SetChartWindowPosition(RECT rect);
    	void SetChartWindowPosition(int left, int top, int right, int bottom);
    	RECT GetChartWindowPosition() const;
    	void SetChartPosition(RECT rect);
    	void SetChartPosition(int left, int top, int right, int bottom);
    
    	RECT GetChartPosition() const;
    	int  GetChartWidth()const  { return m_rtChart.right - m_rtChart.left ; };
    	int  GetChartHeight()const { return m_rtChart.bottom - m_rtChart.top ; };
    	int  GetChartWindowWidth() const { return m_rtWindow.right - m_rtWindow.left; };
    	int  GetChartWindowHeight() const{ return m_rtWindow.bottom - m_rtWindow.top; };
    
    	// 坐标显示边界
    	double SetXStart(double xStart);
    	double SetXEnd(double xEnd);
    	void   SetXRange(double xStart,double xEnd);
    	double SetYStart(double yStart);
    	double SetYEnd(double yEnd);
    	void   SetYRange(double yStart,double yEnd);
    	double GetXStart()const;
    	double GetXEnd()const;
    	double GetYStart()const;
    	double GetYEnd()const;
        
    	// 显示图表区
    	void      SetClrChartBg(COLORREF clr);
    	COLORREF  GetClrChartGb()const;
    	void      SetClrChartBorder(COLORREF clr);
    	COLORREF  GetClrChartBorder()const;
    
    	// 网格
    	double   SetGriddx(double dxGrid);              // 设置网格宽度,返回前一个值
    	double   SetGriddy(double dyGrid);              // 设置网格高度,返回前一个值
    	void     SetGridxy(double dxGrid,double dyGrid);
    	COLORREF SetGridColor(COLORREF color);          // 设置网格颜色,返回前一个值
    	void SetGridOn();                               // 设置网格为显示状态
    	void SetGridOff();                              // 设置网格为关闭状态
    
    	double   GetGriddx()const;
    	double   GetGriddy()const;
    	COLORREF GetGridColor()const;
    	bool     GetGridStatus()const;
    
    	// 坐标轴,轴标,标尺
    	void    SetXLabel(const char* xLabel);
    	void    SetYLabel(const char* yLabel);
    	void    SetXLabelOn();
    	void    SetXLabelOff();
    	BOOL    GetXLabelStatus()const;
    	void    SetYLabelOn();
    	void    SetYLabelOff();
    	BOOL    GetYLabelStatus()const;
    
    	void    SetXRulerOn();
    	void    SetXRulerOff();
    	BOOL    GetXRulerStatus()const;
    	void    SetYRulerOn();
    	void    SetYRulerOff();
    	BOOL    GetYRulerStatus()const;
    
    	void    SetRulerXFormat(const char str[]) { strcpy(m_szRulerXFormat, str);};
    	void    SetRulerYFormat(const char str[]) { strcpy(m_szRulerXFormat, str);};
    
    	void     SetClrLabel(COLORREF clr);
    	COLORREF GetClrLabel()const;
    
    	// 字体
    	void    SetLogFont(LOGFONT logFont);
    	LOGFONT GetLogFont()const;
    
    
    	// 每一个象素所代表的实数值
    	double GetYPerPix() const;
    	double GetXPerPix() const;
    
    protected:
    	int  ShowChartBg();
    	int  ShowGrid();
    	int  ShowRuler();
    	int  ShowLabel();
    
    public:
    	CChartBase();
    	~CChartBase();
    
    	int ShowAt(int left, int top, int right, int bottom); // 在rect中显示该图标窗口,外部最好用该函数
    	int ShowAt(RECT rect);
    	int Show();                                           // 通过设置各种参数显示
    
    	// 坐标转换 r--real  s--screen 2--to
    	int rx2sx(double rx);  
    	int ry2sy(double ry);
    	double sx2rx(int sx);
    	double sy2ry(int sy);
    
    	// 坐标变换
    	void Move(double drx, double dry);                   // 坐标系平移
    	void ScaleCenter(double times);                      // 坐标以坐标框的中心放缩
    	                                                     // times>1时,显示范围扩大,起到缩小的作用
    	                                                     // times<1时,显示范围缩小,起到放大的作用
    	void ScaleX(double times);                           // X轴范围缩放(以x轴中心)
    	void ScaleY(double times);                           // Y轴范围缩放(以y轴中心)
    };
    
    class CChart:public CChartBase
    {
    private:
    	HWND       m_hWnd;           // 图表所在的窗口,该窗口可以处理消息(用于实现坐标变换等)
    	HDC        m_memDCWindow;    // 存储整个绘图窗用的内存句柄
    	HBITMAP    m_bmpInDCWindow;  
    	HDC        m_memDCChart;     // 存储chart的内存设备句柄
        HBITMAP    m_bmpInDCChart;   // 图表所对应的位图句柄
    
    	// 曲线数据
    public:
    	
    	std::vector
  • 相关阅读:
    【JAVA笔记——道】JAVA对象销毁
    【JAVA笔记——道】并发编程CAS算法
    httpClientUtil的get请求
    python基础 day11 下 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 多对多关系 表结构设计作业
    python基础 day11 上 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 事务 索引 python 操作mysql ORM sqlachemy学习
    Python基础 Day10 Gevent协程 SelectPollEpoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 RedisMemcached缓存 Paramiko SSH Twsited网络框架
    python基础 day9 进程、与线程区别 python GIL全局解释器锁 线程 进程
    python基础 day8 Socket语法及相关 SocketServer实现多并发
    python基础 day7 面向对象高级语法部分 异常处理 异常处理 Socket开发基础
    python基础 day6 面向对象的特性:封装、继承、多态 类、方法、
  • 原文地址:https://www.cnblogs.com/mywolrd/p/1930723.html
Copyright © 2011-2022 走看看