ChartDirector Ver 3.0 (Perl Edition)

Database Clickable Charts




In this section, we will present an example that employs both database and image maps.

We will display a bar chart that shows the revenue for the last 10 years. When the user clicks on a bar, it will "drill down" to another bar chart showing the monthly revenue for the year represented by the bar clicked. All data comes from a database.

The code that creates the clickable bar chart for the last 10 years are as follows.

[The following is available as "perldemo_cgi/dbdemo3_main.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; # #Get the revenue for the last 10 years # my $SQLstatement = "Select Sum(Software + Hardware + Services), Year(TimeStamp) " . "From revenue Where Year(TimeStamp) >= 1991 " . "And Year(TimeStamp) <= 2001 " . "Group By Year(TimeStamp) Order By Year(TimeStamp)"; # #Read in the revenue data into arrays # my $dbh = DBI->connect('dbi:mysql:sample','test','test'); my $sth = $dbh->prepare($SQLstatement); my @revenue; my @timestamp; $sth->execute(); while (my @row = $sth->fetchrow_array) { push @revenue, $row[0]; push @timestamp, $row[1]; } $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 Last 10 Years", "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 multi-color bar chart layer using the supplied data $c->addBarLayer3(\@revenue)->setBorderColor($perlchartdir::Transparent, 1); #Set the x-axis labels using the supplied labels $c->xAxis->setLabels(\@timestamp); #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); #Create the image and save it in a temporary location my $filename = perlchartdir::tmpFile().".png"; $c->makeChart($filename); $chartURL = "myimage.pl?img=".$filename; #Create an image map for the chart my $imageMap = $c->getHTMLImageMap("dbdemo3a.pl", "", "title='{xLabel}: USD {value|0}K'"); print "Content-type: text/html\n\n"; print <<EndOfHTML <html> <body> <h1>Database Clickable Charts</h1> <p style="width:500px;">The example demonstrates creating a clickable chart using data from a database. Click on a bar below to "drill down" onto a particular year.</p> <p><a href="viewsource.pl?file=$ENV{"SCRIPT_NAME"}"> View source code </a></p> <img src="$chartURL" border="0" usemap="#map1"> <map name="map1"> $imageMap </map> </body> </html> EndOfHTML ;

The above code first performs a database query and read the data into arrays. It then uses the data to create a bar chart. The chart is saved in a temporary file using BaseChart.makeTmpFile. An <IMG> tag is used to retrieve the chart with "myimage.pl?img=/tmp/tmpcharts/$chart1URL" as the URL. "myimage.pl" is a simple utility that comes with ChartDirector for retrieving images from files.

When the user clicks on the bar chart, the handler "dbdemo3a.pl" will be invoked with a number of HTTP query parameters to indicate which bar the user has clicked. In particular, the xLabel parameter will contain the x-axis label for the bar clicked. Using the xLabel parameter, the "dbdemo3a.pl" knows which year the user has clicked. It then query the database for the data on that year, and produces the bar chart for that year.

In this example, the "dbdemo3a.pl" will produce another clickable chart using "xystub.pl" as the handler.

[The following is available as "perldemo_cgi/dbdemo3a.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"}); # #Retrieve the selected year from the query variable "xLabel" # my $selectedYear = ($query{"xLabel"} or 2001); # #Create an SQL statement to get the revenues of each month for the #selected year. The ArrayIndex will be from 0 - 11, representing Jan - Dec. # 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); #Create the image and save it in a temporary location my $filename = perlchartdir::tmpFile().".png"; $c->makeChart($filename); $chartURL = "myimage.pl?img=".$filename; #Create an image map for the chart my $imageMap = $c->getHTMLImageMap("xystub.pl", "", "title='{dataSetName} @ {xLabel} = USD {value|0}K'"); print "Content-type: text/html\n\n"; print <<EndOfHTML <html> <body> <h1>Database Clickable Chart</h1> <p style="width:500px;">You have click the bar of the year $query{"xLabel"}. Below is the "drill-down" chart showing the monthly details.</p> <p><a href="viewsource.pl?file=$ENV{"SCRIPT_NAME"}"> View source code </a></p> <img src="$chartURL" border="0" usemap="#map1"> <map name="map1"> $imageMap </map> </body> </html> EndOfHTML ;

For demo purpose, the handler "xystub.pl" simply displays what is clicked.

[The following is available as "perldemo_cgi/xystub.pl".]
#!/usr/bin/perl #standard code to parse HTTP query parameters my %query = map {my($k,$v) = split(/=/)} split(/&/, $ENV{"QUERY_STRING"}); print "Content-type: text/html\n\n"; print <<EndOfHTML <html> <body> <h1>Simple Clickable XY Chart Handler</h1> <p><a href="viewsource.pl?file=$ENV{"SCRIPT_NAME"}"> View Source Code </a></p> <p><b>You have clicked on the following chart element :</b></p> <ul> <li>Data Set : $query{"dataSetName"}</li> <li>X Position : $query{"x"}</li> <li>X Label : $query{"xLabel"}</li> <li>Data Value : $query{"value"}</li> </ul> </body> </html> EndOfHTML ;