Project-Gantt
view release on metacpan or search on metacpan
Gantt/Gantt/ImageWriter.pm view on Meta::CPAN
##########################################################################
#
# File: Project/Gantt/ImageWriter.pm
#
# Author: Alexander Westholm
#
# Purpose: The ImageWriter object coordinates the visualization
# of scheduling data. It creates the canvas, and all
# supporting objects that write different aspects of the
# chart to the screen.
#
# Client: CPAN
#
# CVS: $Id: ImageWriter.pm,v 1.14 2004/08/03 17:56:52 awestholm Exp $
#
##########################################################################
package Project::Gantt::ImageWriter;
use strict;
use warnings;
use Image::Magick;
use Project::Gantt::DateUtils qw[:round :lookup];
use Project::Gantt::Globals;
use Project::Gantt::GanttHeader;
use Project::Gantt::TimeSpan;
use Project::Gantt::SpanInfo;
##########################################################################
#
# Method: new(%opts)
#
# Purpose: Constructor. Takes as parameters the mode of drawing
# (hours, days, or months), the root Project::Gantt object,
# and the skin in use.
#
##########################################################################
sub new {
my $cls = shift;
my %opts= @_;
if(not $opts{root}){
die "Must supply root node to ImageWriter!";
}
$opts{mode} = 'days' if not $opts{mode};
my $me = bless \%opts, $cls;
$me->_getCanvas();
return $me;
}
##########################################################################
#
# Method: _getCanvas()
#
# Purpose: This method examines the root node, and sets the width
# of the canvas based on the timespan covered by the chart,
# and sets the height based on how many schedule items
# constitute the chart.
#
##########################################################################
sub _getCanvas {
my $me = shift;
my ($height, $width) = (0,0);
$height = 40;
# add height for each row
$height += 20 for (1..$me->{root}->getNodeCount());
$width = 205;
my $incr = $DAYSIZE;
$incr = $MONTHSIZE if($me->{mode} eq 'months');
# add width for each time unit
$width += $incr for (1..$me->{root}->timeSpan());
my $canvas = new Image::Magick(size=>"${width}x$height");
$canvas->Read('xc:'.$me->{skin}->background());
$me->{canvas} = $canvas;
}
##########################################################################
#
# Method: display(filename)
#
# Purpose: Creates the Calendar header and draws it, then calls
# writeBars to draw in all tasks/subprojects. Finally,
# writes the image to a file.
#
##########################################################################
sub display {
my $me = shift;
my $img = shift;
my $hdr = new Project::Gantt::GanttHeader(
canvas => $me->{canvas},
skin => $me->{skin},
root => $me->{root});
$hdr->display($me->{mode});
# PW added parameters, required by new writeBars with recursive support
$me->writeBars($me->{'root'}, 40);
$me->{canvas}->Write($img);
}
##########################################################################
#
# Method: writeBars()
#
# Purpose: Iterates over all tasks/subprojects contained by the root
# object, and creates SpanInfo and TimeSpan objects for each
# item, then draws them.
#
# Peter Weatherdon: Jan 19, 2005
# Modified this method to allow recursion for support of nested
# projects (more than 1 level deep)
#
##########################################################################
sub writeBars {
my $me = shift;
my $project = shift;
my $height = shift;
my $stDate = $me->{root}->getStartDate();
my @tasks = $project->getTasks();
my @projs = $project->getSubProjs();
# write tasks before sub-projects.. adjust height as we go
for my $tsk (@tasks,@projs){
my $info= new Project::Gantt::SpanInfo(
canvas => $me->{canvas},
skin => $me->{skin},
task => $tsk);
$info->display($height);
my $bar = new Project::Gantt::TimeSpan(
canvas => $me->{canvas},
skin => $me->{skin},
task => $tsk,
rootStr => $stDate);
( run in 2.719 seconds using v1.01-cache-2.11-cpan-d8267643d1d )