Click here to Skip to main content
Click here to Skip to main content

2D Graph ActiveX control in C++ with ATL (no MFC dependency)

By , 8 Mar 2012
 

Introduction

Quite often developers need to plot various data. They expect to use a light control with minimal dependencies.

Background

NTGraph control is a powerful ActiveX control which plots multiple data sets. Unfortunately it depends on MFC libraries.

This new 2D Graph ActiveX control, named DMGraph, is based on the NTGraph drawing engine but eliminates the MFC dependency. For DMGraph, ATL 3.0 was used as the framework. The only dependencies are some MS Windows DLLs (the C runtime library msvcrt.dll is part of the OS starting with Windows 2000). This means there are no deployment issues - DMGraph works on Windows 2000 or later.

Another major change compared with old NTGraphCtrl is the exposed COM interface architecture. Instead of putting everything together under one interface, DMGraphCtrl exposes a hierarchy of interfaces which represents entities used on drawing.

Using the code

The main interface IDMGraphCtrl contains collections of items (managed by the IDMGraphCollection interface). This collection interface exposes the usual methods (such as Add, Delete, Count, Item). What is specific is the concept of "selected item". One item in the collection can be the "selected" one. Sometimes user operations (such as mouse drag) apply to the "selected" item (if any). The IDMGraphCollection::Selected property gets/sets the index of the selected item.

When the user double clicks the graph area, a modal dialog with property pages is displayed. This dialog may be invoked programmatically as well using the ShowProperties method. Modifying data in these property pages has an immediate effect on the displayed graph.

The CDMGraphCtrl class implements the IDMGraphCtrl interface. At runtime, some properties can be viewed or changed using the DM Graph property page:

The CDMGraphCtrl class keeps the following collections exposed by the IDMGraphCtrl interface:

1. Element collection

The get_Elements property exposes the elements collection.

Each item is an instance of the CGraphElement class which exposes the IDMGraphElement interface. A graph element is a collection of points which need to be plotted. The graph element has various properties which define its drawing style. For example, the Linetype property defines what kind of line should be used to connect the points (including "Null" - no lines at all). Color, width, shape can be set for points; the entire set of points can be enabled/disabled for drawing, etc. Each graph element is identified by a "name". All these are accessible through COM properties exposed by the IDMGraphElement interface. When such a property is set, the entire graph is re-drawn to reflect the changes.

The set of points (data to be plotted) is supplied by the client using several methods:

  • Plot - two one-dimensional arrays with same size (one for X, the other for Y) will set the entire point collection for a specific graph element.
  • PlotXY - appends just one point to the point collection (both X and Y coordinates are specified).
  • PlotY - appends just one point to the point collection (only Y is specified, the X is the index of the added point in the points collection).

Each time the point collection is modified, the graph is updated to reflect the changes but the range is not updated. If the new point(s) go(es) out of range, then the SetRange or AutoRange methods need to be called.

New elements can be added to the collection, existing ones removed, selected element index can be changed, and selected element properties can be viewed/changed from the Elements property page.

2. Annotation collection

The get_Annotations property exposes the annotations collection.

One annotation is a piece of text which is displayed on a specific position on the graph. This collection keeps instances of the CGraphAnnotation class which exposes the IDMGraphAnnotation interface. Using this interface various properties can be accessed - such as caption (the displayed text), position, color, text orientation, background enable/disable. When such a property is set, the entire graph is re-drawn to reflect the changes.

New annotations can be added to the collection, existing ones removed, selected annotation index can be changed, and selected annotation properties can be viewed/changed from the Annotations property page.

3. Cursor collection

The get_Cursors property exposes the cursors collection.

A cursor is made of one or two lines which are parallel with the X or Y axis. The IDMGraphCursor interface deals with cursor specific properties. If the Style property (type is the Crosshair enum) is set to "XY" then the cursor will have two lines: one parallel with X axis and the other parallel with Y axis. If the cursor Mode is set to Snap, then the selected cursor will snap to the closest point of the selected graph element during mouse drag.

New cursors can be added to a collection, existing ones removed, selected cursor index can be changed, and selected cursor properties can be viewed/changed from the Cursors property page.

4. Axis objects

Two objects are exposed by the get_Axis property: one for X (horizontal) axis and the other for Y (vertical) axis. The objects are instances of the CGraphAxis class which exposes the IDMGraphAxis interface. Various properties can be get/set for each axis. If the put_Time property is set to VARIANT_TRUE, then the double values for that axis are considered to be date/time values. These values are interpreted like the DATE type (used in OLE Automation VARIANT union). The values are displayed according to the format string set by the Format property. For date/time, possible format strings are documented in the strftime function in MSDN. Otherwise, for non logarithmic axis, the usual sprintf format strings are accepted. Some axis properties are available in the DM Graph property sheet (see above) while others are available in the Format property page (see below).

From the Axis combo box, the X (bottom) or Y (left) axis can be selected. Then the data type can be set for the selected axis. For each type, the Templates list box is filled with the available format templates. When a template item is selected from the left, the Format string on the right is updated.

Basic usage

1. From a Windows client written in C++ with ATL

class CMainWnd : public CWindowImpl<CMainWnd>
{ 
     CAxWindow*                 m_pGraphCtrl; 
     CComPtr<IDMGraphCtrl>      m_spDMGraph; 
}; 

LRESULT CMainWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)  
{ 
     m_pGraphCtrl = new CAxWindow; 
     if(m_pGraphCtrl == NULL) 
           return -1; 
     if(!AtlAxWinInit()) 
           return -1; 
     HRESULT hr; 
     CComPtr<IAxWinHostWindow> spHost; 
     hr = m_pGraphCtrl->QueryHost(IID_IAxWinHostWindow, (void**)&spHost); 
     if(FAILED(hr)) 
     { 
         Message(hr, NULL, L"Cannot query Ax host"); 
         return -1; 
     } 
     hr = spHost->CreateControl(L"DMGraph.DMGraphCtrl", m_pGraphCtrl->m_hWnd, NULL); 
     if(FAILED(hr)) 
     { 
         Message(hr, NULL, L"Cannot start DM Graph control"); 
         return -1; 
     } 

     CComVariant vData; 
     hr = m_pGraphCtrl->QueryControl(IID_IDMGraphCtrl, (void**)&m_spDMGraph); 
     if(FAILED(hr) || m_spDMGraph == NULL) 
     { 
         Message(hr, NULL, L"Cannot query DM Graph control"); 
         return -1; 
     } 
     return 0;
}  
 
void CMainWnd::SetGraphData(VARIANT* pvarrX, VARIANT* pvarrY, LPCTSTR szName)
{ 
  ATLASSERT(pvarrX); 
  ATLASSERT(pvarrY); 
  ATLASSERT(szName); 
  CComBSTR bsName(szName); 
  CComPtr<IDMGraphCollection> spElements; 
  CComPtr<IDMGraphElement> spGraphElement; 
  HRESULT hr = m_spDMGraph->get_Elements(&spElements); 
  long i, nElementCount = 0; 
  BOOL bReplace = FALSE; 
  hr = spElements->get_Count(&nElementCount); 
  for(i=0; i<nElementCount; i++) 
  { 
     CComBSTR bsElemName; 
     CComPtr<IDispatch> spDispatch; 
     
     hr = spElements->get_Item(i, &spDispatch); 

     hr = spDispatch.QueryInterface(&spGraphElement); 

     spGraphElement->get_Name(&bsElemName); 
     if(_wcsicmp(bsElemName, bsName) == 0) 
    { 
         OLECHAR szMsgText[256]; 
        _snwprintf(szMsgText, 256,
              L"There is ALREADY an element named '%s'.\n"
              L"Do you want to replace it ?", bsElemName); 
         if(::MessageBoxW(m_hWnd, szMsgText, NULL,
            MB_YESNO|MB_ICONQUESTION) != IDYES)
         { 
              return;
         } 
         bReplace = TRUE; 
         break; 
    } 
    else 
         spGraphElement = NULL; 
  } 
  if(bReplace == FALSE || spGraphElement == NULL) 
  { 
     CComPtr<IDispatch>     spDispatch; 
     hr = spElements->Add(&spDispatch); 
     spGraphElement = NULL; 
     hr = spDispatch.QueryInterface(&spGraphElement); 

  } 
  hr = spGraphElement->put_Name(bsName); 
  hr = spGraphElement->put_PointSymbol( Dots ); 
  hr = spGraphElement->put_PointSize(3); 
  hr = spGraphElement->Plot(*pvarrX, *pvarrY); 
  if(FAILED(hr)) 
  { 
     Message(hr, spGraphElement, L"Failed to plot items");
     return; 
  } 
  hr = m_spDMGraph->AutoRange(); 
}

2. From an HTML page using VBScript

Inside the HTML body, the ActiveX is created using the object tag. A button click will execute a script to set the data to be plotted.

<object ID="DMGraphCtrl" 
      CLASSID="CLSID:AAF89A51-7FC0-43B0-9F81-FFEFF6A8DB43" 
      width=600 height=400 VIEWASTEXT></object>
<input id=BtnSin value=sin type="button">
<script id=clientEventHandlersVBS language="vbscript">
<!--
Sub BtnSin_onclick
  On Error Resume Next
  Dim dmGraphCtrl
  Set dmGraphCtrl = document.getElementById("DMGraphCtrl")
  Dim idx : idx = dmGraphCtrl.Elements.Selected
  If idx < 0 Then
    MsgBox("Error: please create and select an element first." &_
             vbCrLf & "(Double click to see property pages)")
  Else
    Dim selElement
    Set selElement = dmGraphCtrl.Elements.Item(idx)
    Dim i
    Dim x()
    Dim y()
    ReDim x(100)
    ReDim y(100)
    For i=0 To 100
      x(i) = i/5
      y(i) = Sin( x(i) )
    Next
    selElement.Plot x, y
    dmGraphCtrl.AutoRange()
  End If
  If Err.number <> 0 Then
    MsgBox Err.Description
  End If
End Sub
-->
</script>

3. From a Windows client written in C++ with MFC

#import "..\DMGraph\DMGraph.tlb" no_namespace raw_interfaces_only

class CDmGraphMfcClientDlg : public CDialog
{
    ... ... ...

    IDMGraphCtrlPtr m_spGraph;
};

BOOL CDmGraphMfcClientDlg::OnInitDialog()
{
    ... ... ...

    CWnd* pwndCtrl = GetDlgItem(IDC_DMGRAPHCTRL1);
    ASSERT_VALID(pwndCtrl);
    IUnknown* pUnkCtrl = pwndCtrl->GetControlUnknown(); //weak reference

    HRESULT hr;
    m_spGraph = pUnkCtrl;
    IDMGraphCollectionPtr colElements;
    
    hr = m_spGraph->get_Elements(&colElements);

    IDispatchPtr spDisp;
    IDMGraphElementPtr spElem;
    hr = colElements->Add(&spDisp);
    spElem = spDisp;
    hr = spElem->put_Name(_bstr_t("sin"));
    hr = spElem->put_PointSymbol( Dots );
    hr = spElem->put_PointSize(1);
    hr = spElem->put_PointColor( RGB(255, 0, 0) );
    
    COleSafeArray arrx, arry;
    arrx.CreateOneDim(VT_R8, 100);
    arry.CreateOneDim(VT_R8, 100);
    long i;
    for(i=0; i<100; i++)
    {
        double x, y;
        x = i/10.;
        y = sin(x);

        arrx.PutElement(&i, &x);
        arry.PutElement(&i, &y);
    }

    hr = spElem->Plot(COleVariant(arrx), COleVariant(arry));
    hr = m_spGraph->AutoRange();

    return TRUE;  // return TRUE  unless you set the focus to a control
}

Points of interest

  • The "sprintf" code which formats the input data needs to be guarded against exceptions.
  • The WM_ERASEBKGND needs to be handled to avoid window flickering while resizing.
  • The VARIANT passed by a VBScript client usually needs indirection for contained safe array and conversion for array elements.

History

  • Version 5.0.0.3
    • Corrected a registration error (wrong LIBID was used inside CLSID key)
    • Added the "control" flag for the type library (as attribute in IDL). In this way DMGraph is listed as an ActiveX in Visual Basic Component Control List / Excel Control Toolbox
    • Changed the DrawGraphOffScreen function to behave properly even if the supplied HDC is a metafile DC. This is useful when COM client invokes IDataObject::GetData method. The ATL implementation for this method uses a metafile DC.
  • Version 5.0.0.2
    • Added UI in DM Graph property page to allow grid step changes.
  • Version 5.0.0.1
    • Fixed a minor defect which raised an Assert in the 'Debug build' when the ActiveX was not in place active (example: when inserted into a dialog by the C++ resource editor).
    • Updated help file with MFC client sample code.
  • Version 5.0
    • MFC dependency is removed; the old .OCX library is now a .DLL using ATL. The DLL depends only on standard Windows libraries and on the standard C++ library (msvcrt.dll) which is part of the OS starting with Windows 2000. This means there are no deployment issues.
    • Major re-design in exposed COM interfaces. More interfaces were added. They group together methods and properties which apply to the same kind of objects. As a consequence, there is no backward compatibility with the COM exposed by the old NTGraphCtrl.ocx. Hence all GUIDs and ProgIDs are new.
    • The new DLL exposes dual interfaces (as opposed with the old dispinterfaces).
    • Fixed GDI and memory leaks when printing.
    • Added new API to pass an array of points using just one method call.
    • Added selective zoom (zoom just on X or just on Y).
    • Added a new tracking mode which displays in a tooltip the value of the closest point near the mouse.
    • Printing uses the new OS Print Wizard dialog.
    • Documentation (help) is presented in CHM format.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Marius Samoila
Software Developer (Senior)
Canada Canada
Member

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionCan this Library be used with VS 2010?memberMember 1005971417 May '13 - 6:04 
I am trying to use your library in Visual Studio 2010 for Visual C++. I Downloaded the source code and added the dll into my toolbox. But whenever I try to add it to one of my forms, VS immediately crashes. Am I doing something wrong, or is this project simply not compatible with VS '10?
 
Thanks so much,
~Warren
QuestionUse of CoinitializeEx().. from ClientmemberK ARUN KUMAR20 Jan '13 - 22:02 
Hello,
 
In you sample client for DMGraph, CoInitialize(NULL) was used. I tried to use CoInitializeEx(NULL, COINIT_MULTITHREADED ) which enables using same OLE object from multiple threads. But, this leads to non-visibility of graph. Can you please explain the reason for this behavior.
 
Thanks and Regards,
Arunkumar Karri
AnswerRe: Use of CoinitializeEx().. from Client [modified]memberMarius Samoila21 Jan '13 - 18:43 
I do not think the ATL implementation for ActiveX controls is thread safe. Also, the DMGraph code itself is not thread safe. This means it is not allowed to call COM methods/properties at the same time from various threads (such as add/remove points). Hence your attempt to use this ActiveX in a MTA with no marshaling produces unpredictable results.
 
The threading model for this ActiveX is "Apartment"
 
If the COM client calls CoInitializeEx(NULL, COINIT_MULTITHREADED ) then your client MUST take care to use all DMGraph COM references on the same thread where CoCreateInstance was called. This includes the ActiveX OLE COM interfaces which are used for rendering.
 
Using the COM object on a different thread (other than one which created it) will imply COM marshling (see CoMarshalInterThreadInterfaceInStream and CoGetInterfaceAndReleaseStream or IGlobalInterfaceTable in MSDN ).

modified 22 Jan '13 - 13:45.

GeneralRe: Use of CoinitializeEx().. from ClientmemberK ARUN KUMAR23 Jan '13 - 19:06 
Thanks for the valuable information Smile | :)
Questionpassing array string in DMGRHmemberMember 89030 Apr '12 - 18:11 
thank you for your kind response.
when using VB6, I got an error type mismatch.
may be cause an error when passing array string elements.
 
pls help me
 
Public Elements As Object
Dim y(100), x(100), idx
 

Private Sub Form_Load()
Dim selElement As Object
Dim HorizontalX, spXAxis
Dim sTemp
 

DMGraphCtrl1.Elements.Add
DMGraphCtrl1.Elements.Add
idx = 100
DMGraphCtrl1.SetRange 0, 100, -100, 100

Set selElement = DMGraphCtrl1.Axis(0)
selElement.GridNumber = 5
selElement.Time = True
selElement.Format = "%H:%M:%S"

'hr = spXAxis->put_Format( CComBSTR(L"%d/%b %H:%M:%S") );
'hr = spXAxis->put_Time( VARIANT_TRUE );
End Sub
 
Private Sub Timer1_Timer()
 
If idx >= 100 Then
For i = 0 To 99: x(i) = Format(Time, "h:m:s"): y(i) = y(i + 1): Next i
x(100) = Format(Time, "h:m:s"): y(100) = Rnd() * 200 - 100
Else
x(idx) = Format(Time, "h:m:s"): y(idx) = Rnd() * 200 - 100
idx = idx + 1
End If
Call BtnSin_click
End Sub
 

Sub BtnSin_click()
Dim i As Integer
Dim selElement, selElement1, id
'On Error Resume Next
 
id = DMGraphCtrl1.Elements.Selected
DMGraphCtrl1.LabelColor = vbRed
If (id >= 0) Then
Set selElement = DMGraphCtrl1.Elements.Item(0)
selElement.LineColor = vbCyan
selElement.LineWidth = 3
selElement.Plot x, y '<==== type mismatch error occur
End If
End Sub
 

 
above code is VB6
thanks
AnswerRe: passing array string in DMGRH [modified]memberMarius Samoila2 May '12 - 7:37 
In your code "x" is an array of strings. In DMGraph documentation it is written that for time the data should be supplied as a double type. The interpretation of this double value for date/time is according to MSDN - look at VARIANT. The DATE type is actually a double, the integer part and decimal part have a specific meaning. Search on Internet for details. I did a search for you and this is a place you can read:
 
http://sourcedaddy.com/ms-access/datetime-values-stored-variants.html[^]
 
I did not work in VB but I guess there is a date/time type which you can convert to double.
Once you provide these doubles instead of strings it should work.

modified 2 May '12 - 16:00.

Questionruntime error in plot x,ymemberMember 89027 Apr '12 - 6:17 
type mismatch error (runtime error 13)
for time base x-axis, above error occur..
how to fix it?
AnswerRe: runtime error in plot x,ymemberMarius Samoila28 Apr '12 - 18:22 
I was unable to reproduce the error.
 
I have the following comments:
 
1. About the way to describe a defect. The following information is expected:
a. What COM methods/properties were invoked, in which order and what values have been passed?
b. The steps followed by user in UI (mouse click, where, keyboard etc.)
 
I am using this software for myself having time set for x-axis and I did not have this error. Probably a. and b. above are different for me.
QuestionX-Axis problem for time domainmemberMember 89014 Apr '12 - 3:00 
thank you for your kind reply of Vb6 usgae.
But time can not pass in plot when time as a x-axis value.
so pls check DMgraph for time (x-axis).
thank you.
AnswerRe: X-Axis problem for time domainmemberMarius Samoila14 Apr '12 - 5:47 
The C++ test program (DMGraphTest) contains the code which set time format for X axis. Look in CMainWnd::OnCreate for these lines:

hr = spXAxis->put_Format( CComBSTR(L"%d/%b %H:%M:%S") );
hr = spXAxis->put_Time( VARIANT_TRUE );

You may want compile and execute this test program, add some input data (using its menu) and see how time is displayed for X axis.
QuestionHow to use VB6 like NTgraphmemberMember 8904 Apr '12 - 22:07 
NTgraph have a sample.
I confirm rhat Dmgraph ocx can be referenced by VB6.
But test fail...
So pls help to use in VB6.
thank you
AnswerRe: How to use VB6 like NTgraphmemberMarius Samoila5 Apr '12 - 20:17 
There is nothing special with this ActiveX control. If you know how to handle a standard ActiveX then it should not be a problem. I've just tested with VB6. Here are the basic steps:
1. Add the DMGraph Ctrl in VB control toolbox (right click, choose "Components..." from context menu, check the box near 'DMGraph ActiveX Control module' in Controls tab).
The control's icon should be added in toolbox to the end.
2. Click on control's icon on toolbox. Then drag a rectangle on the form client area to specify the position for the ActiveX control in the form. When you finish this you should see the ActiveX added as a control in the VB form.
3. In properties window change the control name to dmGraphCtrl.
3. Add a push button. Double click in the form to add/edit its "click" event handler.
4. Copy an paste the code from above VB script sample inside the "click" event handler.
5. Do minor adjustments to port from VBScript for Html page to VB6.
Example:
-remove Html specific:
Dim dmGraphCtrl
Set dmGraphCtrl = document.getElementById("DMGraphCtrl")
 
-instead of
dmGraphCtrl.AutoRange()
use
Call dmGraphCtrl.AutoRange
QuestionVC6 projectmemberFlaviu28 Mar '12 - 19:24 
I use VC6 environment, with SP5 and sdk version 2003, still, the project does not function, did you try it on VC6 ? Thank you.
AnswerRe: VC6 projectmemberMarius Samoila9 Mar '12 - 6:09 
Yes, this project was done using MS Visual C++ 6.0 SP5 using in Options/Directories tab the include/lib/executable folders from MS SDK February 2003. I did not have any build errors.
 
What errors did you experience ? Can you provide more details ?
QuestionLegend boxmemberDenisP15 Mar '12 - 10:03 
I'm assuming you had removed the legend object from the original NTGraph control. Any plan to add support for it?
AnswerRe: Legend boxmemberMarius Samoila5 Mar '12 - 20:51 
I do not remember any code related to legend in NTGraph.
 
I've just searched in the orginal source code of NT Graph (just to doublecheck). Again, I did not see any code related to legend. The original code is available here, you can check yourself:
http://www.codeproject.com/KB/miscctrl/ntgraph_activex/NTGraph_src.zip
GeneralRe: Legend box [modified]memberDenisP16 Mar '12 - 4:45 
Never mind, I figured, I forgot to set pDMGraphCtrl->PutElementIdentify
 
What would be nice though is to have a Legend coclass with frame, background, font, placement properties, etc. + align nicely the series captions. Right now the captions for multiple elements are all misalligned. In my case I wanted them left-aligned, so I ended up modifying in CDMGraphCtrl::DrawElementLabel() the following:
 
//SetTextAlign(hDC, TA_TOP | TA_CENTER);
SetTextAlign(hDC, TA_TOP | TA_LEFT);
 
and
 
//rect.left += tm.tmAveCharWidth * strCaption.Length();
rect.left += tm.tmAveCharWidth * 4;
 
Thanks

modified 6 Mar '12 - 11:05.

QuestionUse of control in office applications [modified]memberMember 238363829 Feb '12 - 16:36 
I have previously used NTGraph embedded in a spreadsheet to display coordinate data...worked well and very quick for large datasets.
 
In looking to move to the DMGraph version I tried to insert the new control on a worksheet in excel (after registering the dll) but I get the error 'cannot insert object'.
 
I can create an instance of the control via code, set various parameters and display the properties page without issue, but I cannot figure out how to add the control either to a sheet or a userform.
 
I have tried this on 32 and 64 bit windows (XP and 7) with the same result.
 
Any ideas?

modified 1 Mar '12 - 16:06.

AnswerRe: Use of control in office applications [modified]memberMarius Samoila5 Mar '12 - 20:47 
I found the cause and the fix. A new version 5.0.0.3 is awaiting approval to be published.
These are the changes I did:
 
1.Corrected a registration error (wrong LIBID was used inside CLSID key)
2.Added the "control" flag for the type library (as attribute in IDL). In this way DMGraph is listed as an ActiveX in Visual Basic Component Control List / Excel Control Toolbox.
3.Changed the DrawGraphOffScreen function to behave properly even if the supplied HDC is a metafile DC. This is useful when COM client invokes IDataObject::GetData method. The ATL implementation for this method uses a metafile DC
 
Thanks for your feedback.
 
[08 March 2012]
The version 5.0.0.3 which contains above changes is published now. Please download the source and/or binaries. The problem you mentioned should be gone.

modified 8 Mar '12 - 12:24.

GeneralRe: Use of control in office applicationsmemberAlastairMathias26 Mar '12 - 15:22 
Thank you for the excellent response...I'll download the latest version and get back into it!
GeneralMy vote of 5memberMihai MOGA8 Feb '12 - 6:31 
Great article. Please keep it up!
QuestionLive Datamemberrprasad12 Feb '12 - 1:30 
Can I use the control to plot live/real-time data
AnswerRe: Live DatamemberMarius Samoila2 Feb '12 - 13:03 
This control accepts input data in two ways:
1. The whole data set is provided as input parameter for IDMGraphElement::Plot. This method replaces all previously added points.
2. New points are added one by one; existing ones are preserved (see IDMGraphElement::PlotXY and IDMGraphElement::PlotY).
 
Which method you choose depend of your type of "live" data.
 
If you want to display new "live" data without wiping the already added one, then second way is the good one. While live data continues to arrive, the graph will be more and more crowded. At one point you might want to erase accumulated data (you may call Plot with an empty array).
 
If the newly arrived "live" data is coming in batches and you want to display one batch at a time then first way can be used. The graph will contain just the last batch of "live" data.
QuestionAxis improvementmemberhorskyv28 Jan '12 - 23:45 
Now the both (X and Y) axis range is divided into 5 regions.
 
Do you plan to improve:
- drawing axis with user selectable start value and step value (so the user could select e.g. X axis will start at value "2" and step of X-axis increment is "4"). This will lead to moving axes when panning the graph (insted of showing X axis starts at value 2.0231 Frown | :-( ). THis is very useful especially when showing only date format on X axis - all values in one day are shown starting with the same day and is not possible to estimate if the value was measured at 6:00 12:30 or 21:00.
- drawing ticks with subaxis (user could select step value of subaxis or number of regions in one region of main axis)?
AnswerRe: Axis improvement [modified]memberMarius Samoila29 Jan '12 - 9:32 
Your first suggestion has actually two distinct parts:
 
1. User selectable step for "grid lines" (I think you were thinking to grid lines not to axes - we have just two axes: one X and other Y). The grid lines are dividing the range in 5 regions.
 
The code already has the API to change the step between grid lines. Use IDMGraphAxis::GridNumber method to get/set the step (default value is 5 as you noted). The property pages did not expose UI to get/set this property. The COM client can do it. Still, I added some new UI to allow access to this property from DM Graph property page as well (version 5.0.0.2).
 
2. The grid should stick with the graph when user is doing pan (eventually zoom as well ?).
 
No, the code was not designed to do that. With existing behavior user can use the grid lines to explore the graph values while doing zoom/pan. Personally I enjoyed the frozen grid lines: I used pan to drag the points over the grid lines to see their values. Well, in this case I think the code should keep the existing behavior. If you want to add alternate behavior then a new API should be added to switch between the two modes. This was not in the scope for this project. But since the source code is available, feel free to add & test the new code for this feature (if you need it).
 
Regarding second suggestion: what are the "subaxis" ? I do not see this term in the code. When user disables the grid, small ticks (with values and without values) are drawn on axes. The ticks follow the same logic as grid: they do not stick with points while zoom/pan.

modified 29 Jan '12 - 20:00.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 8 Mar 2012
Article Copyright 2012 by Marius Samoila
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid