Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Gantt Diagrams

by larsen (Parson)
on Apr 02, 2001 at 10:56 UTC ( [id://68941]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info larsen
Description: Simple module to produce Gantt diagram from XML project descriptions.
Or, what Perl can do to help you if you're planning to conquer the world?.
package Gantt;

use strict;

use XML::Simple;
use Data::Dumper;

BEGIN {
    use Exporter qw();

    use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);

    @ISA = qw( Exporter );

    $VERSION = 0.1;

    @EXPORT_OK = qw();
    @EXPORT = qw();
}

use vars @EXPORT_OK;
use vars qw();

my %marked = ();
my $Debug = 0;

sub new
{
    my $self = {};

    $self->{ Project } = undef;
    $self->{ Start } = undef;

    return bless $self;
}


# Obtains a Directed Acyclic Graph from project description
# It also finds and returns the first task in the project 
# (ATTENTION: this task must be is unique)
sub project_to_dag
{
    my $self = shift;
    
    my $start;
    
    foreach my $task ( keys %{ $self->{ Project }->{task} } ) {
        if (not (defined $self->{Project}->{task}->{$task}->{dependenc
+y})) {
            $start = $task;
        } else {
            
            foreach my $t ( @{$self->{Project}->{task}->{$task}->{depe
+ndency}} ) {   
                push @{ $self->{ Project }->{task}->{$t}->{adjacent}},
+ $task; 
            }
        }
    }
    $self->{Start} = $start;

    print Dumper( $self->{ Project } ) if $Debug;
}


# Topological Sort
# see "Data Structures and Algorithms", A.V.Aho, J.E.Hopcroft, J.D.Ull
+man, p. 221 
sub topsort 
{
    my $self = shift;

    my $task = shift;
    my $pred = shift;

    $marked{ $task } = 1;
    if ( $pred ) {
        $self->{ Project }->{task}->{$task}->{from_start} = 
            $self->{ Project }->{task}->{$pred}->{from_start} + 
            $self->{ Project }->{task}->{$pred}->{duration};
    }

    if (defined @{  $self->{ Project }->{task}->{$task}->{adjacent}} )
+ {

        my @sorted_tasks = sort {
            $self->{Project}->{task}->{$b}->{duration} <=>
            $self->{Project}->{task}->{$a}->{duration}
        } @{ $self->{ Project }->{task}->{$task}->{adjacent}};

        foreach my $t ( @sorted_tasks ) {
            if (not $marked{ $t }) {
                $self->topsort( $t, $task );
            }
            
        }
    }
}


sub load_project 
{
    my $self = shift;
    
    my $project_file_name = shift;

    $self->{ Project } = XMLin( $project_file_name, forcearray => 1)
    || die "Can't load project file - $! ";

    $self->project_to_dag( $self->{ Project } );
    $self->topsort( $self->{ Start });
}


sub length
{
    my $self = shift;

    my @l = sort { $b <=> $a } map {
        $_->{from_start} + $_->{duration}
    } values %{ $self->{ Project }->{task}};

    return $l[0];
}


sub print_as_text 
{
    my $self = shift;
    my $l = $self->length();
    
    print Dumper( $self->{ Project } ) if $Debug;

    print "$self->{ Project }->{ name }\n";
    
    print ' ' x (20+7);
    for my $i ( 1..$l ) {
        print ($i % 5 ? '-' : '+'); 
    }
    print "\n\n";

    foreach my $task ( keys %{ $self->{ Project }->{task} } ) {
        printf "%-20s [%3d] ", $task, $self->{ Project }->{task}->{$ta
+sk}->{duration};
        print '-' x $self->{ Project }->{task}->{$task}->{from_start} 
+.
            '#' x $self->{ Project }->{task}->{$task}->{duration} . "\
+n";    
    }

    print "Total days: $l\n\n";
}


"That's all, folks";
END {
}

=head1 AUTHOR

Stefano Rodighiero, (stefano@filibusta.crema.unimi.it)

=cut

__END__

=head1 NAME

Gantt - Simple module to produce Gantt diagram from
XML project descriptions.

=head1 EXAMPLE

    use Gantt;

    my $g = new Gantt();

    $g->load_project( './project.xml' );
    $g->print_as_text;

Here a simple XML project description in the form expected
by this module

    <project name="Program development">
    <task name="Define Specifics" duration="5">
    </task>

    <task name="Analysis" duration="10">
    <dependency>Define Specifics</dependency>
    </task>

    <task name="Search documentation" duration="3">
    <dependency>Define Specifics</dependency>
    </task>

    <task name="Write code" duration="7">
    <dependency>Analysis</dependency>
    <dependency>Search documentation</dependency>
    </task>

    <task name="Write documentation" duration="5">
    <dependency>Write code</dependency>
    </task>

    <task name="Test" duration="5">
    <dependency>Write code</dependency>
    </task>

    <task name="Release" duration="2">
    <dependency>Test</dependency>
    <dependency>Write documentation</dependency>
    </task>

    </project>

=head1 WHAT I WOULD LIKE TO DO

=item * HTML output

=item * GraphViz output

=item * Graphic output using GD

=item * Tk interface to produce XML project description

=cut

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://68941]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2024-04-16 11:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found