#native_company# #native_desc#

Bar Charts With GD Page 5

By Stefan Wiesendanger
on December 17, 2000

Plotting Vertical Columns And X Labels
Plotting the labels is basically just a repetition of what’s been done before for the
Y axis, with slightly changing X and Y positions. The only thing to consider is that if
the labels (i.e. the array keys taken from $data) are too big to fit in the
width of a column ($base), they will overlap. However, since the code uses
relative sizes all along, this can easily be corrected by just using a bigger
We draw the vertical columns as filled rectangles in navy blue. This requires that we
know the X and Y limits of the rectangle. In the vertical Y direction, we use a scaling
factor that represents the number of pixels for one data unit. In our case, that would be
the number of pixels per percentage point. In the X direction, the width of the column is
just the distance between columns – $base – less some right and left padding.


// columns and x labels 

$padding 3// half of spacing between columns 

$yscale $ysize / (($ngrid+1) * $dydat); // pixels per data unit 

for ($i 0; list($xval$yval) = each($data); $i++) { 

    // vertical columns 

$ymax $vmargin $ysize

$ymin $ymax - (int)($yval*$yscale); 

$xmax $hmargin + ($i+1)*$base $padding

$xmin $hmargin $i*$base $padding


    // x labels 

$txtsz imagefontwidth($labelfont) * strlen($xval); 

    $xpos $xmin + (int)(($base $txtsz) / 2); 

$xpos max($xmin$xpos); 

$ypos $ymax 3// distance from x axis 



The final result of this whole effort looks like this:
final result of Presidential Approval Rating chart
What Remains To Be Done
You may note in the chart above that there seems to be a slight glitch for the first
value. In January, approval was 55% but the column just reaches the 54% grid line.
Actually, the grid line is at 54.75%. The cast to (int) used for the
Y labels seems to truncate instead of rounding. If this bothers you, use the correct
rounding function instead: floor($positive_value_to_round + 0.5).
Another possibility is to never do casts and format numbers using sprintf().
To create more fancy graphs, you can fill the columns with a pattern loaded from
another image file. In fact, the stretching of small GIFs we’ve described in the
“Alternatives” section can also be done in PHP. First, you need to load the
GIF with ImageCreateFromGif(). Then, you copy a stretched version of it into
the chart using ImageCopyResized().
If there are multiple series to plot, line charts are more convenient than bar charts.
In that case, you’d use ImageLine() to do the graphing. I refer you to
Allan Kent’s column “Graphing With PHP and GD” for further ideas.
Finally, you have to figure out a way to get your data into the $data array.
Since I use MySQL for most of my work, I find the SQL COUNT(*) construct
very useful. To create time series like the one above with records containing
DATETIME fields, I’d use:
"SELECT COUNT(*) FROM table WHERE date LIKE '%-$month-%'"