picture of Tim Perdue
When I compiled PHP on my LinuxPPC box, I didn't have GD installed and didn't want to add another layer of complexity by compiling it in. GD will let you do all kinds of cool things - creating gifs, complex charts, etc, if you use libraries from the Sample Code Archive here on this site and PHP's built in functionality.
I didn't want the lack of GD to stifle me too much, so I started hunting around for a way to generate html-based graphs and charts. Fortunately, someone had already gone to the trouble of writing up a class to handle that. at WebGuys provided a nifty class called HTML_Graphs.
At first, I was a little taken back by the complexity of the class. It does all kinds of things, from vertical bar charts to multiple horizontal bar charts. Because I knew I was going to use the class a lot, I spent some time creating a couple of wrapper functions.
Many of the functions of the class don't need to be used for basic graphing, which is what I am showing here. For instance, I don't see any need to go into detail on creating multiple charts at once. And vertical charts are created as easily as horizontal charts - just change the "type" parameter in the GraphIt() function that I detail elsewhere.
So let's get started. I will at first lay out the functions I have written, and then we'll talk about a specific use for them.
I wanted to be able to hand a simple database query to a function and have it graph it without me going to a bunch of work, so I whipped up this little function. It takes a database result and a title. The database result should be from a simple query like "select group, count(*) from table group by group". Just two columns, with the first column being the labels, and the second column being numbers.

<?php

include("class-graphs.php3");

Function 
GraphResult($result,$title) {

/*
    Takes a database result set.
    The first column should be the name,
    and the second column should be the values
*/

    /*
        db_ should be replaced with your database, aka mysql_ or pg_
    */
    
$rows=db_NumRows($result);

    if ((!
$result) || ($rows 1)) {
        echo 
"None Found.\n";
    } else {
        
$names[];
        
$values[];

        for (
$j=0$j db_NumRows($result); $j++) {
            if (
db_result($result$j0) != "" && db_result($result$j1) != "" ) {
                
$names[$j]= db_result($result$j0);
                
$values[$j]= db_result($result$j1);
            }
        }

    
/*
        This is another function detailed below
    */
        
GraphIt($names,$values,$title);
    }
}

?>
That function is quite simple. Hand it a result set, it checks for the length, then turns that result set into a set of arrays to pass into my other general function, GraphIt(). GraphIt() can be called directly if you already have an array, or you need to do some custom stuff with it that cannot be done with straight SQL.
Notice that GraphIt() will determine scale for you. It iterates through the values[] array and finds the biggest value. It also builds an appropriate array of colors for the bars on the graph.

<?php
Function GraphIt($names,$values,$title) {

    
$counter=count($names);

    
/*
        Can choose any color you wish
    */
    
for ($i 0$i $counter$i++) {
        
$bars[$i]="#DEDEEE";
    }

    
$counter=count($values);

    
/*
        Figure the max_value passed in, so scale can be determined
    */

    
$max_value=0;

    for (
$i 0$i $counter$i++) {
        if (
$values[$i] > $max_value) {
            
$max_value=$values[$i];
        }
    }

    if (
$max_value 1) {
        
$max_value=1;
    }

    
/*
        I want my graphs all to be 800 pixels wide, so that is my divisor
    */

    
$scale = (int) (800/$max_value);

    
/*
        I create a wrapper table around the graph that holds the title
    */

    
echo "<TABLE BGCOLOR=\"NAVY\" CELLSPACING=2 CELLPADDING=3>";
    echo 
"<TR><TD BGCOLOR=\"NAVY\"><FONT COLOR=WHITE><B>$title</TD></TR><TR><TD>";

    
/*
        Create an associatve array to pass in. I leave most of it blank
    */

    
$vals =  array(
    
"vlabel"=>"",
    
"hlabel"=>"",
    
"type"=>"",
    
"cellpadding"=>"",
    
"cellspacing"=>"",
    
"border"=>"",
    
"width"=>"",
    
"background"=>"",
    
"vfcolor"=>"",
    
"hfcolor"=>"",
    
"vbgcolor"=>"",
    
"hbgcolor"=>"",
    
"vfstyle"=>"",
    
"hfstyle"=>"",
    
"noshowvals"=>"",
    
"scale"=>"$scale",
    
"namebgcolor"=>"",
    
"valuebgcolor"=>"",
    
"namefcolor"=>"",
    
"valuefcolor"=>"",
    
"namefstyle"=>"",
    
"valuefstyle"=>"",
    
"doublefcolor"=>"");

    
/*
        This is the actual call to the HTML_Graphs class
    */

    
html_graph($names,$values,$bars,$vals);

    echo 
"</TD></TR></TABLE>";
}
?>
So those two functions really do the heavy lifting for you. Determing scale was always a headache until I built the wrapper classes, and sometimes the graph would be so large it would go off the page.
Now that those two funtions are in place, it's child's play to use them. I am already using them heavily in the company I work for, VA Linux Systems, and on my own site, Geocrawler.com and here on PHPBuilder to graph traffic flows.
Here is one such report:
Impressions for PHPBuilder
19991025
 
(18715)
19991026
 
(15949)
19991027
 
(16545)
There's so much more you can do with this class, that I can't touch it all here. If you do write up new wrapper classes, please submit them to the code archive. My next project with this class is to extend it so it can do stacked bar charts.
Good luck!
--Tim