ChartDirector Ver 3.0 (Perl Edition)

Direct Database Access




In this example, we will demostrate how to create a web page to show the monthly revenue for a given year. The user will select a year from a HTML form and press OK. The web server will query a database to obtain the necessary data, and return a web page containing the bar chart for the selected year.

The code for producing the HTML form is listed below. It outputs a drop down select list to allow the user to selecte a year. Based on the selected year, it uses an <IMG> tag with a ChartDirector script as the URL and the selected year as query parameter. The ChartDirector script will generate the chart image based on the selected year and deliver it to the browser.

[The following is available as "perldemo_cgi/dbdemo1_main.pl".]
#!/usr/bin/perl #standard code to parse HTTP query parameters my %query = map {my($k,$v) = split(/=/)} split(/&/, $ENV{"QUERY_STRING"}); #the currently selected year my $selectedYear = ($query{"year"} or 2001); print "Content-type: text/html\n\n"; print <<EndOfHTML <html> <body> <h1>Database Integration Demo (1)</h1> <p>The example demonstrates creating a chart using data from a database.</p> <ul> <li><a href="viewsource.pl?file=$ENV{"SCRIPT_NAME"}"> View containing HTML page source code </a></li> <li><a href="viewsource.pl?file=dbdemo1a.pl"> View chart generation page source code </a></li> </ul> <form action="$ENV{"SCRIPT_NAME"}"> I want to obtain the revenue data for the year <select name="year"> <option value="1990">1990 <option value="1991">1991 <option value="1992">1992 <option value="1993">1993 <option value="1994">1994 <option value="1995">1995 <option value="1996">1996 <option value="1997">1997 <option value="1998">1998 <option value="1999">1999 <option value="2000">2000 <option value="2001">2001 </select> <input type="submit" value="OK"> </form> <SCRIPT> //make sure the select box displays the current selected year. document.forms[0].year.selectedIndex = ${\($selectedYear - 1990)}; </SCRIPT> <img src="dbdemo1a.pl?year=$selectedYear"> </body> </html> EndOfHTML ;

As seen from the code above, the chart is created by the URL in the <IMG> tag, which is "dbdemo1a.pl". The "dbdemo1a.pl" is as follows.

[The following is available as "perldemo_cgi/dbdemo1a.pl".]
#!/usr/bin/perl #Include current script directory in the module path (needed on Microsoft IIS). #This allows this script to work by copying ChartDirector to the same directory #as the script (as an alternative to installation in Perl module directory) use File::Basename; use lib dirname($0); use perlchartdir; use DBI; #standard code to parse HTTP query parameters my %query = map {my($k,$v) = split(/=/)} split(/&/, $ENV{"QUERY_STRING"}); # #Displays the monthly revenue for the selected year. The selected year #should be passed in as a query parameter called "year" # my $selectedYear = ($query{"year"} or 2001); # #Create an SQL statement to get the revenues of each month for the #selected year. # my $SQLstatement = "Select Month(TimeStamp) - 1, " . "Software, Hardware, Services " . "From revenue Where Year(TimeStamp)=$selectedYear"; # #Read in the revenue data into arrays # my $dbh = DBI->connect('dbi:mysql:sample','test','test'); my $sth = $dbh->prepare($SQLstatement); my @software = (0) x 12; my @hardware = (0) x 12; my @services = (0) x 12; $sth->execute(); while (my @row = $sth->fetchrow_array) { $software[$row[0]] = $row[1]; $hardware[$row[0]] = $row[2]; $services[$row[0]] = $row[3]; } $dbh->disconnect; # #Now we obtain the data into arrays, we can start to draw the chart #using ChartDirector # #Create a XYChart of size 420 pixels x 240 pixels my $c = new XYChart(420, 240); #Set the chart background to pale yellow (0xffffc0) with a 2 pixel 3D border $c->setBackground(0xffffc0, 0xffffc0, 2); #Set the plotarea at (70, 50) and of size 320 x 150 pixels. Set background #color to white (0xffffff). Enable both horizontal and vertical grids by #setting their colors to light grey (0xc0c0c0) $c->setPlotArea(70, 50, 320, 150, 0xffffff, 0xffffff, 0xc0c0c0, 0xc0c0c0); #Add a title to the chart $c->addTitle("Revenue for $selectedYear", "timesbi.ttf") ->setBackground(0xffff00); #Add a legend box at the top of the plotarea $c->addLegend(70, 30, 0, "", 8)->setBackground($perlchartdir::Transparent); #Add a stacked bar chart layer using the supplied data my $layer = $c->addBarLayer2($perlchartdir::Stack); $layer->addDataSet(\@software, -1, "Software"); $layer->addDataSet(\@hardware, -1, "Hardware"); $layer->addDataSet(\@services, -1, "Services"); $layer->setBorderColor($perlchartdir::Transparent, 1); #Set the x axis labels. In this example, the labels must be Jan - Dec. my @labels = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"); $c->xAxis->setLabels(\@labels); #Set the x-axis width to 2 pixels $c->xAxis->setWidth(2); #Set the y axis title $c->yAxis->setTitle("USD (K)"); #Set the y-axis width to 2 pixels $c->yAxis->setWidth(2); #Output the chart binmode(STDOUT); print "Content-type: image/png\n\n"; print $c->makeChart2($perlchartdir::PNG);

The first part of the above code is a database query using MySQL. The SQL statement is:

my $SQLstatement = "Select Month(TimeStamp) - 1, " . "Software, Hardware, Services " . "From revenue Where Year(TimeStamp)=$selectedYear";

Note that the first column "Month(TimeStamp)-1" will be a number from 0 - 11, representing Jan - Dec. We can use it as index to the data arrays.

The code then executes the SQL query and read the data into an array using a loop. In the loop, the data are read using:

my @software = (0) x 12; my @hardware = (0) x 12; my @services = (0) x 12; $sth->execute(); while (my @row = $sth->fetchrow_array) { $software[$row[0]] = $row[1]; $hardware[$row[0]] = $row[2]; $services[$row[0]] = $row[3]; }

The advantages of using the first column as an "array index" to read the data into arrays are that it does not require the records to be sorted. It also works well in case there are some "missing records" in the database.

After we read the data into arrays, the second part of the code is to create a stacked bar chart using the given data. This is very similar to the examples in other parts of this documentation, so it will not explain further here.