Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Using GD output for HTML imagemaps -- GD::Graph::Map recipe

by boo_radley (Parson)
on Nov 26, 2001 at 04:22 UTC ( [id://127447]=perltutorial: print w/replies, xml ) Need Help??

Problem

You want to use a graph image produced by GD::Graph::* as an imagemap in a web page

Solution

Install and use GD::Graph::Map to create an HTML fragment for img and map tags.

#! 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 cont +inue.\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 t +he 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 "<HTML><BODY BGCOLOR=white>\n"; print "<IMG SRC=\"/$name.png\">"; print "</BODY></HTML>"; } 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 fo +reach 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 i +mage map. foreach (sort keys %sales) { my $sum; foreach my $item (keys (%{$sales{$_}})) {$sum+=$sales{$_}{$ite +m}} 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 <map> tag should be created, # by default, GD::Graph::Map will create both the <map> and an <im +g> 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 "<HTML><BODY BGCOLOR=white>\n", '<IMG SRC="/salesinfo.png" usemap="#salesmap">', ($map->imagemap("salesinfo.png", \@chartdata)), "</BODY></HTML>"; }

Discussion

This module prepares an imagemap based on the contents of a GD::Graph object, and has several constructor options that will alter the contents of the map or its behavior.
The foremost among these is the hrefs parameter (an arrayref) -- this list determines what each map region links to. If there are more regions than hrefs, say by having 8 series of data, but only 4 href elements, each 'leftover' series will have 'javascript:;' for a link. This behavior is a little quirky; it seems like the author could have stopped creating map regions after the last one was finished, but this behavior is apparently to quell some odd behavior on older browsers.
Next is the noImgMarkup option -- this suppresses the output of the img tag, and can be useful if you have a static image that may require several different maps, or whenever the image is either static or has been generated previously.
mapName overrides the default name attribute for the map tag. As the default tag is set to time (), this may not be useful when noImgMarkup is set.
the info (and legend, see POD) param determines what information will be displayed when mousing over a region.
There are a set of options to control the attributes of the img tag (img_*, but these may be of reduced value for most, as most of the common attributes are preset when the tag is generated.
Finally, if you'd like the linked page to appear in a separate browser window, setting newWindow to true tag will accomplish the job.

Of course, this module requires that you have previous knowledge of the assorted GD::Graph modules.

Replies are listed 'Best First'.
Re: Using GD output for HTML imagemaps -- GD::Graph::Map recipe
by Anonymous Monk on May 11, 2004 at 09:22 UTC
    hi, i have tried your code, it apperears so much errors 5.6.1/GD/Graph/Map.pm line 367. Use of uninitialized value in numeric lt (<) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 361. Use of uninitialized value in numeric gt (>) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 310. Use of uninitialized value in numeric gt (>) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 311. Use of uninitialized value in numeric gt (>) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 366. Use of uninitialized value in numeric lt (<) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 367. Use of uninitialized value in numeric lt (<) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 361. Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 309. Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 309. Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 309. Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 309. Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 309. Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 309. Use of uninitialized value in numeric eq (==) at /usr/local/lib/perl5/site_perl/5.6.1/GD/Graph/Map.pm line 309. in fact i meet a same problem, it seems MAP does not work with the objet Pie. i am looking forward to your response mail liu_haisheng@mentor.com regards
      Using perl v5.8.7, i just had to mess with path (in script) and permissions (on file system) and all worked great, a nice one Boo, thank you, great source for my test. Alex

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perltutorial [id://127447]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (5)
As of 2024-03-29 12:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found