Module-Dependency
view release on metacpan or search on metacpan
lib/Module/Dependency/Grapher.pm view on Meta::CPAN
my ( $maxitems, $pushed ) =
_makeCols( $kind, $seeds, $options->{IncludeRegex}, $options->{ExcludeRegex} );
_imageDimsSet();
LOG("Making SVG to $filename");
if ( $maxitems < 8 ) {
$rowHeight = 8 * $rowHeight * 1.5 / $maxitems;
}
elsif ( $maxitems < 16 ) {
$rowHeight = 16 * $rowHeight / $maxitems;
}
my $imgWidth = $colWidth * ( scalar(@TIERS) < 3 ? 3 : scalar(@TIERS) );
my $imgHeight = $rowHeight * $maxitems;
my $realImgWidth = $imgWidth + $wOffset + $eOffset;
my $realImgHeight = $imgHeight + $nOffset + $sOffset;
LOG("Rows are $rowHeight px, maxitems is $maxitems, image is $realImgWidth * $realImgWidth");
my $im = new SVG(
'viewBox' => (
'0 0 '
. ( $imgWidth + $wOffset + $eOffset ) . ' '
. ( $imgHeight + $nOffset + $sOffset )
),
'preserveAspectRatio' => 'xMidYMid',
'-indent' => "\t"
);
# set up image object
my $colours;
while ( my ( $k, $v ) = each %COLOURS ) {
$colours->{$k} = sprintf( '#%2.2x%2.2x%2.2x', @$v );
}
$im->rectangle(
'x' => 0,
'y' => 0,
'width' => ( $imgWidth + $wOffset + $eOffset ),
'height' => ( $imgHeight + $nOffset + $sOffset ),
stroke => $colours->{'black'},
fill => 'none'
);
_packObjects( $imgHeight, 5 );
_linkObjects( $im, $colours );
# are things clickable? Bit of a kludge, this
$colours->{'_HREF_FORMAT'} = $options->{'HrefFormat'};
_labelObjects( $im, $colours );
delete $colours->{'_HREF_FORMAT'};
# add legend and prettiness
TRACE("Drawing legend etc");
$im->text(
'x' => 5,
'y' => 12,
'fill' => $colours->{'title1'},
'style' => { 'font-size' => '12px' }
)->cdata($imgtitle);
$im->text(
'x' => 5,
'y' => 23,
'fill' => $colours->{'title1'},
'style' => { 'font-size' => '9px' }
)->cdata( "Grapher.pm $VERSION - " . localtime() )
unless $options->{'NoVersion'};
_drawLegend( $im, $colours, $realImgWidth - 160 - $eOffset, 3 ) unless $options->{'NoLegend'};
$im->title( id => 'document-title' )->cdata($imgtitle);
$im->desc( id => 'document-desc' )
->cdata('This image shows dependency relationships between perl programs and modules');
TRACE("Printing SVG");
local *IMG;
open( IMG, "> $filename" ) or die("Can't open $filename for image write: $!");
print IMG $im->xmlify;
close IMG;
}
sub makePs {
require PostScript::Simple;
my ( $kind, $seeds, $filename, $options ) = @_;
my $imgtitle = $options->{'Title'} || 'Dependency Chart';
my $eps = ( uc( $options->{'Format'} ) eq 'PS' ) ? 0 : 1;
my $colour = exists( $options->{'Colour'} ) ? $options->{'Colour'} : 1;
my $font = $options->{'Font'} || 'Helvetica';
my ( $maxitems, $pushed ) =
_makeCols( $kind, $seeds, $options->{IncludeRegex}, $options->{ExcludeRegex} );
_psDimsSet();
LOG("Making postscript to $filename");
if ( $maxitems < 8 ) {
$rowHeight = 8 * $rowHeight * 1.5 / $maxitems;
}
elsif ( $maxitems < 16 ) {
$rowHeight = 16 * $rowHeight / $maxitems;
}
my $imgWidth = $colWidth * ( scalar(@TIERS) < 3 ? 3 : scalar(@TIERS) );
my $imgHeight = $rowHeight * $maxitems;
my $realImgWidth = $imgWidth + $wOffset + $eOffset;
my $realImgHeight = $imgHeight + $nOffset + $sOffset;
LOG("Rows are $rowHeight px, maxitems is $maxitems, image is $realImgWidth * $realImgWidth");
my $p = new PostScript::Simple(
eps => $eps,
colour => $colour,
clip => 1,
landscape => ( !$eps ),
xsize => $realImgWidth,
ysize => $realImgHeight,
units => 'bp'
) # we use points because they're close to pixels, as used in GD
|| die("Can't build Postscript object: $!");
$p->setlinewidth(0.5);
$p->setfont( $font, 9 );
_packObjects( $imgHeight, 5.5 );
_linkObjects($p);
$p->setcolour( @{ $COLOURS{'type'} } );
_labelObjects($p);
# add legend and prettiness
TRACE("Drawing legend etc");
_drawPsLegend( $p, $realImgWidth - 160 - $eOffset, 16 ) unless $options->{'NoLegend'};
$p->setfont( $font, 16 );
lib/Module/Dependency/Grapher.pm view on Meta::CPAN
$x += 4;
$y += 3;
_drawText( $im, $colours, $x, $y, 'Legend' );
if ( $type =~ m/^GD/ ) {
$im->line( $x, $y + 8, $x + 30, $y + 8, $colours->{'type'} );
}
elsif ( $type =~ m/SVG/ ) {
$im->line(
x1 => $x,
y1 => $y + 8,
x2 => $x + 30,
y2 => $y + 8,
stroke => $colours->{'type'}
);
}
$y += 12;
_drawLink( $im, $colours, $x + 31, $y, 100 + $x, $y );
_drawText( $im, $colours, $x, $y, 'Foo.pl' );
_drawText( $im, $colours, 100 + $x, $y, 'Bar' );
$y += 12;
_drawText( $im, $colours, $x, $y, 'Foo.pl depends upon Bar.pm' );
}
sub _drawPsLegend {
my ( $p, $x, $y ) = @_;
_drawText( $p, undef, $x + 2, $y + 26, 'Legend' );
$p->setlinewidth(0.4);
$p->line( $x + 2, $y + 25, $x + 32, $y + 25 );
_drawText( $p, undef, $x + 2, $y + 14, 'Foo.pl' );
_drawText( $p, undef, $x + 102, $y + 14, 'Bar' );
_drawText( $p, undef, $x + 2, $y + 2, 'Foo.pl depends upon Bar.pm' );
_drawLink( $p, undef, $x + 29, $y + 14, $x + 102, $y + 14 );
$p->setlinewidth(0.25);
$p->setcolour( @{ $COLOURS{'black'} } );
$p->box( $x, $y - 1, $x + 120, $y + 34 );
}
# ! behaves differently for each image type
sub _drawText {
my ( $im, $colours, $x, $y, $text ) = @_;
my $type = ref($im);
# TRACE("_drawText for $type");
if ( $type =~ m/^GD/ ) {
$im->string( gdTinyFont(), $x, $y, $text, $colours->{'type'} );
}
elsif ( $type =~ m/^PostScript/ ) {
$im->text( $x, $y, $text );
}
elsif ( $type =~ m/^SVG/ ) {
if ( $colours->{'_HREF_FORMAT'} ) {
$im->anchor( -href => sprintf( $colours->{'_HREF_FORMAT'}, $text ) )->text(
'x' => $x,
'y' => $y + 5.5,
'fill' => $colours->{'type'},
'style' => { 'font-size' => '8px', 'font-family' => 'Courier, Monaco, monospaced' }
)->cdata($text);
}
else {
$im->text(
'x' => $x,
'y' => $y + 5.5,
'fill' => $colours->{'type'},
'style' => { 'font-size' => '8px', 'font-family' => 'Courier, Monaco, monospaced' }
)->cdata($text);
}
}
}
# ! behaves differently for each image type
sub _drawLink {
my ( $im, $colours, $xa, $ya, $xb, $yb ) = @_;
my $type = ref($im);
# TRACE("_drawLink for $type");
if ( $type =~ m/^GD/ ) {
$im->line( $xa, $ya + 3, $xb - 3, $yb + 3, $colours->{'links'} );
$im->rectangle( $xa, $ya + 2, $xa + 1, $ya + 4, $colours->{'blob_from'} );
$im->rectangle( $xb - 3, $yb + 2, $xb - 4, $yb + 4, $colours->{'blob_to'} );
}
elsif ( $type =~ m/^PostScript/ ) {
$im->setlinewidth(0.22);
$im->line( $xa, $ya + 3, $xb - 3, $yb + 3, @{ $COLOURS{'black'} } );
$im->setcolour( @{ $COLOURS{'white'} } );
$im->circle( $xb - 3, $yb + 3, 1, 1 );
$im->setcolour( @{ $COLOURS{'black'} } );
$im->circle( $xa, $ya + 3, 1, 1 );
$im->circle( $xb - 3, $yb + 3, 1, 0 );
}
elsif ( $type =~ m/^SVG/ ) {
$im->line(
x1 => $xa,
y1 => $ya + 3,
x2 => $xb - 3,
y2 => $yb + 3,
stroke => $colours->{'links'}
);
$im->rectangle(
'x' => $xa,
'y' => $ya + 2,
'width' => 2,
'height' => 2,
stroke => 'none',
fill => $colours->{'blob_from'}
);
$im->rectangle(
'x' => $xb - 4,
'y' => $yb + 2,
'width' => 2,
'height' => 2,
stroke => 'none',
fill => $colours->{'blob_to'}
);
}
else {
die 'This indicates that the object model has changed somewhere. Should not happen.';
}
}
sub _imageDimsSet {
$colWidth = 200;
$rowHeight = 12;
$nOffset = 40;
( run in 2.272 seconds using v1.01-cache-2.11-cpan-5b529ec07f3 )