Chart-ThreeD
view release on metacpan or search on metacpan
lib/Chart/ThreeD/Pie.pm view on Meta::CPAN
# make sure we are writing to a binary stream
binmode STDOUT;
# Draw the pie, Convert the image to GIF and print it on standard output
print $pie->plot->gif;
=head1 DESCRIPTION
Chart::ThreeD::Pie allows you to create 3D Piecharts very easily
and emit the drawings as GIF files. You can customize almost everything
using a large number of methods.
This module requires the Lincoln D. Stein's GD module available on CPAN.
=head1 Method Calls
=head2 Creating Pie
=over 5
=item C<new>
C<Chart::ThreeD::Pie::new(width, height, title)> I<class method>
To create a new pie, send a new() message to the Chart::ThreeD::Pie
class. For example:
$pie = new Chart::ThreeD::Pie (450, 320, 'my title');
This will create an image that is 450 x 320 pixels wide. If you don't
specify the dimensions, a default of 400 x 300 will be chosen. The default
title is an empty string (no title). The three parameters can be changed
using the corresponding methods specified bellow.
=back
=cut
# A new Pie object
sub new {
my $this = shift;
my $class = ref($this) || $this;
my $self = {};
bless $self, $class;
$self->initialize (@_);
return $self;
}
sub initialize {
my $self = shift;
$self->{xmax} = shift || 400;
$self->{ymax} = shift || 300;
$self->{title} = shift || '';
$self->{data} = [];
$self->{bgcolor} = '#FFFFFF';
$self->{fgcolor} = '#000000';
$self->{limit} = [ 7, '#FF0000', 'others' ];
$self->{transparent} = 0;
$self->{interlaced} = 0;
$self->{thickness} = 30; # pixels
$self->{radius} = $self->{xmax} / 3;
$self->{want_sort} = 0;
$self->{border} = 0;
$self->{percents} = 0;
}
=head2 Commands
=over 5
=item C<thickness>
C<Chart::ThreeD::Pie::thickness(val)> I<object method>
This allows you to set the thickness (in pixel) of the pie if val is
defined. The current value is returned. Default value is 30 pixels.
Example:
print "Current thickness is ", $pie->thickness, " pixels\n";
# set it to 20.
$pie->thickness(20);
=cut
sub thickness {
my $self = shift;
my $arg = shift;
$self->{thickness} = $arg if defined $arg;
return $self->{thickness};
}
=item C<want_sort>
C<Chart::ThreeD::Pie::thickness(bool)> I<object method>
This will allow you to sort the parts of the pie if bool is non-null.
The current value is returned. Default is null;
Example:
print "Current want_sort value is ", $pie->want_sort, "\n";
# set it to true
$pie->want_sort(1);
=cut
sub want_sort {
my $self = shift;
my $arg = shift;
$self->{want_sort} = $arg if defined $arg;
return $self->{want_sort};
}
=item C<transparent>
C<Chart::ThreeD::Pie::transparent(bool)> I<object method>
This will allow you to make the background of the final picture transparent
if bool is non-null. The current value is returned. Default is null;
Example:
# Background will be transparent.
$pie->transparent(1);
=cut
sub transparent {
my $self = shift;
my $arg = shift;
$self->{transparent} = $arg if defined $arg;
return $self->{transparent};
}
=item C<interlaced>
C<Chart::ThreeD::Pie::interlaced(bool)> I<object method>
This will allow you to make the background of the final picture interlaced
if bool is non-null. The current value is returned. Default is null;
Example:
# Picture will be interlaced
$pie->interlaced(1);
=cut
sub interlaced {
my $self = shift;
my $arg = shift;
$self->{interlaced} = $arg if defined $arg;
return $self->{interlaced};
}
=item C<percents>
C<Chart::ThreeD::Pie::percents(bool)> I<object method>
This will add percentages after the label of each part of the pie
if bool is non-null. The current value is returned. Default is null;
Example:
# add percents in labels
$pie->percents(1);
=cut
sub percents {
my $self = shift;
my $arg = shift;
$self->{percents} = $arg if defined $arg;
return $self->{percents};
}
=item C<bgcolor>
C<Chart::ThreeD::Pie::bgcolor(bgcolor)> I<object method>
Set the background color if bgcolor is defined. The current value is
returned. Default value is '#000000' (black). Color is a string
composed of a '#' followed by 3 two-digits hexadecimal values, respectively
Red, Green and Blue.
Example:
# set the background color to yellow
$pie->bgcolor ('#FFFF00');
=cut
lib/Chart/ThreeD/Pie.pm view on Meta::CPAN
return $self->{ymax};
}
=item C<title>
C<Chart::ThreeD::Pie::title(val)> I<object method>
This allows you to change the title of the pie if val is defined.
The current value is returned.
Example:
print "Current title is '", $pie->title, "'\n";
# set it to 'my own title'.
$pie->title('my own title');
=cut
sub title {
my $self = shift;
my $arg = shift;
$self->{title} = $arg if defined $arg;
return $self->{title};
}
=item C<add>
C<Chart::ThreeD::Pie::add(val, color, label)> I<object method>
This method adds a part to a pie. The size of the part is specified by val.
Both color and label are optional. The default color is '#DDDDDD' and the
default label is ''.
=cut
sub add {
my $self = shift;
my $value = shift;
my $color = shift || "#DDDDDD";
my $label = shift || '';
push @{$self->{data}}, [ $value, $color, $label ];
}
=item C<plot>
C<Chart::ThreeD::Pie::plot()> I<object method>
Draw the pie. This method returns a GD object (see L<GD>).
=cut
sub plot {
my $self = shift;
my $pie = new GD::Image($self->xmax, $self->ymax);
my $fontw = gdSmallFont->width;
my $fonth = gdSmallFont->height;
my $bgcolor = $pie->colorAllocate (&cvtcolor ($self->bgcolor));
$pie->transparent ($bgcolor) if $self->transparent;
$pie->fill (0, 0, $bgcolor);
my $total = 0;
map { $total += $$_[0] } @{$self->{data}};
my $fgcolor = $pie->colorAllocate (&cvtcolor ($self->fgcolor));
my $defaultcolor = $pie->colorAllocate (&cvtcolor (${$self->limit}[1]));
my $defaultcolor2 = $pie->colorAllocate
(&shadecolor (&cvtcolor (${$self->limit}[1])));
my $orgx = $self->xmax / 2;
my $orgy = $self->ymax / 2 - $self->thickness / 2 + gdGiantFont->height / 2;
my $x = $self->radius * 11 / 6;
my $y = $self->radius * 7 / 6;
$pie->arc ($orgx, $orgy, $x, $y, 0, 360, $fgcolor);
$pie->fill ($orgx, $orgy, $defaultcolor);
$pie->arc ($orgx, $orgy + $self->thickness, $x, $y, 0, 180, $fgcolor);
$pie->line ($orgx - $x / 2, $orgy, $orgx - $x / 2, $orgy + $self->thickness,
$fgcolor);
$pie->line ($orgx + $x / 2, $orgy, $orgx + $x / 2, $orgy + $self->thickness,
$fgcolor);
$pie->fill ($orgx, $orgy + $self->thickness * 3 / 4 + $y / 2,
$defaultcolor2);
my @data = $self->want_sort ? sort {$$b[0] <=> $$a[0]} @{$self->{data}} :
@{$self->{data}};
my ($elem, $old);
my $num = 0;
my $a0 = 270;
my $a = $a0;
my $k = 0.55;
for $elem (@data) {
$num++;
my $angle = 360 * $$elem[0] / $total;
my $ang = $a + $angle / 2;
my $h = sin (°2rad ($ang - $a0));
my $r = cos (°2rad ($ang - $a0));
my $color = $pie->colorAllocate (&cvtcolor ($$elem[1]));
my $color2 = $pie->colorAllocate (&shadecolor (&cvtcolor ($$elem[1])));
my $dial = 0;
$dial = 1 if $h >= 0 && $r >= 0;
$dial = 2 if $h >= 0 && $r < 0;
$dial = 3 if $h < 0 && $r < 0;
$dial = 4 if $h < 0 && $r >= 0;
if (!$self->want_sort || !${$self->limit}[0] ||
($ {$self->limit}[0] > 0 && $angle > $ {$self->limit}[0] * 3.6)) {
$pie->line ($orgx, $orgy, $orgx - $x / 2 * sin (°2rad ($a)),
$orgy - $y / 2 * cos (°2rad ($a)), $fgcolor)
unless $$elem[0] == $total;
$pie->line ($orgx, $orgy,
$orgx - $x / 2 * sin (°2rad ($a + $angle)),
$orgy - $y / 2 * cos (°2rad ($a + $angle)), $fgcolor)
unless $$elem[0] == $total;
$pie->fill ($orgx - $x / 4 * sin (°2rad ($a + $angle / 2)),
$orgy - $y / 4 * cos (°2rad ($a + $angle / 2)),
$color);
$pie->line ($orgx - $x / 2 * sin (°2rad ($a + $angle)),
( run in 1.262 second using v1.01-cache-2.11-cpan-39bf76dae61 )