65.9K
CodeProject 正在变化。 阅读更多。
Home

2D 图表 ActiveX 控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (155投票s)

2002年11月20日

MIT

8分钟阅读

viewsIcon

1672586

downloadIcon

70423

用于 2D 数据可视化的 ActiveX 控件。

Sample Image - NTGraph_ActiveX.jpg

引言

这是一个简单的OCX控件,允许您绘制二维数据。尽管VC++附带了一套庞大的控件,但没有现成的控件可以提供简单明了的2D数据可视化。Kapil Chaturvedi撰写的ActiveX控件教程启发了我写自己的控件,主要是因为我想在需要时自定义源代码。随着时间的推移,ActiveX控件的功能变得越来越完善,最终我决定发布我手头的内容。

它能做什么?

该控件能够绘制大量点,并通过新数据更新图表中的一个或多个图,用新图替换旧图。可以实时自定义具有单独属性(如名称、线条和点样式、宽度)的多个图。在运行时,该控件能够显示自己的属性页(双击控件区域或调用ShowProperties方法),并在用户按下F1键时控件获得焦点时显示简短帮助。通过设置TrackMode属性,您应该能够在不同的模式之间切换,例如移动时跟踪光标坐标(按下鼠标左键)、缩放、XY平移、X平移和Y平移。最后,控件的快照可以复制到剪贴板、打印或保存为位图文件。

它不能做什么?

您不能绘制3D数据,但您可以使用NTGraph3D ATL/STL/OpenGL activeX控件来完成此操作!

有什么新功能?

  • 对数坐标轴模式现在可以工作,显示log10网格和适当的标签,它还转换图表元素的data
  • 控件的快照现在可以保存为位图文件,非常感谢Robert Harber提供代码!
  • 增加了动态创建注释标签的功能,这些标签可以具有不同的颜色、方向,并且可以隐藏或显示。
  • 增加了“Annotations”属性页,在实际/设计模式下提供对注释列表的完全访问。
  • 增加了动态绘制多个光标的功能,具有不同的颜色、十字线样式、浮动/固定或捕捉到当前选定的元素!
  • 增加了“Cursors”属性页,在实际/设计模式下提供对光标列表的完全访问。
  • 增加了坐标轴格式化功能,允许自定义底部和左侧坐标轴标签。
  • 增加了“Format”属性页,该属性页提供对坐标轴格式属性的访问,以及常用数据格式(如:数字、指数、符号、日期和时间)的模板!
  • 为图表坐标轴增加了时间格式。要使用它,您应该将 `XTime/YTime` 属性设置为 `True`。
    您还必须将日期/时间数据转换为 `double` 格式。日期/时间格式实现为浮点值,表示自1899年12月30日午夜以来的天数。因此,1899年12月31日午夜表示为1.0。同样,1900年1月1日早上6点表示为2.25,1899年12月29日午夜表示为1.0。然而,1899年12月29日早上6点表示为1.25。
    有关更多信息,请参阅MSDN关于类:`COleDateTime`!

如何测试控件

您可以使用ActiveX控件测试容器,并从“工具\宏...”菜单加载Test.dsm宏。您可以编写自己的例程来测试控件的行为(查看Test.dsm宏)。

如何使用该控件

要使用此OCX控件,请将其嵌入支持OCX控件使用的应用程序中。Microsoft Visual Basic应用程序、Office应用程序以及使用Microsoft Developer Studio的AppWizard创建的应用程序都可以支持OCX控件的使用。使用此控件需要两个文件。它们是
  • NTGraph.hlp - 此控件的帮助文件。
  • NTGraph.ocx - NTGraph控件的代码和数据。

在使用ActiveX控件之前,它必须在系统注册表中注册为COM组件。这是一个自注册控件。这意味着要将控件注册到系统注册表中,您只需要有一个应用程序加载该控件并调用控件导出的DllRegisterServer函数。您可以使用REGSVR32实用程序,或者让您的安装程序执行此操作。

如何使用REGSVR32实用程序?

将 *NTGraph.ocx* 复制到您的目录并键入

regsvr32 NTGraph.ocx
`regsvr32 /u NTGraph.ocx`(注销服务器)

自定义控件

您可以在设计时或运行时更改此控件的属性,以影响控件如何绘制数据。
使用新的控件属性页

Graph Property Page(图表属性页)

Graph Property Page

Elements Property Page(元素属性页)

Elements Property Page

Annotations Property Page(注释属性页)

Annotations Property Page

Cursors Property Page(光标属性页)

Cursors Property Page

Format Property Page(格式属性页)

Cursors Property Page

您可以按照ActiveX控件的标准步骤将控件包含在您的项目中

  1. 创建MFC对话框项目或MDI/SDI项目,其中视图类派生自 `CFormView`
  2. 选择菜单“项目”|“添加到项目”|“组件和控件...”
  3. 打开已注册的ActiveX控件库
  4. 选择 `NTGraph` 控件并单击“插入”
  5. Visual C++ 将生成 `CNTGraph` 类
  6. 然后您可以定义 `CNTGraph` 类型的变量。

控件的自定义选项非常直接

// Customize Graph Properties 

m_Graph.SetBackColor (RGB(0,0,0));
m_Graph.SetAxisColor (RGB(0,255,0));
m_Graph.SetLabelColor (RGB(128,255,255));

// Control's Frame and Plot area options
m_Graph.SetFrameColor((RGB(0,0,0));
m_Graph.SetPlotAreaColor(RGB(212,222,200));

m_Graph.SetFrameStyle(2) // (1) - Flat
                         // (2) - Scope (raised frame and sunken plot area borders)
                         // (3) - 3DFrame (a bitmap frame picture)
    
m_Graph.SetGridColor(RGB(192,192,192));
m_Graph.SetShowGrid (TRUE);

m_Graph.SetCursorColor (RGB(255,0,0));
m_Graph.SetTrackMode (1);

m_Graph.SetGraphTitle("XY Plot");
m_Graph.SetXLabel ("X Axis");
m_Graph.SetYLabel("Y Axis");
m_Graph.SetRange(0.,10,-1,1.);

您无需每次更改Graph属性时都调用控件的 `Invalidate()` 函数。更改会自动反映在控件的外观上。

将数据加载到控件中...

//
//
// Customize Graph Elements 
//
//
   // The Graph elements are dynamically allocated! 
   
   // Element 0 is allocated by default
   // Even after a call to the ClearGraph method,
   // the Element-0  is automaticaly allocated.
  
   m_Graph.SetElementLineColor(RGB(255,0,0));
   m_Graph.SetElementLinetype(0);
   m_Graph.SetElementWidth(1);

   m_Graph.SetElementPointColor(RGB(0,0,255);
   m_Graph.SetElementPointSymbol(3);
   m_Graph.SetElementSolidPoint(TRUE);
	

   // Allocate a new element: Element-1
   m_Graph.AddElement();
	   
   m_Graph.SetElementColor (RGB(0,255,0));
   m_Graph.SetElementLinewidth(1);
   m_Graph.SetElementLinetype(2);
   
   // Allocate a new element: Element-2
   m_Graph.AddElement();

   m_Graph.SetElementColor (RGB(0,0,255));
   m_Graph.SetElementLinetype(3);
   

  // Now change again the properties of Element-1
  m_Graph.SetElement(1); 
 
  m_Graph.SetElementColor (RGB(0,0,255)); 
  ...

//
// Load Data int the Graph Elements 
//


  double y;
  for (int i = 0; i < NumberOfElements; i++) 
  {
 	for (int x = 0; x < NumberOfPoints; x++) 
	{
	   y = (double)rand() / RAND_MAX * 10.0;
	   y = y / 3 + 10.0 / 2 * i + 1;
           m_Graph.PlotXY(x, y, i); 
           // or PlotY(double data, long ElementID) 
	}
  }

Visual Basic 用户也一样

  With NTGraph1
       .PlotAreaColor = vbBlack
       .FrameStyle = Frame
       .Caption = ""
       .XLabel = ""
       .YLabel = ""
         
       .ClearGraph 'delete all elements and create a new one
       .ElementLineColor = RGB(255, 255, 0)
       .AddElement  ' Add second elements
       .ElementLineColor = vbGreen
      
       For X = 0 To 100
            Y = Sin(X / 3.15) * Rnd - 1
            .PlotY Y, 0
             Y = Cos(X / 3.15) * Rnd + 1
            .PlotXY X, Y, 1
            .SetRange 0, 100, -3, 3
        Next X
  End With

NTGraph 属性

  •  `short` Appearance(外观)
  •  BSTR Caption(标题)
  •  `short` Appearance(外观)
  •  BSTR Caption(标题)
  •  BSTR XLabel(X轴标签)
  •  BSTR YLabel(Y轴标签)
  •  OLE_COLOR ControlFrameColor(控件边框颜色)
  •  OLE_COLOR PlotAreaColor(绘图区域颜色)
  •  OLE_COLOR AxisColor(坐标轴颜色)
  •  OLE_COLOR GridColor(网格颜色)
  •  OLE_COLOR LabelColor(标签颜色)
  •  OLE_COLOR CursorColor(光标颜色)
  •  IPictureDisp* ControlFramePicture(控件边框图片)
  •  IPictureDisp* PlotAreaPicture(绘图区域图片)
  •  IFontDisp*LabelFont(标签字体)
  •  IFontDisp* TickFont(刻度字体)
  •  IFontDisp* TitleFont(标题字体)
  •  IFontDisp* IdentFont(标识字体)
  •  FrameType FrameStyle(边框样式)
  •  `short` XGridNumber(X轴网格数量)
  •  `short` YGridNumber(Y轴网格数量)
  •  boolean ShowGrid(显示网格)
  •  boolean XLog(X轴对数)
  •  boolean YLog(Y轴对数)
  •  `double` XCursor(X轴光标)
  •  `double` YCursor(Y轴光标)

    元素

  •  `short` Element(元素)
  •  `short` ElementCount(元素数量)
  •  OLE_COLOR ElementLineColor(元素线条颜色)
  •  OLE_COLOR ElementPointColor(元素点颜色)
  •  LineType ElementLinetype(元素线条类型)
  •  `short` ElementWidth(元素宽度)
  •  SymbolType ElementPointSymbol(元素点符号)
  •  boolean ElementSolidPoint(元素实心点)
  •  boolean ElementShow(显示元素)
  •  TrackModeState TrackMode(跟踪模式)
  •  BSTR ElementName(元素名称)
  •  boolean ElementIdent(元素标识)

    注解

  •  `short` Annotation(注释)
  •  `short` AnnoCount(注释数量)
  •  BSTR AnnoLabelCaption(注释标签标题)
  •  `double` AnnoLabelX(注释标签X坐标)
  •  `double` AnnoLabelY(注释标签Y坐标)
  •  OLE_COLOR AnnoLabelColor(注释标签颜色)
  •  boolean AnnoLabelHorizontal(注释标签水平)
  •  boolean AnnoVisible(注释可见)

    光标

  •  `short` Cursor(光标)
  •  `short` CursorCount(光标数量)
  •  `short` CursorMode`(0 - 固定;1 - 浮动;2 - 捕捉到当前选定元素)
  •  `double` CursorX(光标X坐标)
  •  `double` CursorY(光标Y坐标)
  •  OLE_COLOR CursorColor(光标颜色)
  •  `short` CursorStyle`(0 - 十字线;1 - 仅X轴线;2 - 仅Y轴线;)
  •  boolean CursorVisible(光标可见)

    格式

  •  boolean XTime(X轴时间)
  •  boolean YTime(Y轴时间)
  •  BSTR FormatAxisBottom(底部坐标轴格式)
  •  BSTR FormatAxisLeft(左侧坐标轴格式)

方法

  •  `void` SetRange(`double` xmin, `double` xmax, `double` ymin, `double` ymax)
  •  `void` AutoRange()
  •  `void` CopyToClipboard()
  •  `void` PrintGraph()
  •  `void` ShowProperties()

    元素

  •  `void` AddElement()
  •  `void` DeleteElement(`short` ElementID)
  •  `void` ClearGraph()
  •  `double` GetElementXValue(`short` index, `short` ElementID)
  •  `void` SetElementXValue(`short` index, `short` ElementID, `double` newValue)
  •  `double` GetElementYValue(`short` index, `short` ElementID)
  •  `void` SetElementYValue(`short` index, `short` ElementID, `double` newValue)
  •  `void` PlotXY(`double` X, `double` Y, `short` ElementID)
  •  `void` PlotY(`double` Y, `short` ElementID)

    注解

  •  `void` AddAnnotation()
  •  `void` DeleteAnnotation(`short` AnnotationID)

    光标

  •  `void` AddCursor()
  •  `void` DeleteCursor(`short` CursorID)

跟踪模式常量

  • None = 0
  • Track = 1 跟踪光标位置(按住鼠标按钮)
  • Cursor = 2 单击定位光标
  • Zoom = 3 取消缩放(单击鼠标右键)
  • PanXY = 4
  • PanX = 5
  • PanY = 6

边框样式常量

  • Flat = 0
  • Scope = 1 (凸起的边框和凹陷的绘图区域边框)
  • 3DFrame = 2 (位图边框图片)

线条样式常量

  • Solid = 0
  • Dash = 1
  • Dot = 2
  • DashDot = 3
  • DashDotDot = 4
  • Null = 5
  • XYStep = 6
  • YXStep = 7
  • Bars = 8
  • Stick = 9

符号样式常量

  • Nosym = 0
  • Dots = 1
  • Rectangles = 2
  • Diamonds = 3
  • Asterisk = 4
  • DownTriangles = 5
  • UpTriangles = 6
  • LeftTriangles = 7
  • RightTriangles = 8

是的,就是这样!

尽情享用!

发送邮件至 nteofilov@yahoo.de 询问关于本文的问题或评论。

历史

2002年11月22日 - v1.0 首次发布

2002年12月01日 - v1.1

  • 添加了新的方法copy2clipboard。
  • 增加了绘制具有不同数量点的元素的能力。(作者:A.Hoffman)
  • A.Hoffman添加了新的方法来显示/隐藏图表元素
  • Bug修复。感谢A.Hofmann的帮助。
  • 修复了一些绘图问题。感谢Judd。
  • 增加了自定义字体支持。
  • Zoom Mode: 尚未实现,但已预留。

2003年1月26日 - v2.0(控件的无闪烁版本)

  • 感谢Keith Rule提供的 `CMemDC`类
  • ZoomMode 已实现。
  • 添加了显示当前光标位置的工具提示。
  • 添加了新方法 `Autorange`。
  • 添加了新属性 `ElementLinewidth`。
  • 添加了新属性 `ElementLinetype`。
  • 修复了一些绘图问题。
  • 添加了(*Test.htm*)关于如何将控件添加到网页的简要说明。

2003年3月9日 - v2.1

  • PanMode 已实现。
  • 修改了 `SetElementColor`、`SetElementLinewidth`、`SetElementLinetype`,使其接受ElementID作为第一个参数。
  • 修复了一些绘图问题。现在应该干净了。
  • 修复了GDI泄露。

2003年6月1日 - v3.0 新版本发布!

2003年8月2日 - v4.0 最终发布!

  • 感谢Robert Harber提供的有益的讨论、想法和代码。
  • 感谢tagi1修复了打印字体问题。
  • 感谢Judd测试了该控件。

注意由于最后一个版本有重大更改,您应该从您的项目中删除(先注销然后删除)所有旧版本的控件!在Office应用程序中使用该控件的VBA用户还应该删除计算机的Temp目录中的以下文件NTGRAPHLib.exd。该文件由Office应用程序自动创建,并保存了以前创建的控件实例的属性。在插入新版本的控件之前,您必须删除此文件,以便在属性浏览器中获得正确的名称。

© . All rights reserved.