AXTutorial15

From Steema Software Reference Wiki
Jump to: navigation, search

Ax.png

Contents page
Previous | Next

Tutorial 15 - MS VC Applications

Introduction

This tutorial focuses on some of the technical and syntactical issues for working with TeeChart and Microsoft's Visual C . Most TeeChart documentation is written using Visual Basic examples but hopefully by the end of this tutorial you should find it easy enough to 'port' those examples and apply them to Visual C (of course VC then has a few tricks of its own !).

Applied examples in this tutorial originate with MFC in mind.


Quick start

Adding TeeChart to your Project

  • Use the 'New' option on the Developer Studio file menu and select 'MFC Application Wizard' from the Projects page. We'll start here by creating a Dialog based application, the Wizard leads you through the steps to create the application's project. On step 2 of the Wizard pages be sure to maintain ActiveX Controls selected (default).

  • When your project is created you may add the TeeChart control to the project. Select the 'Project' menu option from the IDE then 'Add To project' and 'Components and Controls'. Select TeeChart Pro Activex Control v2012 from the list of Registered ActiveX controls. After selecting the 'Insert' button you are offered a choice of which TeeChart classes you can add to the project. If in doubt as to what you will need, select them all. Close the 'Components and Controls gallery' dialog when finished. TeeChart classes now form a part of your project.

  • The next step is to add Teechart to the project's default Dialog box (for example). Go to the resources window of the project and select the Dialog folder. Within the folder you will see (normally) an 'About' dialogue and the 'Application' dialogue. Double click on the Dialog box to which you wish to add a TeeChart, that will open the Dialog box in its display format.

  • Right mouseclick on the Dialog box and select 'Insert Activex Control...' from the menu. Choose Teechart from the list of controls to place it on the Form from where you can drag it out to size.

  • You can now compile the application to see a Dialog box with an empty Chart. Please note that to save designtime Editor changes you should use the Chart Editor via the right mouseclick 'Properties' option not the right mouseclick 'TeeChart Pro Activex v2012 Object','Editor' option.

Naming the Chart

  • We must name the Chart to work with it. Open the ClassWizard and select the 'Member variables' page. Double-click on the Chart ID (probably IDC_TCHART1) to bring up the 'Member variable naming' screen. Add a name for this instance of TChart. In this example we will use 'm_Chart1'. Select 'OK' to exit.

Adding data to the Chart

  • Before we close this chapter we'll make the Chart show some data. We can add a data Series at design time but that is amply discussed in other tutorials so we'll do this at runtime here. Add a Button from the VC Component palette to the Dialog form. Right-click on the Button to confirm its ID and to add any desired Caption. Close the properties window for the Button and right-click anywhere on the Form to bring up the menu to select the ClassWizard. From within the 'Message maps' page select Class Name as the Dialog box, Object id as the Button id and then double-click on the Button's BN_CLICKED message to provoke the creation of a Function for the message. Select 'Edit code' to add/edit the function.

  • To display some data we need to add a Series and populate it.
void CMyDlg::OnButton1()
{
	//Add this include to the implementation file
	#include "Series.h"

	// Add a Bar Series, (constants are discussed later in the tutorial)
	m_Chart1.AddSeries(1);
	// Fill with random data
	m_Chart1.Series(0).FillSampleValues(10);
}

Compile the project and select the button to populate a Bar Series on the Chart.


Upgrading from TeeChart v8

Please read the whole of this section before commencing to upgrade your VC project to TeeChart ActiveX Control v2012. The following describes manual steps and a semi-automated upgrade using the TeeChart Upgrade utility.

Manual upgrade

The differences between TeeChart Pro AX v8 and TeeChart Pro AX v2012 to be considered when upgrading v8 projects are as follows:

  • 1. A VC project lists all TeeChart interface ids in the .dsp project file. The interface ids have changed between v8 and v2012 so these ids must be modified. The TeeChart utilities folder contains a conversion document, guids.txt, for interface numbers. The document is used by the Upgrade utility tool when it upgrades the .dsp file.
  • 2. Ids for TeeChart placeable components are listed in the .dsw workspace file. The TeeChart utilities folder file, AllGuids.txt lists the conversions from v8->v2012 for these ids.
  • 3. The project .rc file contains the interface GUID for placed TeeChart components. The ids should be replaced with the Version 2012 equivalents as listed in the guids.txt file.
  • 4. Most Interfaces, interfaced as TeeChart classes by VC Class Wizard, have been updated in some way between v8 and v2012. The classes can be regenerated by re-adding the TeeChart control to your project. Please not that auto-generated pragma directives are not dependably regenerated by the Class Wizard. An option is to tackle any errors as they occur, often reported as duplicate definitions, by adding a pragma directive to the Class header file:
        #if _MSC_VER > 1000
        #pragma once
        #endif // _MSC_VER > 1000
        //prevents the following compile error type:
        tchart.h(29) : error C2012: 'CTChart' : 'class' type redefinition
..or add the directives to all header files before compiling the project as a preventative measure.
..or overwite the v8 class files with the TeeChart v2012 files created and stored in the New VC classes folder below the utilities folder.

Assisted upgrade

For most conventional project types the TeeChart Upgrade utility (accessible via the TeeChart Program Manager group) can do the majority of the routine work of the upgrade.

To use the upgrade tool, start it from the icon below the TeeChart Program Manager group. Select the VC tab and select the workspace you wish to upgrade.

  • The utility will do steps 1., 2. and 3. as described in the manual steps above. Though we recommend making a backup, the process will make a backup of changed files for you if you choose to accept the option.
  • The utility will do step 4. if you selected the checkbox option to copy over class files. You can do this step yourself. Whilst normally without issue, this step is only recommended to be made with the utility if your project has been built in a standard manner with the VC project wizard.

See the Upgrading from TeeChart v5 Word document, in the 'Docs' folder, for more information about upgrading projects from TeeChart v5.


Working with TeeChart in VC

Changing Chart properties at design time

To change Chart properties at design time, right mouseclick on the Chart on the Form and select 'Properties' from the menu to display the properties window. Select the 2nd tab, TeeChart Pro Editor to display the Chart Editor. You can make changes to the Chart as described in previous tutorials.

*Note
Do not use the Chart Editor accessible via 'TeeChart Pro ActiveX Control Object' from the Mouse right Button menu when clicking on the Chart in a Form. If you Edit in this way and not via 'Properties' as described in the previous paragraph, modified properties are not permanently saved for runtime.


TeeChart events

Adding an event for the Chart on the Dialog Form is fairly straightforward. Right click on the Chart in the Form and select Events from the menu. Developer Studio offers you a list of TeeChart events. Select the event you wish to add from the list and the 'Add and Edit' button. This will add the handler and the function to the implementation file.


Coding TeeChart for runtime

MS VC adds the TeeChart classes to the project as per the steps outlined in [#QuickStart Quick start]. These can be viewed with the ClassView window. The Chart itself, here named as m_Chart1, can be accessed without further modification to the implementation file. To work with any other Class you will need to add it as an #include to the file. Take the following example, we are modifying the Chart Panel Gradient. We need to include the Classes for Panel and Gradient.

void CMyDlg::OnButton1()
{
	//Add includes
	#include "Panel.h"
	#include "Gradient.h"

	//Enable Panel Gradient
	m_Chart1.GetPanel().GetGradient().SetVisible(true);
}

Note the key difference to code described for Visual Basic in the online help file. VC requires the Get and Set of each property. In effect we are 'getting' each Class (Panel and Gradient) and 'setting' the property. The structure remains the same.

MS VC v7 makes coding considerably easier as you are now prompted with all properties and methods that relate to a Class as you type the code. You still need the header #include though.


How to apply TeeChart Online help to VC

The Online help contains a listing of declarations of Classes, Properties, Methods, Constants and Events. These can be applied with reasonable uniformity to different programming environments. TeeChart coded examples, for all environments, can be found in the [../../../Examples File:FolderIcon.png Examples folder]. The Online help also includes some examples, mostly written for Visual Basic. Due to space constraints there are far more examples in VB than VC but all principles used in VB can be applied in VC . All new concepts are presented in the TeeChart AX Feature Demo accessible via the TeeChart Program Manager menu group. The following table translates some of the VB coded expressions used in the demo to VC .

VB Expression

VC equivalent

Add method

TChart1.Series(0).Add 3, "Pears", vbRed


#include "series.h"
 
 m_Chart1.Series(0).Add(3,"Pears",RGB(255,0,0));
 

Axis Title

TChart1.Axis.Left.Title.Caption="My left axis"


#include "axes.h"
 #include "axis.h"
 #include "axisTitle.h"
 
 m_Chart1.GetAxis().GetLeft().GetTitle().SetCaption("My Left Axis");
 

Chart Title

With Chart1.Header.Text
	.Clear
	.Add("ACME Monthly Sales")
	.Add("Year: 2012")
End with


#include "Titles.h"
 #include "Strings.h"
 
 COleVariant var1(CString ("ACME Monthly Sales"));
 COleVariant var2(CString ("Year: 2012"));
 CTitles hd = m_Chart.GetHeader();
 hd.GetText().Clear();
 hd.GetText().Add(*(LPCVARIANT)var1);
 hd.GetText().Add(*(LPCVARIANT)var2);
 
 //if items (header lines) already in list (  alternative COleVariant declare syntax)
 
 m_Chart1.GetHeader().GetText().SetItem(0, COleVariant("ACME Monthly Sales"));
 m_Chart1.GetHeader().GetText().SetItem(1, COleVariant("Year: 2012"));
 

Canvas draw

TChart1.Canvas.MoveTo(0,0)
TChart1.Canvas.LineTo(100,100)
TChart1.Canvas.TextOut(50,50,"My output text)


#include "Canvas.h"
 
 m_Chart1.GetCanvas().MoveTo(0,0);
 m_Chart1.GetCanvas().LineTo(100,100);
 m_Chart1.GetCanvas().TextOut(50,50,"My output text");
 

OnGetAxisLabel event

'Add following text to Bottom Axis Labels
If aAxis = atBottom Then
  LabelText = "Period "   LabelText
End If
CString strLabel(*LabelText);
strLabel  = " Period";
strLabel.SetSysString(LabelText);

OnGetNextAxisLabel event

If Axis = atBottom Then
   MoreLabels = True
   'Only label if following cases are true
   Select Case LabelIndex
      Case 0: LabelValue = 900
      Case 1: LabelValue = 5000
      Case 2: LabelValue = 10000
      Case Else: MoreLabels = False
   End Select
End If
{
  if (Axis == atLeft)
  {
    *MoreLabels = true;

    //Only label if following cases are true
    switch( LabelIndex )
    {
      case 0: *LabelValue = 900; break;
      case 2: *LabelValue = 5000; break;
      case 1: *LabelValue = 10000; break;
      default: *MoreLabels=false;
    }
  }
}

Outputting numeric information with Canvas TextOut


  Dim value1, value2, total As Integer

   value1 = 4
   value2 = 6
   total = value1   value2

  TChart1.Canvas.TextOut 10, 10, total
  CString text;
  int value1,value2,total;

  value1 = 4;
  value2 = 6;

  total = value1 value2;

  text.Format(_T("Serie : %d"),total);

  m_Chart1.GetCanvas().TextOut(10,10,text));

Series as Datasource for Function

  ' Using Series datasource as an interface
  ' permits the input of Series from different
  ' Charts as Function datasource for a Chart Series

  With TChart1
    .AddSeries (scBar)
    .AddSeries (scLine)
    .Series(0).FillSampleValues 50

    .Series(1).SetFunction (tfAverage)

    '************************************
    .Series(1).DataSource = "Series0"

    'Or...

    .Series(1).DataSource = TChart1.Series(0)
    '************************************

    .Series(1).CheckDataSource
  End With
  VARIANT SourceSeries;

  m_Chart1.AddSeries(scBar);
  m_Chart1.AddSeries(scLine);
  m_Chart1.Series(0).FillSampleValues(50);

  m_Chart1.Series(1).SetFunction(tfAverage);

  //***********************************************************
  m_Chart1.Series(1).SetDataSource(COleVariant("Series0"));

  // Or....

  SourceSeries.vt=VT_DISPATCH;
  CSeries InputSeries=m_Chart1.Series(0);
  SourceSeries.pdispVal=InputSeries;

  m_Chart1.Series(1).SetDataSource(SourceSeries);
  //***********************************************************

  m_Chart1.Series(1).CheckDatasource(3);



Notes on use of TeeChart in Windows 98

An observation on VC /Windows 98 behaviour: When TeeChart is added to a dialog form, VC creates an IDC constant for the Chart, eg. IDC_TCHART1 = 1000. If your project later calls upon Windows 98 to assign Hwnd handles for TeeChart upon request, eg. via the GetDlgItem method then, if several TeeCharts reside on a form, Windows 98 4 digit (decimal) dynamically allocated handles may coincide with values of the IDC constants assigned to the Charts. That shouldn't be a problem, however VC treats the original constants as duplicate Hwnd handles only in the case where duplicity occurs in the same live form, overriding the true Hwnd handle for a Chart and recognising the conflicting IDC_ constant, as a conflicting Hwnd handle. To avoid this behaviour set IDC_TCHART constants to five digit values, eg. 10001. The 4 digit handles returned by Windows will therefore not coincide with the Chart constant.

The above behaviour is only limited to Windows 95 and 98 platforms. WinNT and Win2000 use a higher address range for Hwnd handles.


Notes on use of TeeChart in Visual Studio.NET

Please note that when creating a VC 7.0 (or greater) MFC Application project the TeeChart AX v2012 classes (*.cpp) and header files (*.h) have to be added manually. All the files necessary can be found under the New VC classes folder below the utilities folder; these files should be copied to your project folder (using Windows Explorer) and then should be added in to the project (in Solution Explorer -> right click over "Source Files" & "Header Files" folders -> Add Existing Item...).


Constant defines

MS VC doesn't natively support import of TeeChart constants. You need to create you own defines file and #include it in your project. We offer a pre built defines file in the [../../../Examples/Visual C File:FolderIcon.png Examples\Visual C folder]. Including the file in your project will allow you to use constants by name as matching the Enum declarations in the Online help file.

Notes about the TeeRect Structure

Generation of the TeeRect structure, as with CalenderSeries may give the following error messages:

// method 'RectCell' not emitted because of invalid return type or
parameter type
And
// method 'SeriesRect' not emitted because of invalid return type or
parameter type

The automatic code generator fails to define the structure. You can do it manually:

typedef struct tagTeeRect
{
  long Left; // Left boundery value.
  long Top; // Top boundery value.
  long Right; // Right boundery value.
  long Bottom; // Bottom boundery value.
} TeeRect;

TeeRect CCalendarSeries::RectCell(long Column, long Row)
{
  static BYTE parms[] = VTS_I4 VTS_I4;
  VARIANT vtResult;
  InvokeHelper(0xb, DISPATCH_PROPERTYGET, VT_VARIANT, (void*)&vtResult, parms, Column, Row);
  return *(TeeRect*)vtResult.pvRecord;
}

TeeRect CCalendarSeries::GetSeriesRect()
{
  VARIANT vtResult;
  InvokeHelper(0xd, DISPATCH_PROPERTYGET, VT_VARIANT, (void*)&vtResult, NULL);
  return *(TeeRect*)vtResult.pvRecord;
}

The Calendar RectCell method should function correctly with the above definition for the structure. Thanks to Glyn Thomas for this contribution.

Applied examples

Canvas example
Canvas code placed in the OnAfterdraw event will draw after each Chart redraw thus allowing its use after Zoom or Scroll.

void CVCExampleDlg::OnOnAfterDrawTchart1()
{
	// Draw line to 5th point and label it
	if (m_Chart1.Series(0).GetCount() > 4)
	{
		CCanvas cv = m_Chart1.GetCanvas();
		CAxes ax = m_Chart1.GetAxis();

		//Setup pen and brush
		//See section [#Constants Constant defines] for
		// how to define bsClear
		cv.GetPen().SetColor(RGB(0,0,0));
		cv.GetBrush().SetStyle(bsClear);
		cv.TextOut(m_Chart1.Series(0).CalcXPos(5), m_Chart1.Series(0).CalcYPos(5), "HELLO");
		cv.MoveTo(ax.GetLeft().GetPosition(), ax.GetTop().GetPosition());
		cv.LineTo(m_Chart1.Series(0).CalcXPos(5), m_Chart1.Series(0).CalcYPos(5));
	}
}


ODBC example
This example connects to TeeChart ODBC test data and displays the Chart in the form of a Pie.

#include "series.h"
 #include "valuelist.h"
 #include "marks.h"
 
 void CVCExampleDlg::OnButton5()
 {
 	// Add a Pie series and define the datasource
 	m_Chart1.AddSeries(5);
 	m_Chart1.Series(0).SetDataSource("DSN=TeeChart Pro Database; SQL=select * from employee");
 	m_Chart1.Series(0).GetYValues().SetValueSource("SALARY");
     	m_Chart1.Series(0).SetLabelsSource("LASTNAME");
 	m_Chart1.Series(0).GetMarks().SetVisible(false);
 }
 


Using the additional TeeChart Controls in VC

TeeChart Pro AX v2012 includes several controls that may be added to a project to enhance runtime functionality of a Charting application.

TeeListBox

TeeEditor

TeePreviewer

TeeCommander

TeePreviewPanel

ChartGrid

TeeListBox TeeEditor TeePreviewer TeeCommander TeePreviewPanel ChartGrid


ChartGridNavigator

ChartPageNavigator

ChartEditorPanel

SeriesTextSource

SeriesXMLSource

CrossTabSource

ChartGridNavigator ChartPageNavigator ChartEditorpanel SeriesTextSource SeriesXMLSource CrossTabSource

The controls are separately listed in the Registered Controls list when using Project & Add to Project so you will need to select and add them individually.

TeeCommander

The ChartLink property connects the TeeCommander control bar to a TeeChart.

Example

m_Commander1.SetChartLink(m_Chart1.GetChartLink());

// Set the TeeCommander Editor to use TeeEditor1
// parameters when opening the Chart Editor
m_Commander1.SetEditorLink(m_TeeEditor1.GetEditorLink());
// Set the TeeCommander Print Previewer to use TeePreviewer1
// parameters when showing Print Preview.
m_Commander1.SetPreviewerLink(m_TeePreviewer1.GetPreviewerLink());

TeeEditor

The ChartLink property connects the TeeEditor control bar to a TeeChart.

Example

m_TeeEditor1.SetChartLink(m_Chart1.GetChartLink());

// Disable the 'Add Series' and 'Help' buttons on the Editor
m_TeeEditor1.GetOptions().SetAdd(false);
m_TeeEditor1.GetOptions().SetHelp(false);

TeePreviewer

Example

m_TeePreviewer1.SetChartLink(m_Chart1.GetChartLink());

TeeListBox

Example

m_TeeListBox1.SetChartLink(m_Chart1.GetChartLink());

TeePreviewPanel

Example

m_TeePreviewPanel1.SetChartLink(m_Chart1.GetChartLink());

ChartGrid and ChartGridNavigator

Example

m_ChartGrid1.SetChartLink(m_Chart1.GetChartLink());
m_ChartGridNavigator1.SetGridLink(m_ChartGrid1.GetGridLink());

SeriesTextSource

The SeriesTextSource component permits import of text file based data into a Chart Series.

Example

// See the TeeChart VC   examples for a full working
// project with this code.
// Use the SeriesTextSourceComponent to import data
// from a text file.

// It's sensitive to decimal type in text so we do a check
// here on the machine locale.

VARIANT SeriesIndex;
LCID lcid;
CHAR lpszLang[2];

lcid=GetThreadLocale();
int rc = GetLocaleInfo(lcid, LOCALE_SDECIMAL, lpszLang, 2);

if (CString(&lpszLang[0]).Compare(CString(","))==0) {
        m_TextSource1.SetFilename("SurfaceDataComma.txt"); //use comma decimal separator
}
else {
        m_TextSource1.SetFilename("SurfaceDataPoint.txt"); //use point decimal separator
}

SeriesIndex.vt=VT_INT;
SeriesIndex.intVal= m_Chart1.AddSeries(scTriSurface);

// The following line only necessary if SeriesIndex as VT_INT.
m_TextSource1.SetChartLink(m_Chart1.GetChartLink());
m_TextSource1.SetSeries(SeriesIndex);
m_TextSource1.SetFieldSeparator(";");
m_TextSource1.AddField("x",1);
m_TextSource1.AddField("y",2);
m_TextSource1.AddField("z",3);
m_TextSource1.SetActive(true);

SeriesXMLSource

The SeriesTextSource is non-visible at run-time. It allows data to be brought in from XML files to specified Chart series. Use this compenent's methods and properties to define or modify the data's fields and field delimiters and to set the location of the XML file as a path, URL or stream.

Example

VARIANT SourceSeries;
m_Chart1.AddSeries(1);

SourceSeries.vt=VT_DISPATCH;
CSeries InputSeries=m_Chart1.Series(0);
SourceSeries.pdispVal=InputSeries;

m_SeriesXMLSource1.SetFileName("http://www.steema.com/SampleData.xml"); //This can also be a local file
m_SeriesXMLSource1.SetSeries(SourceSeries);
m_SeriesXMLSource1.SetSeriesNode("USA");
m_SeriesXMLSource1.SetValueSource("Bar");
m_SeriesXMLSource1.Open();

CrossTabSource

The CrossTabSource is non-visible at run-time. CrossTabSource component connects to any dataset and automatically creates series from database data, using Group and Label fields and formula (sum or count values).

Example

void CAXv6VC60MFCDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CDialog::OnShowWindow(bShow, nStatus);

	VARIANT SourceSeries;
	m_Chart1.AddSeries(1);

	SourceSeries.vt=VT_DISPATCH;
	CSeries InputSeries=m_Chart1.Series(0);
	SourceSeries.pdispVal=InputSeries;

	m_CrossTabSource1.SetSeries(SourceSeries);
	m_CrossTabSource1.SetGroupField("Terms");
	m_CrossTabSource1.SetLabelField("Paymtype");
	m_CrossTabSource1.SetValueField("Amntpaid");
	m_CrossTabSource1.SetDataSet(COleVariant("DSN=TeeChart Pro System db; SQL=select * from orders"));
	m_CrossTabSource1.SetActive(true);

	m_Chart1.RefreshData();
}

void CAXv6VC60MFCDlg::OnButton1()
{
	CString tmp;
	tmp = m_CrossTabSource1.GetGroupField();
	m_CrossTabSource1.SetGroupField(m_CrossTabSource1.GetLabelField());
	m_CrossTabSource1.SetLabelField(tmp);
	m_CrossTabSource1.SetActive(true);
	m_Chart1.RefreshData();
}



PREVIOUS

NEXT


© 1998-2019 Steema Software SL. All rights reserved.