354 Field one 127 Field two 753 Field three 529 Field four 73 Field five 236 Field six #### #! /usr/local/bin/perl -w # ############################################################################# # Program : graphdemo.pl # # # # Abstract : graphdemo is designed to demonstrate drawing simple graphs in # # : Perl. They may not be the most beautiful things in the world, # # : but they work well without much user intervention. # # # # Input : Takes a tab delimited data file (hardcoded) and generates a # # : graph using the first two columns. Will only handle 6 items # # : in this initial version. # # # # Output : Writes out a PNG file (hardcoded). # # # # History : 2001-03-30 M. Litherland - Initial version. # # : 2001-04-04 M. Litherland - Minor cleanups and improvements # ############################################################################# ##################### # Uses and requires # ##################### # This is our graphics library. use GD; use strict; ####################### # Globals and defines # ####################### # Path definitions my $PATH = ""; # This could be passed to us or read from a config file. my $INPUTFILE = "graphdemo.dat"; my $OUTPUTFILE = "graphdemo.png"; my $IMAGEWIDTH = 800; my $IMAGEHEIGHT = 600; my $FIELDCOUNT = 6; my $BARWIDTH = 30; my $TDSHIFT = 12; my $GRAPHTITLE = "Graph title (TTF)"; # We should really check in our file for this... my $FIELDMAX = 800; # This could be function of FIELDMAX my $HASHES = $FIELDMAX / 10; # Handles. my $graph; my ($red, $green, $blue, $rg, $gb, $br, $white, $black, $ltgrey, $mdgrey, $dkgrey); ################ # Main routine # ################ # Local variables my ($i); my (@file, @file2, $row, $data, $text); my (@bounds); # Bounding box used for rendering TTFs. # The integers in these values are to tweak the margins. my $division = $IMAGEWIDTH/($FIELDCOUNT + 1); my $bottomtop = $IMAGEHEIGHT/($FIELDCOUNT + 3); my ($left, $right, $top, $bottom); # Create a GD image $graph = new GD::Image($IMAGEWIDTH, $IMAGEHEIGHT); # Allocate some colors $white = $graph->colorAllocate(255,255,255); $black = $graph->colorAllocate(0,0,0); $ltgrey = $graph->colorAllocate(223,223,223); $mdgrey = $graph->colorAllocate(191,191,191); $dkgrey = $graph->colorAllocate(159,159,159); $red = $graph->colorAllocate(255,0,0); $green = $graph->colorAllocate(0,255,0); $blue = $graph->colorAllocate(0,0,255); $rg = $graph->colorAllocate(191,191,0); $gb = $graph->colorAllocate(0,191,191); $br = $graph->colorAllocate(191,0,191); my %colorHash = ( "0" => "$red", "1" => "$green", "2" => "$blue", "3" => "$rg", "4" => "$gb", "5" => "$br" ); # Set up some image characteristics #$graph->transparent($white); $graph->interlaced('true'); # Draw a frame around the image $graph->rectangle(0,0,$IMAGEWIDTH - 1,$IMAGEHEIGHT - 1, $black); # Draw a shadow box for small rectangle $graph->filledRectangle($division / 2, $bottomtop, $IMAGEWIDTH - ($division / 2), $IMAGEHEIGHT - $bottomtop, $mdgrey); # Draw a smaller rectangle for a background $graph->filledRectangle(($division / 2) + $TDSHIFT, $bottomtop + $TDSHIFT, $IMAGEWIDTH - ($division / 2), $IMAGEHEIGHT - $bottomtop, $ltgrey); # Draw a title for our graph $graph->string(gdGiantFont,10,10,"There should be a TTF font right below this.", $black); # This actually renders the string. @bounds = $graph->stringTTF($black,"c:/winnt/fonts/trebuc.ttf",40,0,10,60,$GRAPHTITLE) or print "Problem: $@\n"; print "Bounds = ($bounds[0], $bounds[1]), ($bounds[2], $bounds[3]), ($bounds[4], $bounds[5]), ($bounds[6], $bounds[7])\n"; open (FILEHANDLE, "<$INPUTFILE"); @file = ; close (FILEHANDLE); # This is sloppy. BAD PROGRAMMER. @file2 = @file; # Draw shadow boxes for the bars. for ($i = 0; $i < $FIELDCOUNT; $i++) { my $subdivision; $row = shift @file; ($data, $text) = split(/\t/, $row); chomp $text; $subdivision = $division + ($division * $i); $left = $subdivision - $BARWIDTH + $TDSHIFT; $right = $subdivision + $BARWIDTH + $TDSHIFT; $top = $IMAGEHEIGHT - $bottomtop - ($IMAGEHEIGHT - (2 * $bottomtop))*($data/$FIELDMAX) + $TDSHIFT; $bottom = $IMAGEHEIGHT - $bottomtop; $graph->filledRectangle($left, $top, $right, $bottom, $mdgrey); $graph->string(gdSmallFont, $left, $top - ($bottomtop / 4.0), $data, $mdgrey); } # Draw hashes at regular intervals for ($i = 0; $i <= ($FIELDMAX/$HASHES); $i++) { $graph->line($division / 2, $IMAGEHEIGHT - $bottomtop - ($IMAGEHEIGHT - (2 * $bottomtop))*(($i * $HASHES)/$FIELDMAX), $IMAGEWIDTH - ($division / 2), $IMAGEHEIGHT - $bottomtop - ($IMAGEHEIGHT - (2 * $bottomtop))*(($i * $HASHES)/$FIELDMAX), $dkgrey); $graph->string(gdSmallFont, $IMAGEWIDTH - ($division / 2) + 5, $IMAGEHEIGHT - $bottomtop - ($IMAGEHEIGHT - (2 * $bottomtop))*(($i * $HASHES)/$FIELDMAX) - 5, $i * $HASHES, $black); } # Generate the graphed items. for ($i = 0; $i < $FIELDCOUNT; $i++) { my $subdivision; $row = shift @file2; ($data, $text) = split(/\t/, $row); chomp $text; $subdivision = $division + ($division * $i); $left = $subdivision - $BARWIDTH; $right = $subdivision + $BARWIDTH; $top = $IMAGEHEIGHT - $bottomtop - ($IMAGEHEIGHT - (2 * $bottomtop))*($data/$FIELDMAX); $bottom = $IMAGEHEIGHT - $bottomtop; $graph->filledRectangle($left, $top, $right, $bottom, $colorHash{$i}); $graph->rectangle($left, $top, $right, $bottom, $black); $graph->string(gdMediumBoldFont, $left, $IMAGEHEIGHT - ($bottomtop / 1.5), $text, $black); $graph->string(gdSmallFont, $left, $top - ($bottomtop / 4.0), $data, $black); } # Outline the data window $graph->rectangle($division / 2, $bottomtop, $IMAGEWIDTH - ($division / 2), $IMAGEHEIGHT - $bottomtop, $black); # Write the final image to a file open (FILEHANDLE, ">$OUTPUTFILE"); binmode FILEHANDLE; print FILEHANDLE $graph->png; close (FILEHANDLE); exit;