Overriding DrawXXXLabels()
Changing the Standard Behavior of Axis Labels
The scale objects (SRGDecimalScale, SRGLogScale, SRGIndexScale, etc.) that create the axis labels have settable parameters that control the appearance and spacing of axis labels. Because SRGraphDisplay::DrawXXXLabels() creates, configures, updates, and destroys the scale objects internally, these parameters are not readily accessible to the programmer.
Changing the standard behavior requires the definition of a new class derived from SRGraphDisplay (or one of the graph-type specific display classes) with an override of the appropriate DrawXXXLabels() function. A copy of the body of the function from the library provides the starting point for your modifications. Once your have taken this step, the axis labels can be changed in a variety of ways.
A more technically correct procedure is to define a custom axis type and override DrawCustomLabels() as described later in this chapter.
Note: Be sure to modify your chart setup code to instantiate your new class instead of SRGraphDisplay and set the axis style to your custom axis type, if appropriate.
For the following discussion, we assume that DrawClassicLabels() is the function being overridden. The specific changes described may not be appropriate for other DrawXXXLabels() functions.
Modifying the Interval Between Labels
You can control the number of labels that are generated by setting the resolution (the interval between labels). The scaling system in Objective Chart makes setting the resolution for SRGDecimalScale unnecessary in most cases. But it is still useful for SRGIndexScale. In this case, the resolution is a skip factor: 1 gives a label for each index, 2 gives a label for every other index, 3 every third, etc.
To modify the interval between labels, call SetResolution() during the setup of the scale object before calling CreateLabels().
SRGDecimalScale *pDS=new SRGDecimalScale;
pDS->SetResolution(10.0); // ten centimeters
or
SRGIndexScale *pDS=new SRGIndexScale;
pDS->SetResolution(5); // every fifth data object
SetResolution(0) lets the scale object chose the interval between labels.
Changing the Number of Digits and Adding Text for Units
To change the number of digits or add text for units, call SetFormatString() during the setup of the SRGDecimalScale object before CreateLabels().
SRGDecimalScale *pDS=new SRGDecimalScale;
pDS->SetFormatString(“%g cm”);
or
pDS->SetFormatString(“%.3f”);
Avoiding Overlapping Labels
To avoid overlapping or too-close-together labels, call SetCheckOverlaps(TRUE) for the label block in your override of DrawXXXLabels().
You can choose to hide the overlapping labels or to move them. For example,
SRGDecimalScale* pDS=new SRGDecimalScale;
pDS->SetCheckOverlaps(TRUE);
pDS->GetStyle()->SetLabelStyle(CX_LABELBLOCK_MOVELABELS);
// or SetLabelStyle(CX_LABELBLOCK_HIDELABELS);
Alternatively, you can rotate the labels to 45 or 90 degrees to avoid overlap.
SRGDecimalScale* pDS=new SRGDecimalScale;
pDS->GetStyle()->SetAutoOrientation(FALSE);
pDS->SetOrientation(45.);
pDS->SetLocationPoint(SRGraphLabel::MidRight);
Creating Unevenly Spaced or other Specific Labels
If you really want to control which labels are created, you can derive a new class from one of the scale classes and override CreateLabels() to generate any labels you want.
For example, you could override SRGIndexScale::CreateLabels() to generate a label for each index i such that (i+5)%nResolution==0. Then modify your DrawXXXLabels() override to use your new scale class.
Or, you could override SRGDecimalScale::CreateLabels() to generate a fixed number, say 5, of labels.
Derive your own class from SRGDecimalScale and override CreateLabels() to generate labels however you want.
Override the appropriate DrawXXXLabels() routine for the graph type— generally DrawClassicLabels()— to utilize your new scale class instead of SRGDecimalScale.
The SimpleCustom sample project overrides DrawClassicLabels() to orient the x-axis labels at 45 degrees and to add units to the y-axis labels.
The USDChart sample is a more elaborate customization. Its display class overrides DrawLineData(), DrawClassicLabels(), DrawClassicAxis(), DrawScatterData(), and DrawScatterLabels() to create a Y-axis with the origin at the top and with values increasing downward. SRGraphPosition is subclassed also, and the view class contains an override of GetPosition() that uses the new graph position class. This axis could be used for displaying temperature versus depth in the ocean, for example.






