Audio-DB

 view release on metacpan or  search on metacpan

DB/Reports.pm  view on Meta::CPAN

 -height      desired height of the image in pixels
 -range       array of year range to display (ie [1950..2004]).
              If not provided, all years in the collection will be used
 -background  background color for the image as an [r g b] array reference
 -foreground  foreground color for the boxes as an [r g b] array reference
 -omit_totals if provided, yearly totals will be omitted

=cut

sub distribution {
  my ($self,@p) = @_;
  my ($class,$width,$height,$range,$background,$foreground,$omit_totals)
    = rearrange([qw/CLASS WIDTH HEIGHT RANGE BACKGROUND FOREGROUND OMIT_TOTALS/],@p);

  eval { use GD; };# or die "You need to install the GD.pm module in order to use the album_distibution() method";

  # Set up some suitable defaults
  use constant DEBUG => 0;
  $width    ||= 600;
  $height   ||= 550;

  # Padding around all sides of the image
  my $PADRIGHT  = 20;
  my $PADLEFT   = 50;
  my $PADTOP    = 10;
  my $PADBOTTOM = 50;

  my $adaptor = $self->adaptor;
  my $sth = ($class eq 'songs') 
    ? $adaptor->song_queries('songs_per_year') : $adaptor->album_queries('albums_per_year');

  # Calculate the totals for each year
  my %years_seen;
  foreach (@$range) {
    $sth->execute($_);
    my ($result) = $sth->fetchrow_array;
    $years_seen{$_} = $result;
  }

  # Find the year which contains the most albums to dynamically set the y-scale
  my @sorted_years = sort { $years_seen{$a} <=> $years_seen{$b} } @$range;
  my $biggest_year = $years_seen{$sorted_years[-1]};
  my $yscale = ($height - ($PADTOP + $PADBOTTOM) - 30) / $biggest_year;

  print STDERR "y-scale: $yscale\n" if DEBUG;
  print STDERR "biggest year: $sorted_years[-1], $biggest_year\n" if DEBUG;

  my $im = new GD::Image($width,$height);

  push(@$background,255,255,0) unless @$background;
  my ($bred,$bgreen,$bblue) = @{$background};
  my $bg = $im->colorAllocate($bred,$bgreen,$bblue);

  push(@$foreground,0,255,255) unless @$foreground;
  my ($fred,$fgreen,$fblue) = @$foreground;
  my $fg    = $im->colorAllocate($fred,$fgreen,$fblue);

  my $black = $im->colorAllocate(0,0,0);
  my $blue  = $im->colorAllocate(0,0,255);
  
  $im->transparent($bg);
  $im->rectangle(0 + $PADLEFT,0 + $PADTOP,
		 $width - $PADRIGHT,$height - $PADBOTTOM,$black);

  # Set up the axis, grid, and labels
  # Create a suitable scale of y-axis tick marks
  # if drawing 10 up the axis
  my $division = int($biggest_year/10);
  my $total = $division * 10;
  for (my $i = 0;$i<=9;$i++) {
    my $y1 = ($division * $i) * $yscale + $PADBOTTOM;
    print STDERR $division . '-' . $y1,"\n" if DEBUG;
    $im->line(0+$PADLEFT-5,$y1,0 + $PADLEFT,$y1,$black);
    $im->line(0+$PADLEFT,$y1,$width - $PADRIGHT,$y1,$blue);
    $im->string(gdTinyFont,$PADLEFT-20,$y1-(gdTinyFont->height/2),($total - ($division*$i)),$black);
  }

  $im->stringUp(gdSmallFont,0+5,((($height - $PADTOP - $PADBOTTOM)/2) + (gdSmallFont->height * 1)/2),
     'TOTAL ' . uc($class),$black);
  $im->string(gdSmallFont,
	      (($width - $PADLEFT - $PADRIGHT)/2) + ((gdSmallFont->width * 5)/2),$height-20,'YEARS',$black);

  # Now I need to iterate through the range drawing boxes
  # Dynamically set the box width based on the number of years seen
  my $boxwidth = ($width - ($PADLEFT + $PADRIGHT)) / scalar (@$range);
  my $xoffset;
  foreach my $year (@$range) {
    my $total = $years_seen{$year} || 0;
    
    # normalize the yoffset to the biggest column
    my $y1 = int(($height - $PADBOTTOM) - ($total * $yscale));
    my $x1 = int($PADLEFT + $xoffset);
    
    my $x2 = int($x1 + $boxwidth);
    my $y2 = int($height - $PADBOTTOM);
    $im->filledRectangle($x1,$y1,$x2,$y2,$fg);
    $im->rectangle($x1,$y1,$x2,$y2,$black);
    #  $im->stringUp(gdTinyFont,$x1-2,$y2+25,$year,$black);
    
    # Add the year and totals
    $im->stringUp(gdTinyFont,$x1 + ((gdTinyFont->width * 1)/2),$y2+25,$year,$black);
    unless ($omit_totals) {
      $im->stringUp(gdTinyFont,$x1 + ((gdTinyFont->width * 1)/2),$y1-5,$total,$black);
    }
    $xoffset += $boxwidth;
    print STDERR join("\t",$year,$total,$x1,$y1,$x2,$y2),"\n" if DEBUG
  }

  my $string = $im->png;
  return $string;
}


=pod

=item $report->library_size()

Calculate the full size of your library. Returns a hash reference
containing the size in kilobytes (Kb), megabytes (MB), and the size in
gigabytes (GB).



( run in 1.154 second using v1.01-cache-2.11-cpan-f889d44b568 )