Structure Data Model
The Standard and Dynamic data models store the chart’s data in special objects that are created and destroyed automatically (more or less) by the main chart object. In this sense, these data objects are internal to the chart system.
Objective Chart also supports more general data access from external memory buffers.
Data logging applications, for example, often acquire measurements of a fixed number of variables repeatedly over time. They store all the measurements from one observation cycle in a block or structure, followed by a similar block for the next observation. The values of the different variables often require different storage space. The resulting data buffer can be thought of as an array of structures, where each structure contains the various data types required for all the variables.
The Structure data model provides access to data within this external array of structures. The data values for a selected variable can be accessed in situ. No replication or movement of the data is required.
This concept of an array of structures is quite general. The structure can be a single variable of a simple data type. Or, it can be an array itself— even a multidimensional array. The details of the Structure data model are presented in the following topics.
NOTE >> Any memory block in which the data values to be plotted are uniformly spaced in memory is a candidate for access using the Structure model.
SRGStructureData
SRGStructureData is an abstract class that forms the basis of the Structure data storage model. Derived from SRGraphDynamicData, SRGStructureData provides a same set of methods for extracting data from any array of structures. The same data access functions are used regardless of the memory model used.
SRGStructureData maintains a set of pointers and indices that are used to access the data. These members are shown in Figure 120.
Figure 120 – The SRGStructureData object
The following example illustrates how these variables are used to access data in a memory block. The code below defines a simple C++ structure, MyStruct.
 
struct MyStruct
{
int nTemperature;
double dHeight;
float fHumidity;
};
An array of these structures would produce the memory block that is shown in Figure 121.
Figure 121 – How SRGStructureData accesses memory
After initialization:
*m_pStructure points to the start of the memory buffer.
*m_DataOffset defines the position of the first data item within the buffer.
*Alternatively, m_pStructure can point to the first data item with m_DataOffset set to 0.
*m_nStructureSize is the increment used to step from one data item to the next – the structure size in this case.
*m_nBufferSize (in SRGraphDynamicData) contains the number of structures in the buffer or the number of data items to be found.
Data-type Specific Classes
SRGStructureData is an abstract class. A class derived from SRGStructureData must be used to access the memory block. Objective Chart assumes that all data to be plotted is a double precision floating-point number, but the members of the structure may be of any numeric data type. Therefore, several classes, based upon SRGStructureData, are provided to handle various data types.
The following derived classes are provided:
*SRGIntStructData is designed to extract integers.
*SRGShortStructData extracts short integers.
*SRGFloatStructData extracts single precision floating-point numbers.
*SRGCharStructData extracts byte-sized numbers.
*SRGDoubleStructData handles double precision floating-point numbers.
Classes to extract other data types can be derived by simply adding new overloads of the GetValue() and SetValue() functions, following the example shown by these classes. The Chart AppWizard can create a skeleton implementation for new Structure data classes.
Structure Model Features
The Structure data model has these features:
*Data values are stored (uniformly spaced) in an memory buffer external to the chart classes.
*Structure data stores only data values. It does not store individual styles, annotations, or null flags. An annotation, style, and null flag are stored only in the SRGraphDynamicData (base class) object itself. Any request for annotations, style settings, or null status from an indexed data value always returns the annotation, style setting, or null flag from this object.
*Structure data objects can not be individually styled.
*Options for axis labels and feedback are limited. Annotations must be generated programmatically in an override of SRGraphDynamicData::GetAnnotation().
*Data values can not be individually flagged as invalid or null.
*SRGStructureData does not maintain a hi-low history for the data. It can not be used with graph types that require hi-low information.
*The data buffer exists outside of Objective Chart. The chart is not free to change its size or reorder the values. Setup simply involves setting the address, spacing, and number of data items.
*The model provides rapid sequential access. Nonsequential access speeds are expected to be between the speeds of the other two models.
*Users are responsible for inserting or deleting values. Data rolling is not supported.
Using the Structure Model
To initialize a chart using the Structure data storage model:
1. Create an SRGraph or SRDynamicGraph object in your application.
2. Create an SRGraphDataList object for the desired group.
3. Create and initialize a Structure data object.
4. Add the prepared Structure data object to the SRGraphDataList object of the selected group.
Once configured, the Structure data buffer can be accessed with the same GetValue() and SetValue() functions that are used in the Standard model. Different Structure classes are provided for a variety of data types. In addition, the SetValue() and GetValue() functions of the Structure data classes can be used for more direct, sequential access.
Integrating these classes with the Objective Chart system is simple. Continuing the MyStruct example, the following code sets up an SRGIntStructData object to display the temperature member of the MyStruct structure.
 
// My array of structures
MyStruct* m_pData=new MyStruct[30000];
 
// My graph object
SRGraph m_Graph;
 
// Create a data list object for our group
SRGraphDataList* pDL=m_Graph.GetGroup(0);
 
// Create a structure data object
SRGIntStructData* pSD=new SRGIntStructData;
 
// Initialize the structure data object
// Tell the object how many items are in the buffer.
pSD->SetBufferSize(30000); // number depends on app!
 
// Initialize the structure stepping variable
pSD->SetStructureSize(sizeof(MyStruct));
 
// Set pointer to the first data value
pSD->SetStructure(&(m_pData->nTemperature));
 
// Leave offset as 0
pSD->SetDataOffset(0);
 
// Specify that data are available
pSD->SetNull(FALSE);
 
// Specify that data are dynamic
pDL->SetDynamic();
 
// Add Structure data object to the data list
pDL->AddTail(pSD);
Now the chart components can read integers from the external memory block and plot them on the screen. The ExData sample application demonstrates the use of the Structure data classes.