#! perl -w use GD::Graph::pie; use GD::Graph::Map; use GD::Graph::bars; use CGI qw (param header); use CGI::Carp (fatalsToBrowser); use strict; # some bogus sales data my %sales = ( Tom => { Ravioli => 20, Lasagne => 30, SpaghettiOs => 50 }, Dick => { Chai => 25, Green => 30, Oolong =>40 }, Harry => { Kiwi => 10, Tomato => 15, Grapes => 40 }, Elspeth => { knives=> 40, fistpacks=>40, truncheons=>35 } ); # # if there's a name, show that person's sales; # if (param ("name")) { my $name=param ("name"); # get requested person's name # primitive error checking. die "salesman not found. Insert salesman and press any key to continue.\n" unless exists ($sales{$name}); # prepare data. # this is not incredibly readable, but I wanted to see if it could be done this way... perl continues to amuse and amaze... # to clarify, we're adding the names of the person's products in the first arrayref, # and the sales in the second array. # my @data = ([keys % {$sales {param ("name")}}], [values % {$sales {param ("name")}}]); # # prepare & display graph. # please refer to GD::Graph's docs if this doesn't make sense. # my $my_graph = new GD::Graph::bars( 200, 200 ) || die "$!"; $my_graph->set( x_label => 'Products', y_label => 'Dollars', title => "Sales for $name", bar_spacing => 8 ) ; open PNG, ">../htdocs/$name.png"; binmode PNG; print PNG $my_graph->plot(\@data)->png; close PNG; # finally, print out html; print header; print "\n"; print ""; print ""; } else { # # no name selected; show pie chart. # my @chartdata; # start by pushing the names of the salesmen onto chartdata in an arrayref. push @chartdata, [sort keys %sales]; my @salestotals; my $urlbase="http://127.0.0.1/cgi-bin/gdmap2.cgi?name="; my @urls; #this loop does 2 things. # first it gathers the total sales for each salesman (the inner foreach loop) and pushes # that value onto @salestotals, which is used to create the graph. # After that, it creates a url and stores it for creation of the image map. foreach (sort keys %sales) { my $sum; foreach my $item (keys (%{$sales{$_}})) {$sum+=$sales{$_}{$item}} push @salestotals, $sum; push @urls, $urlbase.$_; } # now we're finished with that, add the sales totals to the chart data push @chartdata, [@salestotals]; # all the data's ready for the graph, # time to plot it out. # if this doesn't make sense to you, review GD::Graph workings my $my_graph = new GD::Graph::pie( 200, 200 ); $my_graph->set( '3d' => 0, label => 'Sales totals', ); open PNG, ">../htdocs/salesinfo.png"; binmode PNG; print PNG $my_graph->plot(\@chartdata)->png; close PNG; # ok, the graph's finished. now make the map. # the hrefs param is the list of urls to map to # noImgMarkup indicates that only the tag should be created, # by default, GD::Graph::Map will create both the and an tag # mapName is, ha-ha, will be the name of the map. # info will show mouseover data for the map. my $map = new GD::Graph::Map($my_graph, hrefs=>\@urls , noImgMarkup=>1, mapName=>"salesmap", info => 'Total sales for %x: %y (%p%)' ); #finally, show the html print header; print "\n", '', ($map->imagemap("salesinfo.png", \@chartdata)), ""; }