Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

comment on

( [id://3333]=superdoc: 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.


In reply to Using GD output for HTML imagemaps -- GD::Graph::Map recipe by boo_radley

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (4)
As of 2024-03-29 11:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found