WithMap.pm
上传用户:shbosideng
上传日期:2013-05-04
资源大小:1555k
文件大小:5k
源码类别:

SNMP编程

开发平台:

C/C++

  1. package GIFgraph::WithMap;
  2. use strict;
  3. use vars qw (@ISA %fields $AUTOLOAD $VERSION);
  4. use Carp;
  5. use CGI;
  6. use MRP::BaseClass;
  7. $VERSION = 1.0;
  8. # use AUTOLOAD to pass everything that we can't do to _GIFgraph.
  9. # don't know if this is kosha. AHHHH.
  10. sub AUTOLOAD {
  11.   my $thing = shift;
  12.   my ($package, $function) = $AUTOLOAD =~ m/^(.*)::([^:]+)$/;
  13.   if(ref($thing)) {
  14.     my $delegate = $thing->_GIFgraph;
  15.     $function = join '::', $delegate, $function;
  16.     return $thing->$function(@_);
  17.   }
  18.   die "Could not find method $AUTOLOAD via $thing";
  19. }
  20. sub isa {
  21.   my ($thing, $type) = @_;
  22.   return $thing->_GIFgraph->isa($type) || $thing->SUPER::isa($type);
  23. }
  24. sub new {
  25.   my $class = shift;
  26.   my $GIFgraph = shift;
  27.   my $baseClass = new MRP::BaseClass;
  28.   my $self = $class->rebless($GIFgraph, $baseClass);
  29.   $self->_GIFgraph(ref $GIFgraph);
  30.   return $self;
  31. }
  32. sub draw_data {
  33.   my ($self, $gd, $data) = @_;
  34.   my $fuzz = $self->fuzz;
  35.   my $map = "";
  36.   my $mapname = $self->mapname || confess "You must set the name for this map before calling plot";
  37.   my $seriesnames = $self->seriesnames;
  38.   my $links = $self->links;
  39.   my $delegateFunc = join '::', $self->_GIFgraph, 'draw_data';
  40.   $self->$delegateFunc($gd, $data);
  41.   
  42.   $map = '<MAP NAME="' . $mapname . '">'."n";
  43.   foreach my $series (1 .. $self->{numsets}) {
  44.     my (@up, @down);
  45.     foreach my $point (0 .. $self->{numpoints}) {
  46.       next unless defined($$data[$series][$point]);
  47.       my ($x, $y) = $self->val_to_pixel($point+1, $$data[$series][$point], $series);
  48.       push @up, $x, $y+$fuzz;
  49.       unshift @down, $x, $y-$fuzz;
  50.     }
  51.     my $seriesname = $seriesnames->[$series-1] || 'series '.$series;
  52.     my $link = $links->[$series-1] || "#$seriesname";
  53.     $map .= join("nt",
  54.  '<AREA',
  55.  'alt="' . $seriesname . '"',
  56.  'href="' . $link . '"',
  57.  'onMouseOver="self.status=' . "'$seriesname'" . '; return true"',
  58.  'onMouseOut="self.status=' . "''" . '; return true"',
  59.  'shape=polygon',
  60.  'coords="' .  join(', ', @up, @down) . '"',
  61.  );
  62.     $map .= ">n";
  63.   }
  64.   $map .= "</MAP>n";
  65.   $self->map($map);
  66. }
  67. BEGIN {
  68.   @ISA = qw (MRP::BaseClass);
  69.   %fields = (
  70.      'fuzz' => 1,
  71.      'map' => undef,
  72.      'mapname' => undef,
  73.      'seriesnames' => [],
  74.      'links' => [],
  75.      '_GIFgraph' => undef,
  76.     );
  77.   GIFgraph::WithMap->check4Clashes;
  78. }
  79. $VERSION;
  80. __END__
  81. =head1 NAME
  82. GIFgraph::WithMap - generates HTML map text while plotting graph
  83. =head1 DESCRIPTION
  84. Generates the html map block for a graph so that data series become
  85. 'clickable',
  86. =head1 SYNOPSIS
  87. This module extends GIFgraph objects such as GIFgraph::lines. You can
  88. do everything that you would with a GIFgraph object. In addition, when
  89. the data is plotted, it generates some MAP html text.
  90. The series will be labeled 'series 1', 'series 2' etc. unless the
  91. $obj->seriesnames has been set. For each series, it will create a
  92. polygon area, with the following structure (assuming series is named
  93. 'Green', and that the links member array is empty:
  94.  <AREA
  95.         alt="Green"
  96.         href="#Green"
  97.         onMouseOver="self.status='Green'; return true"
  98.         onMouseOut="self.status=''; return true"
  99.         shape=polygon
  100.         coords="87, 41, 165, 250, 165, 246, 87, 37">
  101. So - clicking on the series will take you to #Green. If you don't
  102. specify #Green in the document, clicking on it will do very little. If
  103. you have (e.g. in the key) then it should take you there.
  104. =head1 new
  105. Use something like
  106.  $map = new GIFgraph::WithMap(new GIFgraph::lines(400,300));
  107. =head1 fields
  108. =over
  109. =item map
  110. Once plot has been called, map contains the map text.
  111.  print $graphWithMap->map;
  112. =item fuzz
  113. This is the up/down fuzz used to construct the ploygon. It defaults to
  114. 1 - so the polygon will be three pixles wide (the pixle drawn and one
  115. above and below it).
  116. =item mapname
  117. Set this before calling plot. This is the name of the map, as given by
  118. usemap="#mapname" in <img>. It is a fatal error to try to plot without
  119. a name.
  120. =item seriesnames
  121. Array of names for the series. If a name is absent for a series (or
  122. all series) then it will be named Series #. This must be set before
  123. the graph is plotted.
  124.  $graphWithMap->seriesnames('name1', 'name2');
  125. =links
  126. Array of links for the series. If a link is absent for a series (or
  127. all series) then it will be named #SeriesName (where SeriesName is
  128. generated as described in L<seriwsnames>).
  129. =back
  130. =head1 Guts
  131. This module uses MRP::BaseClass to implement member access functions.
  132. In the constructor, a new object is created that is a meld of an
  133. MRP::BaseClass derived object, and the GIFgraph object passed in. The
  134. type of that object is stoored in _GIFgraph. In AUTOLOAD, first I
  135. check to see if the GIFgraph object's package named in _GIFgraph
  136. implements the function. If it does, then I return the value of that
  137. function - i.e. it behaves as if the object inherits from that
  138. package. If that fails, then I return the value of SUPER::AUTLOLOAD,
  139. which will presumably handle it or die gracefully. Hey presto -
  140. dynamic parenting.
  141. @ISA does not include anything to implement a GIFgraph object as a
  142. parent. However, I have overridden 'isa' to account for this.