I'm having some trouble getting the image created by the following function to display correctly.
I'm pulling some data out of MySQL then plotting a barchart. However, I can only get the image stream to display, even if I wrap <img scr=" "> around it, and I don't really want to generate a file. How can I call the function, and display the image correctly?
reports.php:
Code:
if (isset($_POST['submit'])) {
$output=show_barchart_reports();
echo '<img src="'.$output.'">';
}
function.php
Code:
function show_barchart_reports(){
$year = 2008;
$month= 12;
$numdays = cal_days_in_month(CAL_GREGORIAN, $month, $year) ;
for ( $i = 1; $i <= $numdays; $i++) {
$sql = "SELECT COUNT(id) FROM `support_requests` WHERE `date` LIKE '$year-$month-$i %'";
$result = mysql_query($sql) or die('Query failed: ' . mysql_error());
while($row=mysql_fetch_array($result)){
$data[$i] = $row['COUNT(id)'];
}
}
// create image
$width = 480;
$height = 350;
$image = imagecreate($width, $height);
// title
$titlefont = 3;
// colors
$white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
$navy = imagecolorallocate($image, 0x00, 0x00, 0x80);
$black = imagecolorallocate($image, 0x00, 0x00, 0x00);
$gray = imagecolorallocate($image, 0xC0, 0xC0, 0xC0);
// layout
$maxval = max($data);
$nval = sizeof($data);
$vmargin = 20; // top (bottom) vertical margin for title (x-labels)
$hmargin = 38; // left horizontal margin for y-labels
$base = floor(($width - $hmargin) / $nval); // distance between columns
$ysize = $height - 2 * $vmargin; // y-size of plot
$xsize = $nval * $base; // x-size of plot
$txtsz = imagefontwidth($titlefont) * strlen($title); // pixel-width of title
$xpos = (int)($hmargin + ($xsize - $txtsz)/2); // center the title
$xpos = max(1, $xpos); // force positive coordinates
$ypos = 3; // distance from top
imagestring($image, $titlefont, $xpos, $ypos, $title , $black);
// y labels and grid lines
$labelfont = 2;
$ngrid = 4; // number of grid lines
$dydat = $maxval / $ngrid; // data units between grid lines
$dypix = $ysize / ($ngrid + 1); // pixels between grid lines
for ($i = 0; $i <= ($ngrid + 1); $i++) {
// iterate over y ticks
// height of grid line in units of data
$ydat = (int)($i * $dydat);
// height of grid line in pixels
$ypos = $vmargin + $ysize - (int)($i*$dypix);
$txtsz = imagefontwidth($labelfont) * strlen($ydat); // pixel-width of label
$txtht = imagefontheight($labelfont); // pixel-height of label
$xpos = (int)(($hmargin - $txtsz) / 2);
$xpos = max(1, $xpos);
imagestring($image, $labelfont, $xpos,
$ypos - (int)($txtht/2), $ydat, $black);
if (!($i == 0) && !($i > $ngrid)) {
imageline($image, $hmargin - 3,
$ypos, $hmargin + $xsize, $ypos, $gray);
// don't draw at Y=0 and top
}
}
// 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;
imagefilledrectangle($image, $xmin, $ymin, $xmax, $ymax, $navy);
// x labels
$txtsz = imagefontwidth($labelfont) * strlen($xval);
$xpos = $xmin + (int)(($base - $txtsz) / 2);
$xpos = max($xmin, $xpos);
$ypos = $ymax + 3; // distance from x axis
imagestring($image, $labelfont, $xpos, $ypos, $xval, $black);
}
// plot frame
imagerectangle($image, $hmargin, $vmargin,
$hmargin + $xsize, $vmargin + $ysize, $black);
// flush image
header('Content-type: image/gif'); // or "Content-type: image/png"
imagegif($image); // or imagepng($image)
imagedestroy($image);
}
Last edited by bjblackmore; 01-14-2009 at 09:26 AM.
This is a rather quick answer, and the only thing I checked code-wise is that you sent out the proper header before using imagegif() or imagepng(), aside from that, you're going about it wrong.
Seeing how you have your function in a file function.php anyway, remove the actual enclosed function and just have the code as a standalone .php file. Then, all you have to do is include this HTML code in your page:
HTML Code:
<img src="function.php" />
If you need to create several different images using function.php, then pass different parameters to it and use $_GET in the function.php file to get them:
Quick answer: Remove the function declaration from function.php and use <img src="function.php" /> in your HTML.
Remember, imagegif() or imagepng() will output binary image data - you want a ASCII file in your image tag (i.e. <img src="function.php" />) - things make a lot more sense when you think about what you're trying to do.
Last edited by aj_nsc; 01-14-2009 at 10:04 AM.
I've switched careers...
I'm NO LONGER a scientist,
but now a web developer...
awesome.
The trouble is, function.php has about 20 other functions, including a user_create function, login & logout function etc.
Wouldn't this cause problems?
I guess I could put the image creation function inside a barchart.php, then run my sql query, and call the barchart.php, but I was hoping to try and keep to as few files as possible. So there would be functions.php in a sub dir called \include then in the root just an index.php, which would display different page content depending on the ?action, i.e. index.php?action=login would show the login page, index.php?action=reports would show a page with a selection of reports, including this barchart, and piecharts etc.
Ben
Last edited by bjblackmore; 01-14-2009 at 10:31 AM.
Bookmarks