GD2+ Doughnut Chart

Please Note: Due to running GD2.0.12 at the moment on this server, the anti-alias facility of the function had to be set to zero (the anti-alias effect is achieved through an iterated ImageCopyMerge loop which has snags in 2.0.12). As such, all the shown graphs look a tad jaggedy and don't really do the function justice. If you run a different version of GD I advise adding an anti-alias of between 10 and 20 to smooth the edges.

Note: My next 'on the agenda' task is compiling a class distribution of the DataGraphs which will involve slightly different calls and a better anti-aliasing algorythm. Feel free to use the single function distros for a while and upgrade to the class later on.

Major Usage Warning The process algorythm used within this function iterates through a nested loop to determine the colour for each doughnut pixel. At roughly 200,000 iterations, server resource usage is relatively high and results in a script processing time of several seconds. As such, you should not generate on-the-fly graphs with this function.
Cache a generated graph at specific intervals (eg once a day for web stats / when a vote is cast for polls) and link to the cached image.
I repeat. Do not ever run this script at every page load.

Download the GD2+ Doughnut Chart Function
downloaded 1479 times from this site.


This class is freely available for use in any non-profit applications, though a note to say you are using it would be appreciated. If you require it for a more commercial project, please contact me.

coloured doughnut chart The doughnut chart is a method of showing statistical data in a visual format using a system similar to the more common pie chart.
An associative array of input data will be automatically converted to percentage sections of a circular tube (as per the shown images).
Many parameters can be passed to the function (most with default values) to dictate exactly how the chart is rendered.
The basic width and height of the doughnut area can be set as pixel values. These will also govern the output size of the full image depending upon where the legend is placed.
The name and path of the server saved image can be passed as a string parameter.
Colours are attributed through passing an array with various indices to the function. The index 'bg' defines the background colour and a gradient can be used by passing two indices 'fg1' and 'fg2'. Using the gradient indices will cause the script to determine each segment colour as a proportional step running from 'fg1' at front left to 'fg2' at front right. Alternatively you can define every colour used as an array value within the 'colours' index (see usage notes and sample calls). gradient doughnut chart

The legend can be shown on the right of the doughnut by passing the string 'right' as a parameter. Using the string 'below' will render the legend below the chart, while all other strings will cause no legend to be shown. The size of the output image is determined by where the legend lies.
'right' => 2*width by height
'below' => width by 2*height
Percentage values in the legend can be toggled with a simple 'yes' / 'no' parameter.
Anti-alias strength is the last possible parameter for the function and governs how strongly the edges should be smoothed. Values between 5 and 20 should be fine for builds where the ImageCopyMerge function of GD is behaving properly.
Hardcoded within the function itself is a text colour setting and jpeg compression/quality value which can both be amended manually if required.

You may need to experiment with a few width and height values before using this system on a page. Generally a height = 50-90% of width relation should be ok visually. Also note: values between 125 and 375 are best as smaller or larger charts will render worse.

Sample Calls and Usage Notes

You may like to copy/paste the below as a textual reference for using the function.

Warning Version 2.0.12 (and possibly 2.0.10 - 2.0.15) of the GD libraries has snags with the ImageCopyMerge function which is used in the anti-alias effect. Make certain you set anti-alias to zero for all troubled builds (noticable by the image suddenly becoming badly jagged and shades of black)

Function Parameters

doughnut_chart(
Data Array, (array) associative 'title'=>value, array of segment text and value pairs
Doughnut Width, (int) pixel width of doughnut chart only - image will be double that if legend set to 'right'
Doughnut Height, (int) pixel height of doughnut chart - image height doubled if legend set to 'below'
Save Name, (string) XXXXX.png => png output, else jpeg (directory may need chmod setting)
Colours Array, (array) associative array of hex values for colours - see below/above
Legend, (string) 'below' or 'right', else no legend shown
Show Percents, (string) 'yes' => % values shown in legend, else no
Anti-Alias, (int) strength of antialiasing 0=off (needed for version 2.0.12 of GD) values 5 to 20 are suitable
);

All parameters except the first (the data) are optional and will default to values as defined in the actual function.

Sample Call: Gradient Segments - Legend on Right with Percentages - png output

include_once('function_doughnut_chart.php');
$data = array('title 1'=>14, 'title 2'=>23, 'title 3'=>8, 'title 4'=>23, 'title 5'=>45, 'title 6'=>21);
$colours = array('bg'=>'C3DDEE','fg1'=>'333333','fg2'=>'FFFFFF');
doughnut_chart( $data, 200, 150, 'graphs/donut.png', $colours, 'right', 'yes', 0);

Precompiling the associative array for the data tends to make the code more readable and thus easier to debug. Here we have six indices holding integer values.
The array of $colours below is where we define the processed colours for the background and segments. The 'bg' index should be self explanatory, holding a hex value for the image background. The next two are set index names to force a gradient process.
'fg1' => hex# - this is the colour used for the first segment (this will be the largest segment as the data array is sorted highest first before drawing commences).
'fg2' => #hex - this is the last colour used (smallest segment). All the segments in between will be shown in a colour determined as a proportioanl step from the fg1 colour to the fg2 colour.
Our call to doughnut_chart() passes the $data array, width, height, save name (ending with 'png' forces a .png file output), the $colours array, the legend setting, toggle string for showing percentages in legend and finally the anti-alias (set to zero here - maybe due to using GD2.0.12).

Sample Call: Defined Colours - Legend below with No Percentages - jpeg output

include_once('function_doughnut_chart.php');
$data = array('title 1'=>14.82, 'title 2'=>23.01, 'title 3'=>8.69, 'title 4'=>23.19);
$colours = array(
            
'bg'=>'C3DDEE',
            
'colours'=>array(
                
'F49999',
                
'C47878',
                
'782121',
                
'953434',
                
'A94545'));
doughnut_chart( $data, 180, 140, 'graphs/donut.jpg', $colours, 'below', 'no', 0);

Similar to the first sample call, we precompile both the data array and colours array. This time though we want to define seperate colours for every segment in turn. Leaving out the 'fg1' and 'fg2' indices, we instead add an index called 'colours' which in turn is an array. Note: there must be at least as many indices in the $colours['colours'] array as there are in the data array. In the example above I have added one more value to the colours array than to the data array - the last colour will not be used.
The call to doughnut_chart is also very similar, passing the data array pointer, width, height, save name (as the last three characters are not 'png' the output will be a jpeg) and colour array pointer. . Now we have used the string 'below' to place the legend and have toggled the show percentages setting to 'no'. Again we have used an anti-alias of zero.

Most of the parameters are optional and will default to values hardcoded within the function definition. Only the first parameter has to be sent. You could simply hardcode new values into the definition and just run very basic calls of doughnut_chart($data, 180, 150, 'savename.png'); to save having to think too much every time.

Anyway, enjoy.

SiteMap