SRGDataWatcher
SRGDataWatcher is another Objective Chart component that can be created and added to the component list. The data watcher’s primary function is to scan the data; not to draw it.
In standard charts, one or more data watchers can be added to the component list immediately before the display component on which it acts. Being positioned before the display allows the data watcher to modify style settings for out-of-range data items to highlight them.
SRGDataWatcher is derived from SRGGridLines. This hierarchy is shown in a figure in Chapter 18, “Compound Component System.” The data watcher can optionally draw its limit lines on its associated display.
Data may be watched for the conditions outlined in Table 24:
Table 24 – SRGDataWatcher 
Condition
Description
CX_SCAN_ABOVELIMIT
All data must be below the limit.
CX_SCAN_BELOWLIMIT
All data must be above the limit.
CX_SCAN_AVERAGEABOVELIMIT
The average of the data in the scope must be below the limit.
CX_SCAN_AVERAGEBELOWLIMIT
The average of the data in the scope must be above the limit.
CX_SCAN_INBRACKET
All data must remain in the range defined by the upper and lower limits.
CX_SCAN_OUTOFBRACKET
All data must remain outside of the range defined by the upper and lower limits.
CX_SCAN_AVERAGEINBRACKET
The average of the data in the scope must remain within the range defined by the upper and lower limits.
CX_SCAN_AVERAGEOUTOFBRACKET
The average of the data in the scope must remain outside of the range defined by the upper and lower limits.
CX_SCAN_CUSTOM
A custom routine is called which decides the validity of the data according to parameters defined in the user application.
The function SetScanType() selects the desired limit condition. SetHighLimit() and SetLowLimit() set the limit values.
NOTE >> For the conditions that require only one limit, use SetHighLimit().
During the processing of its Draw() function, the SRGDataWatcher scans the data to be plotted.
For half of the limit conditions, each data value is compared to the limit condition. For each data value, either MarkExcursion() or UnMarkExcusion() is called depending on whether the out-of-range condition is met. MarkExcursion() sets the highlight flag to CX_HIGHLIGHT_MEDIUM in the data item’s style member and calls FlagExcursion(). FlagExcursion() does nothing, but it can be overridden to perform some sensible application-specific task, such as incrementing a counter or changing other style flags. UnMarkExcursion() just resets the highlight flag to CX_HIGHLIGHT_NONE.
The other limit conditions compare the average of the data values to the limits. For these conditions, MarkExcursion() and UnMarkExcursion() are not called, and data items are not highlighted.
For all limit conditions, ScanData() calls either DataInRange() or DataExcursion() once, depending on whether any data values were out of range. Both of these functions do nothing, but they can be overridden to perform some sensible task such as displaying a message, sounding a warning, or taking corrective action.
The following sections provide details about using a data watcher in a chart.
Using a Data Watcher
One or more data watchers can be used with a standard SRGraphDisplay. The data watcher finds the first display component after it in the component list. The data watcher obtains the data scope and other information from this display.
When used in conjunction with a compound display (as described in Chapter 18, “Compound Component System”), the SRGDataWatcher is registered with and managed by an SRGAxisManager object. Then the data watcher uses information from the display component of the same axis manager.
The data watcher can draw a line (or lines) on the graph indicating the limit level(s). Because SRGDataWatcher is derived from SRGGridLines, the appearance of its line(s) can be modified in the same way as grid lines.
NOTE >> Currently the data watcher fully supports only charts with one group per series. For other chart types, only the data values in the first group can be scanned. Use SetScope() and SetGroupStep() to limit the data objects to be scanned.
NOTE >> Currently the data watcher does not correctly draw lines on displays with logarithmic axes.
To set up a typical data watcher with a standard display:
 
SRGDataWatcher *pDW=new SRGDataWatcher;
// set condition and limit values
pDW->SetScanType(CX_SCAN_OUTOFBRACKET);
pDW->SetHighLimit(25.4*120); // Ten feet in mm
pDW->SetLowLimit(25.4*36); // Three feet in mm
// use following display’s scope
// instead of all the data in SRGraph list
pDW->SetLinkToDisplay(TRUE);
pDW->SetVisible(TRUE); // draw limit lines
// set number of groups per series, if more than 1
pDW->SetGroupStep(2);
mGraph.AddComponent((SRGraphComponent*)pDW);
 
// the display must follow
SRGraphDisplay* pD = new SRGraphDisplay;
To set up a data watcher in a compound display, see the CChart example in Chapter 18, “Compound Component System.”
Customizing a Data Watcher
To implement a limit condition that is not provided:
*Specify the custom scan condition— SetScanType(CX_SCAN_CUSTOM).
*Override SRGDataWatcher::ScanCustom().
To perform a custom task for each out-of-range data item, override SRGDataWatcher::FlagExcursion().
To perform a custom task when an out-of-limit condition occurs, override SRGDataWatcher::DataExcursion().
To perform a custom task when all data are within limits, override SRGDataWatcher::DataInRange().