If you use the Pie function to create pie charts, the size of each pie wedge will be based on the relative sizes of data items. This involves calculating starting and ending points of the pie figures that are derived from the internal angle of the pie wedge.
It's time for a trigonometry refresher. In a Cartesian coordinate system (with x increasing to the right and y increasing as it moves up), we can draw a triangle like this:
The relationship between each of the three sides of the triangle and the angle Þ is given by the formulas:
sin (Þ) = y/r
cos (Þ) = x/r
tan (Þ) = y/x
If you know the angle Þ (which in a pie chart will be a fraction of a circle) and r (which will be the radius of the circle), you can determine that the point (x, y) is equal to:
(r * cos (Þ), r * sin (Þ))
In the C library functions sin and cos, angles are specified in terms of radians. There are 2 * PI radians in 360 degrees.
Let's try drawing a pie chart that uses five numbers. For convenience, we'll set this condition with a #define statement:
#define NUM 5
In a real program, that would be a variable.
You'll also find it convenient to define an identifier called TWO_PI that is the number of radians in a circle:
#define TWO_PI (2.0 * 3.14159)
Next you define some variables:
static short nValues [NUM] = { 3, 5, 2, 7, 4 };
short i, nSum [NUM + 1] ;
The initialized values in nValues are the data we'll be graphing. In a real program, these values would be variables. The nSum array is set to the accumulated sum of the data values where the first element of the array is set to 0:
nSum [0] = 0 ;
for (i = 0 ; i < NUM ; i++)
nSum [i + 1] = nSum [i] + nValues [i] ;
The array element nSum [NUM] is the sum of the five values.
Now we are ready to start drawing the pie chart. Set the mapping mode to MM_ISOTROPIC, which is the mode in which you can most easily draw a circle:
SetMapMode (hdc, MM_ISOTROPIC) ;
SetWindowExt (hdc, 400, 400) ;
SetViewportExt (hdc, xClient, -yClient) ;
SetViewportOrg (hdc, xClient / 2, yClient / 2) ;
The logical point (0, 0) is the center of the client area, and the x- and y-coordinates define a normal Cartesian coordinate system.
Our pie has a radius of 100 logical units. Here's the code to paint the five pie segments:
for (i = 0 ; i < NUM ; i++)
Pie (hdc, -100, 100, 100, -100,
(short) (100.0 * cos (TWO_PI * nSum [i] / nSum [NUM])),
(short) (100.0 * sin (TWO_PI * nSum [i] / nSum [NUM])),
(short) (100.0 * cos (TWO_PI * nSum [i + 1] / nSum [NUM])),
(short) (100.0 * sin (TWO_PI * nSum [i + 1] / nSum [NUM]))) ;
The pie chart produced from this code is shown in Figure 12-11. The first pie wedge is at the right of the pie chart, just above the x-axis. The other pie wedges are drawn in a counterclockwise direction.
The values:
TWO_PI * nSum [i] / nSum [NUM]
and:
TWO_PI * nSum [i + 1] / nSum [NUM]
are ratios of the accumulated sum of the items to the total sum of the items converted to angles that are measured counterclockwise from the horizontal. The second formula includes the item that the particular pie wedge represents; the first does not. By taking the cosine and sine of these angles and multiplying by 100, we're calculating the starting and ending points on the circle.