GitHub
The latest source code can be checked out from GitHub (https://github.com/xiangzhai/gdiplusplot).
Introduction
This is a simple OCX control, which allows you to plot two-dimensional data. Despite ProEssentials developed by Gigasoft Co., Ltd, there is no out-of-the-box control that provides simple and straightforward 2D data visualization based on GDI+. The NtGraph ActiveX control by Nikolai Teofilov (http://www.codeproject.com/KB/miscctrl/ntgraph_activex.aspx) inspired me to write my own control, mostly because I wanted to customize the source code when needed. Over time, the functionality of the ActiveX control became more elaborate, and finally I made a decision to publish what I have in hand under LGPL v3 license.
What Can It Do?
The control is able to plot a large number of points and update one or more plots on the graph with new data, replacing the old plot with the new plot. Multiple plots with individual properties such as color, visible could be customized at runtime.
How To Use the Control
To use this OCX control, embed it in an application that supports the use of OCX controls. Microsoft Visual Basic applications, Office applications and applications created with the Microsoft Developer Studio's AppWizard can support the use of OCX controls. There are two files required to use this control. They are:
- GDIPlusPlot.ocx——The
GDIPlusPlot
controls code and data
- gdiplus.dll——The GDI+ dynamic linker library by Microsoft
Before the ActiveX control can be used in your application, it must be registered as a COM Component in the system registry. This is a self registering control. This means that to register the control in the system registry, you only need to have an application load the control and call the control's exported function DllRegisterServer
. You can use the REGSVR32
utility or have your setup program do this.
How to Use the REGSVR32 Utility?
Copy GDIPlusPlot.ocx to your directory and type:
regsvr32 GDIPlusPlot.ocx
regsvr32 /u GDIPlusPlot.ocx (Unregister server)
Customizing the Control
You can include the control in your project by following the standard steps for ActiveX controls:
- Create MFC Dialog project or MDI/SDI project with View class derived from
CFormView
- Choose menu Project|Add To Project|Components and Controls...
- Open the Registered ActiveX Control gallery
- Choose the
GDIPlusPlot
Control and click Insert
- Visual C++ will generate the class
CGDIPlusPlot
- Then you can define variable of the type as
CGDIPlusPlot
Using the Code
HelloWorld
example (here m_GDIPlusPlot1
is the on-the-fly realtime control and m_GDIPlusPlot2
is the static
control):
BOOL CHelloWorldDlg::OnInitDialog()
{
int RANGE_MIN = -10;
int RANGE_MAX = 10;
unsigned int i;
......
m_GDIPlusPlot1.SetXTime(TRUE);
m_GDIPlusPlot1.SetCaption("RealTime");
m_GDIPlusPlot1.AddElement(0); m_GDIPlusPlot1.AddElement(2);
m_GDIPlusPlot2.SetXTrack(TRUE); m_GDIPlusPlot2.AddElement(3);
m_GDIPlusPlot2.AddElement(4);
m_GDIPlusPlot2.AddElement(0);
for (i = 0; i < 168; i++)
{
int randv = (((double) rand() /
(double) RAND_MAX) * RANGE_MAX + RANGE_MIN);
m_GDIPlusPlot2.PlotXY(i, randv, 0);
m_GDIPlusPlot2.PlotXY(i, randv / 1.6, 1);
m_GDIPlusPlot2.PlotXY(i, sin(randv), 2);
}
SetTimer(1, 100, NULL);
......
}
void CHelloWorldDlg::OnTimer(UINT nIDEvent)
{
int RANGE_MIN = -6;
int RANGE_MAX = 6;
int randv = (((double) rand() /
(double) RAND_MAX) * RANGE_MAX + RANGE_MIN);
m_GDIPlusPlot1.PlotY(randv, 0);
m_GDIPlusPlot1.PlotY(randv * 3, 1);
......
}
GDIPlusPlot Properties
BSTR caption;
boolean xTime;
BSTR xLabel;
BSTR yLabel;
short interval;
BSTR annolabel;
boolean xTrack;
Methods
void PlotXY(double xValue, double yValue, short index);
void SetRange(double xMin, double xMax, double yMin, double yMax);
void PlotY(double newValue, short index);
void ClearGraph();
void AddElement(short color);
void IsElementVisible(short index, boolean visible);
void SetXCursorPos(double xValue);
double GetQuadrantWidth();
Points of Interest
The NtGraph ActiveX control based on GDI by Nikolai Teofilov inspired me to write my own control, mostly because I wanted to customize the source code when needed, so I have fun with GDI+ ^_^.