GD::Graph::Polar - Make polar graph using GD package


GD-Graph-Polar documentation Contained in the GD-Graph-Polar distribution.

Index


Code Index:

NAME

Top

GD::Graph::Polar - Make polar graph using GD package

SYNOPSIS

Top

  use GD::Graph::Polar;
  my $obj=GD::Graph::Polar->new(size=>480, radius=>100);
  $obj->addPoint        (50=>25);
  $obj->addPoint_rad    (50=>3.1415);
  $obj->addGeoPoint     (75=>25);
  $obj->addGeoPoint_rad (75=>3.1415);
  $obj->addLine($r0=>$t0, $r1=>$t1);
  $obj->addLine_rad($r0=>$t0, $r1=>$t1);
  $obj->addGeoLine($r0=>$t0, $r1=>$t1);
  $obj->addGeoLine_rad($r0=>$t0, $r1=>$t1);
  $obj->addArc($r0=>$t0, $r1=>$t1);
  $obj->addArc_rad($r0=>$t0, $r1=>$t1);
  $obj->addGeoArc($r0=>$t0, $r1=>$t1);
  $obj->addGeoArc_rad($r0=>$t0, $r1=>$t1);
  $obj->addString($r=>$t, "Hello World!");
  $obj->addString_rad($r=>$t, "Hello World!");
  $obj->addGeoString($r=>$t, "Hello World!");
  $obj->addGeoString_rad($r=>$t, "Hello World!");
  $obj->font(gdSmallFont);  #sets the current font from GD exports
  $obj->color("blue");      #sets the current color from Graphics::ColorNames
  $obj->color([0,0,0]);     #sets the current color [red,green,blue]
  print $obj->draw;

DESCRIPTION

Top

This package is a wrapper arround GD to produce polar graphs with an easy interface. I use this package to display GPS satellites on a graph with data from the Net::GPSD3 package.

CONSTRUCTOR

Top

new

The new constructor.

  my $obj = GD::Graph::Polar->new(               #default values
                                  size=>480,     #width and height in pixels
                                  radius=>1,     #scale of the radius
                                  ticks=>10,     #number of major ticks
                                  border=>2,     #pixel border around graph
                                  rgbfile=>"/usr/X11R6/lib/X11/rgb.txt"
                                 );

METHODS

Top

initialize

addPoint

Method to add a point to the graph.

  $obj->addPoint(50=>25);

addPoint_rad

Method to add a point to the graph.

  $obj->addPoint_rad(50=>3.1415);

addGeoPoint

Method to add a point to the graph.

  $obj->addGeoPoint(75=>25);

addGeoPoint_rad

Method to add a point to the graph.

  $obj->addGeoPoint_rad(75=>3.1415);

addLine

Method to add a line to the graph.

  $obj->addLine(50=>25, 75=>35);

addLine_rad

Method to add a line to the graph.

  $obj->addLine_rad(50=>3.14, 75=>3.45);

addGeoLine

Method to add a line to the graph.

  $obj->addGeoLine(50=>25, 75=>35);

addGeoLine_rad

Method to add a line to the graph.

  $obj->addGeoLine_rad(50=>3.14, 75=>3.45);

addArc

Method to add an arc to the graph.

  $obj->addArc(50=>25, 75=>35);

addArc_rad

Method to add an arc to the graph.

  $obj->addArc_rad(50=>3.14, 75=>3.45);

addGeoArc

Method to add an arc to the graph.

  $obj->addGeoArc(50=>25, 75=>35);

addGeoArc_rad

Method to add an arc to the graph.

  $obj->addGeoArc_rad(50=>25, 75=>35);

addString

Method to add a string to the graph.

addString_rad

Method to add a string to the graph.

addGeoString

Method to add a string to the graph.

addGeoString_rad

Method to add a string to the graph.

color

Method to set or return the current drawing color

  my $colorobj=$obj->color("blue");     #if Graphics::ColorNames available
  my $colorobj=$obj->color([77,82,68]); #rgb=>[decimal,decimal,decimal]
  my $colorobj=$obj->color;

font

Method to set or return the current drawing font (only needed by the very few)

  use GD qw(gdGiantFont gdLargeFont gdMediumBoldFont gdSmallFont gdTinyFont);
  $obj->font(gdSmallFont); #the default
  $obj->font;

draw

Method returns a PNG binary blob.

  my $png_binary=$obj->draw;

BUGS

Top

Please log on RT and send to the author.

SUPPORT

Top

DavisNetworks.com supports all Perl applications including this package.

AUTHOR

Top

Michael R. Davis qw/perl michaelrdavis com/

LICENSE

Top

Copyright (c) 2011 Michael R. Davis (mrdvt92)

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

Top

GD, Geo::Constants, Geo::Functions, Graphics::ColorNames


GD-Graph-Polar documentation Contained in the GD-Graph-Polar distribution.
package GD::Graph::Polar;
use strict;
use warnings;
use Geo::Constants qw{PI};
use Geo::Functions qw{rad_deg};
use GD qw{gdSmallFont};

our $VERSION="0.16";

sub new {
  my $this = shift();
  my $class = ref($this) || $this;
  my $self = {};
  bless $self, $class;
  $self->initialize(@_);
  return $self;
}

sub initialize {
  my $self = shift();
  my $param = {@_};
  $self->{'size'}=$param->{'size'} || 480;
  $self->{'radius'}=$param->{'radius'} || 1;
  $self->{'ticks'}=defined($param->{'ticks'}) ? $param->{'ticks'} : 10;
  $self->{'border'}=defined($param->{'border'}) ? $param->{'border'} : 2;
  $self->{'object'}=GD::Image->new($self->{'size'}, $self->{'size'});
  eval 'use Graphics::ColorNames';
  unless($@) {
    my $rgb;
    foreach (qw{
                 /usr/share/X11/rgb.txt
                 /usr/X11R6/lib/X11/rgb.txt
                 /etc/X11/rgb.txt
                 ./rgb.txt
                 ../rgb.txt
               }) {
      $rgb=$_ if -r;
    }
    $self->{'rgbfile'}=$param->{'rgbfile'} || $rgb;
    die('Error: Cannot read rgb.txt file "'. $self->{'rgbfile'}. '"') unless -r $self->{'rgbfile'};
    $self->{'ColorNames'}=Graphics::ColorNames->new($self->{'rgbfile'});
  }

  # make the background transparent and interlaced
  $self->{'object'}->transparent($self->color([255,255,255]));
  $self->{'object'}->interlaced('true');
  
  # Put a frame around the picture
  $self->{'object'}->rectangle(0, 0, $self->{'size'}-1, $self->{'size'}-1, $self->color([0,0,0]));

  $self->color([192,192,192]);
  if ($self->{'ticks'} > 0) {
    foreach (0..$self->{'ticks'}) {
      my $c=$self->{'size'} / 2;
      my $r=$self->_width * $_ / $self->{'ticks'};
      $self->{'object'}->arc($c,$c,$r,$r,0,360,$self->color);
    }
  }

  $self->{'object'}->line($self->{'size'}/2,
                          $self->{'border'},
                          $self->{'size'}/2,
                          $self->{'size'}-$self->{'border'},
                          $self->color);
  $self->{'object'}->line($self->{'border'},
                          $self->{'size'}/2,
                          $self->{'size'}-$self->{'border'},
                          $self->{'size'}/2,
                          $self->color);
  $self->font(gdSmallFont);
  $self->color([0,0,0]);
}

sub addPoint {
  my $self = shift();
  my $r=shift();
  my $t=rad_deg(shift());
  return $self->addPoint_rad($r,$t);
}

sub addPoint_rad {
  my $self = shift();
  my $r=shift();
  my $t=shift();
  my ($x, $y)=$self->_imgxy_rt_rad($r,$t);
  my $icon=7;
  return $self->{'object'}->arc($x,$y,$icon,$icon,0,360,$self->color);
}

sub addGeoPoint {
  my $self = shift();
  my $r=shift();
  my $t=rad_deg(shift());
  return $self->addGeoPoint_rad($r,$t);
}

sub addGeoPoint_rad {
  my $self = shift();
  my $r=shift();
  my $t=PI()/2-shift();
  return $self->addPoint_rad($r,$t);
}

sub addLine {
  my $self = shift();
  my $r0=shift();
  my $t0=rad_deg(shift());
  my $r1=shift();
  my $t1=rad_deg(shift());
  return $self->addLine_rad($r0=>$t0, $r1=>$t1);
}

sub addLine_rad {
  my $self = shift();
  my $r0=shift();
  my $t0=shift();
  my $r1=shift();
  my $t1=shift();
  my ($x0=>$y0)=$self->_imgxy_rt_rad($r0=>$t0);
  my ($x1=>$y1)=$self->_imgxy_rt_rad($r1=>$t1);
  return $self->{'object'}->line($x0, $y0, $x1, $y1, $self->color);
}

sub addGeoLine {
  my $self = shift();
  my $r0=shift();
  my $t0=rad_deg(shift());
  my $r1=shift();
  my $t1=rad_deg(shift());
  return $self->addGeoLine_rad($r0=>$t0, $r1=>$t1);
}

sub addGeoLine_rad {
  my $self = shift();
  my $r0=shift();
  my $t0=PI()/2-shift();
  my $r1=shift();
  my $t1=PI()/2-shift();
  return $self->addLine_rad($r0=>$t0, $r1=>$t1);
}

sub addArc {
  my $self = shift();
  my $r0=shift();
  my $t0=rad_deg(shift());
  my $r1=shift();
  my $t1=rad_deg(shift());
  return $self->addArc_rad($r0=>$t0, $r1=>$t1);
}

sub addArc_rad {
  my $self = shift();
  my $r0=shift();
  my $t0=shift();
  my $r1=shift();
  my $t1=shift();
  my $m=($r1-$r0) / ($t1-$t0);
  my $inc=0.02; #is this good?
  my $steps=int(($t1-$t0) / $inc);
  my @array=();
  foreach (0..$steps) {
    my $t=$_ / $steps * ($t1-$t0) + $t0;
    my $r=$r0 + $m * ($t-$t0);
    push @array, [$r=>$t];
  } 
  my @return=();
  foreach (1..$steps) {
    push @return, $self->addLine_rad(@{$array[$_-1]}, @{$array[$_]});
  }
  return \@return;
}

sub addGeoArc {
  my $self = shift();
  my $r0=shift();
  my $t0=rad_deg(shift());
  my $r1=shift();
  my $t1=rad_deg(shift());
  return $self->addGeoArc_rad($r0=>$t0, $r1=>$t1);
}

sub addGeoArc_rad {
  my $self = shift();
  my $r0=shift();
  my $t0=PI()/2-shift();
  my $r1=shift();
  my $t1=PI()/2-shift();
  return $self->addArc_rad($r0=>$t0, $r1=>$t1);
}

sub addString {
  my $self=shift();
  my $r=shift();
  my $t=rad_deg(shift());
  my $string=shift();
  return $self->addString_rad($r=>$t, $string);
}

sub addString_rad {
  my $self=shift();
  my $r=shift();
  my $t=shift();
  my $string=shift();
  my ($x=>$y)=$self->_imgxy_rt_rad($r=>$t);
  return $self->{'object'}->string($self->font, $x, $y, $string, $self->color);
}

sub addGeoString {
  my $self=shift();
  my $r=shift();
  my $t=rad_deg(shift());
  my $string=shift();
  return $self->addGeoString_rad($r=>$t, $string);
}

sub addGeoString_rad {
  my $self=shift();
  my $r=shift();
  my $t=PI()/2-shift();
  my $string=shift();
  return $self->addString_rad($r=>$t, $string);
}

sub color {
  my $self = shift();
  if (@_) {
    my $color=shift();
    if (ref($color) eq "ARRAY") {
      $self->{'color'}=$self->{'object'}->colorAllocate(@{$color});
    } else {
      if (defined($self->{'ColorNames'})) {
        $self->{'color'}=
          $self->{'object'}->colorAllocate($self->{'ColorNames'}->rgb($color))
            || $self->{'object'}->colorAllocate(0,0,0);
      } else {
        warn(qq{Warning: Graphics::ColorNames unavailable. Unknown color($color); Using [0,0,0] (black).\n});
        $self->{'color'}=$self->{'object'}->colorAllocate(0,0,0);
      }
    }
  }
  return $self->{'color'};
}

sub font {
  my $self = shift();
  if (@_) { $self->{'font'} = shift() } #sets value
  return $self->{'font'};
}

sub draw {
  my $self=shift();
  return $self->{'object'}->png;
}

#=head2 _scale
#
#Method returns the parameter scaled to the image.
#
#=cut

sub _scale {
  my $self=shift();
  my $r=shift();
  return $self->_width / 2 / $self->{'radius'} * $r;
}

#=head2 _width
#
#Method returns the width of the graph.
#
#=cut

sub _width {
  my $self=shift();
  return $self->{'size'} - $self->{'border'} * 2;
}

#=head2 _imgxy_xy
#
#Method to convert xy to imgxy cordinates
#
#  $obj->addPoint_rad(50=>3.1415);
#
#=cut

sub _imgxy_xy {
  my $self = shift();
  my $x=shift();
  my $y=shift();
  my $sz=$self->_width;
  $x=$sz/2 + $x + $self->{'border'};
  $y=$sz/2 - $y + $self->{'border'};
  return ($x, $y);
}

#=head2 _xy_rt_rad
#
#Method to convert polar cordinate to Cartesian cordinates.
#
#=cut

sub _xy_rt_rad {
  my $self=shift();
  my $r=shift();
  my $t=shift();
  my $x=$r*cos($t);
  my $y=$r*sin($t);
  return ($x, $y);
}

#=head2 _imgxy_rt_rad
#
#Method to convert polar cordinate to Cartesian cordinates.
#
#=cut

sub _imgxy_rt_rad {
  my $self = shift();
  my $r=shift();
  my $t=shift();
  my ($x,$y)=$self->_xy_rt_rad($self->_scale($r), $t);
  return $self->_imgxy_xy($x, $y);
}

1;