Chapter 4:
The Data Interface
|
The library supports these methods of providing data for charting: |
|
|
|
Callback functions |
|
|
SEND_DATA Interface |
|
Your application can use only one of these methods in a chart. |
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
The callback configuration of the DLL requires your application to provide a callback function. The function is called by the DLL with a row and column number to provide the data for charting. This configuration is best when your application is already buffering the data to be graphed. For example, your application collects the data from a database, a mainframe, a network, proprietary file format, etc., and buffers it for other purposes. Each time the graph is drawn the DLL calls your function to provide each data point and string for the chart. The following call-back functions are defined in the header file: |
|
|
|
CALLBACK *LPFNGetDataCallBack |
|
|
CALLBACK *LPFNGetLabelCallBack |
|
|
CALLBACK *LPFNGetStringCallBack |
|
|
CALLBACK *LPFNSetPageCallBack |
|
|
CALLBACK *LPFNRealToStringCallBack |
|
|
CALLBACK *LPFNGetRawLimits |
|
|
CALLBACK *LPFNPictureCallBack |
|
This data interface calls a function in your application. A parameter points to a location for your function to load the requested data. The library does not buffer the data; once the data is charted, the data is overwritten with the next piece of data for charting. This data interface is best when your application already buffers the data. This prevents double buffering of the data by the library. Each time the chart is drawn by DrawTheGraph(), the data is requested from your application. |
Initializing the Data Callback Functions
|
The library requires pointers to the data callback functions in your application. The following example demonstrates how to initialize the callback functions: |
|
BOOL PUBLIC InitDataCallBacks( |
|
{ |
|
/* If the data information doesn't */ |
|
{ |
|
/* Good practice to explicitly */ |
|
/* always set datalook-related info */ |
|
/* Set to number of rows to graph */ |
|
/* Set to number of columns to graph */ |
|
/* PUT HANDLE TO THIS GRAPH INTO A FIELD THAT IS |
|
Note that the graphData structure contains the number of rows and columns. That is because the data is organized like a spreadsheet. Do not confuse the rows and columns with series and groups. |
|
This function provides the actual data for charting. The library resolves series and groups to the way your application data is stored as rows and columns. This means your application should NOT try to swap rows and columns when the data axes are reversed. Your application data model should be similar to a spreadsheet, with data stored in rows and columns. The illustration below shows the spreadsheet style data model: |
|
|
|
The prototype for the data callback function pointer describes each of the parameters passed to your application callback. |
|
typedef INT16 (CALLBACK *LPFNGetDataCallBack) |
|
Your application data value must be a REAL64 when passed to the library. If necessary, cast the value to a REAL64. Sample code for the data callback function is shown below: |
|
int NumData1 [4][3] = |
|
If you want to change the size of an existing chart, your application should get the GraphDataInfo structure using GetGraphDataInfo(). Use SetGraphDataInfo() to modify the number of rows and columns in the chart. You do NOT need to reinitialize the callback function pointers if you are using the same callbacks to provide data to the library, only change the number of rows and columns. Return FALSE if the data is missing or if you want to skip this data point. |
|
This function provides the strings used to draw the charts group labels and the legend series labels. The library resolves series and groups to the way your application data is stored as rows and columns. This means your application should NOT try to swap rows and columns when the data axes are reversed. Your application data model should be similar to a spreadsheet, with data stored in rows and columns. |
|
|
|
The prototype for the label callback function pointer describes each of the parameters passed to your application callback: |
|
typedef INT16 (CALLBACK *LPFNGetLabelCallBack) |
|
A row label is requested when nCol is equal to -1. A column label is requested when nRow is equal to -1. The example of the label callback function shown below uses a global array to store the strings. Make sure you check the string length before copying a string into the buffer area. Return FALSE if the label is missing or if you want to skip this label. |
|
char StringData[12][64] = { |
|
The string callback function provides the strings used to draw the following chart titles: |
|
|
|
title |
|
|
subtitle |
|
|
footnote |
|
|
series title |
|
|
group title |
|
|
X, Y1, Y2, and Z-axis titles |
|
|
|
|
The prototype for the string callback function pointer describes each of the parameters passed to your application callback. |
|
|
typedef INT16 (CALLBACK *LPFNGetStringCallBack) |
|
|
The constants used for the ordinal ID number (nWhich) are defined in the enum structure GraphDataStringType in the header file: |
|
|
typedef enum _GraphDataStringType { |
|
|
The example of the string callback function shown below uses a global array to store the strings. Make sure you check the string length before copying a string into the buffer area. Return FALSE if the requested string is missing or you do not want to set a particular string. |
|
|
char StringData[12][64] = |
|
|
INT16 FAR PASCAL LOCAL_GetStringCallback( |
|
|
{ |
|
|
case gsTITLE: |
|
|
case gsSUBTITLE: |
|
|
case gsFOOTNOTE: |
|
|
case gsSERIESTITLE: |
|
|
case gsY1AXISTITLE: |
|
|
case gsGROUPSTITLE: |
|
|
case gsXAXISTITLE: |
|
|
default: |
|
This call back function provides the current graph page: |
|
typedef INT16 (CALLBACK *LPFNSetPageCallBack) |
|
This function is only used for 3D stacked charts. |
Real-to-String Callback Function
|
This callback function passes object, series, and group information: |
|
typedef INT16 (CALLBACK *LPFNRealToStringCallBack) |
|
The following example is a simple utility function that formats a numeric value of type REAL64 into a string. If any piece of numeric data has its nformat code (A2D_FORMAT_xx) set equal to or greater than 60, this callback is triggered. This lets you do your own custom numeric formatting instead of using built-in PGSDK logic. |
|
INT16 FAR PASCAL LOCAL_RealToStrCallback( |
|
This function provides the raw limits of the chart. The raw limits represent the actual range of values in the chart data set. |
|
typedef BOOLEAN16 (CALLBACK *LPFNGetRawLimits) |
|
Normally, PGSDK does a complete scan through the data before imaging a chart. This allows the system to determine the minimum and maximum values for any axis. If you want to optimize performance or disable the minimum/maximum logic, you can register this call back. If registered, PGSDK will NOT scan the data. Instead, it will call this function and use the minimum/maximum values that are provided. |
|
This callback function can be used when the user has a specified a handle for a picture: |
|
typedef INT16 (CALLBACK *LPFNPictureCallBack) |
|
Set lpbIsAPM to TRUE for an APM metafile. For an APM metafile, use lpAPMbox, to specify a rectangle in world coordinates. |
|
This function is only used when special affects are created with A_AREASFX. |
|
The Send Data Interface provides API functions for your application to load the strings and data directly into the chart object for buffering. This configuration is best when your application can get the data but does not keep it buffered. The graph uses the same data for drawing until your application explicitly loads new data. When a graph is saved to an output file both the graph and the data can be saved in the output file. |
|
Using the send data interface, your application must send all the charting data to the chart for buffering. The data is sent to the chart using API function calls. This interface is best when your application has access to the data but does not buffer it. For example, when the data is stored in a disk file, your application could retrieve the data once, and send it to the library for buffering. Each time the chart is drawn, the library retrieves the data from its own internal storage and draws the chart. |
Initializing the Send Data Interface
|
The library GraphDataInfo structure must be initialized to set the number of rows and columns for data and to initialize the library for the send data interface. The example shown below demonstrates how to initialize the library. |
|
BOOL PUBLIC InitDataCallBacks( |
|
Note that the structure contains the number of rows and columns. That is because the data is organized like a spreadsheet. Do not confuse the rows and columns with series and groups. Do not initialize the callback function pointers in the data structure, leave them set to NULL. |
|
These API functions are provided to send data to the library for buffering. |
|
|
|
GetGraphFootNote()/SetGraphFootNote() |
|
|
GetGraphGroupsLabel()/SetGraphGroupsLabel() |
|
|
GetGraphGroupsTitle()/SetGraphGroupsTitle() |
|
|
GetGraphSeriesLabel()/SetGraphSeriesLabel() |
|
|
GetGraphSeriesTitle()/SetGraphSeriesTitle() |
|
|
GetGraphSubTitle()/SetGraphSubTitle() |
|
|
GetGraphTitle()/SetGraphTitle() |
|
|
GetGraphY1AxisTitle()/SetGraphY1AxisTitle() |
|
|
GetGraphY2AxisTitle()/SetGraphY2AxisTitle() |
|
|
GetGraphDataInfo()/SetGraphData() |
|
See the PGSDK API Guide for a description of these API functions that support the send data interface. |