PDF-Reuse-OverlayChart
view release on metacpan or search on metacpan
OverlayChart.pm view on Meta::CPAN
}
}
if (! defined $self->{color})
{ $self->{color} = ['0 0 0.8', '0.8 0 0.3', '0.9 0.9 0', '0 1 0', '0.6 0.6 0.6',
'1 0.8 0.9', '0 1 1', '0.9 0 0.55', '0.2 0.2 0.2','0.55 0.9 0.9'];
}
return $self;
}
sub overlay
{ my $self = shift;
my %param = @_;
for (keys %param)
{ my $key = lc($_);
if ($possible{$key})
{ $self->{$key} = $param{$_};
}
else
{ warn "Unrecognized parameter: $_, ignored\n";
}
OverlayChart.pm view on Meta::CPAN
elsif (substr($self->{type}, 0, 1) eq 'a')
{ $self->{type} = 'area';
}
else
{ $self->{type} = 'bars';
}
}
$self->{xdensity} = 1 if (! exists $self->{xdensity});
$self->{ydensity} = 1 if (! exists $self->{ydensity});
$self->{level} = 'overlay';
return $self;
}
sub add
{ my $self = shift;
my @values = @_;
my $name = shift @values || ' ';
my $num = 0;
my $ready;
if (! defined $self->{col})
OverlayChart.pm view on Meta::CPAN
{ $chartMin = $self->{initialminy}
}
if ((exists $param{'merge'}) && ($self->{type} ne 'percentbars'))
{ for (@{$param{'merge'}})
{ if ($_->{type} ne 'percentbars')
{ push @array, $_;
}
}
for my $overlay (@array)
{ my ($tmax, $tmin, $tmaxSum, $tminSum, $tnum) = $overlay->analysera();
if (($overlay->{type} eq 'totalbars') || ($overlay->{type} eq 'area'))
{ $tmaxSum = sprintf ("%.0f", ($tmaxSum / $overlay->{ydensity}));
$tminSum = sprintf ("%.0f", ($tminSum / $overlay->{ydensity}));
$chartMax = $tmaxSum if ($tmaxSum > $chartMax);
$chartMin = $tminSum if ($tminSum < $chartMin);
}
else
{ $tmax = sprintf ("%.0f", ($tmax / $overlay->{ydensity}));
$tmin = sprintf ("%.0f", ($tmin / $overlay->{ydensity}));
$chartMax = $tmax if ($tmax > $chartMax);
$chartMin = $tmin if ($tmin < $chartMin);
}
$tnum = sprintf ("%.0f", ($tnum / $overlay->{xdensity}));
$num = $tnum if ($tnum > $num);
$tnum = sprintf ("%.0f", ($self->{num} / $overlay->{xdensity}));
$num = $tnum if ($tnum > $num);
if ((defined $overlay->{rightscale})
&& (! defined $rightScale))
{ $rightScale = $overlay;
}
if ((defined $overlay->{topscale})
&& (! defined $topScale))
{ $topScale = $overlay;
}
$overlay->{x} = $self->{x};
$overlay->{xsize} = $self->{xsize};
$overlay->{size} = $self->{size};
$overlay->{y} = $self->{y};
$overlay->{ysize} = $self->{ysize};
}
}
my $xSteps = $#{$self->{col}} + 1;
$xSteps = $num if ($num > $xSteps);
my $groups = $#{$self->{sequence}} + 1;
if ($self->{type} ne 'percentbars')
{ if ($chartMin > 0)
{ $ySteps = $chartMax || 1;
}
OverlayChart.pm view on Meta::CPAN
my $col1 = 0.9;
my $col2 = 0.4;
my $col3 = 0.9;
srand(9);
my $tStart = $xStart + 20;
unshift @array, $self;
for my $overlay (@array)
{ if (defined $overlay->{groupstitle})
{ my $yTemp = $yStart;
if ($yTemp < ($y0 + 20))
{ $yTemp = $y0 - 20;
$yStart = $yTemp - 20;
}
$str .= "0 0 0 rg\n";
$str .= "BT\n";
$str .= "/$font 12 Tf\n";
$str .= "$xStart $yTemp Td\n";
$str .= '(' . $overlay->{groupstitle} . ') Tj' . "\n";
$str .= "ET\n";
$yStart -= $iStep;
}
if (defined $overlay->{groupstext})
{ my $yTemp = $yStart;
if ($yTemp < ($y0 + 20))
{ $yTemp = $y0 - 20;
$yStart = $yTemp - 20;
}
$str .= "0 0 0 rg\n";
$str .= "BT\n";
$str .= "/$font 12 Tf\n";
$str .= "$xStart $yTemp Td\n";
$str .= '(' . $overlay->{groupstext} . ') Tj' . "\n";
$str .= "ET\n";
$yStart -= $iStep;
}
my @color = (defined $overlay->{color}) ? @{$overlay->{color}} : ();
my $groups = $#{$overlay->{sequence}} + 1;
for (my $i = 0; $i < $groups; $i++)
{ if (! defined $color[$i])
{ $col1 = $col3;
my $alt1 = sprintf("%.2f", (rand(1)));
my $alt2 = sprintf("%.2f", (rand(1)));
$col2 = abs($col2 - $col3) > abs(1 - $col3) ? $col3 : (1 - $col3);
$col3 = abs($col3 - $alt1) > abs($col3 - $alt2) ? $alt1 : $alt2;
$color[$i] = "$col1 $col2 $col3";
}
if ((defined $overlay->{nogroups}) && ($overlay->{nogroups}))
{ next;
}
my $name = $overlay->{sequence}->[$i];
$str .= "$color[$i] rg\n";
if (($yStart < ($y0 + 13)) && ($yStart > ($y0 - 18)))
{ $yStart = $y0 - 20;
}
$str .= "$xStart $yStart 10 7 re\n";
$str .= "b*\n";
$str .= "0 0 0 rg\n";
$str .= "BT\n";
$str .= "/$font 12 Tf\n";
$str .= "$tStart $yStart Td\n";
if ($name)
{ $str .= '(' . $name . ') Tj' . "\n";
}
else
{ $str .= '(' . $i . ') Tj' . "\n";
}
$str .= "ET\n";
if ((defined $self->{iparam})
&& (defined $overlay->{boxAction}->{$name}))
{ $overlay->insert($xStart,
$yStart,
10,
7,
$self->{iparam},
$overlay->{boxAction}->{$name},
$overlay->{boxToolTip}->{$name});
}
$yStart -= $iStep;
}
@{$overlay->{color}} = @color;
}
for my $overlay ( reverse @array)
{ $str .= "0 0 0 RG\n0 j\n0 J\n";
if ($overlay->{type} eq 'bars')
{ $str .= $overlay->draw_bars($xSteps, $xCor, $y0, $labelStep, $prop);
}
elsif ($overlay->{type} eq 'totalbars')
{ $str .= $overlay->draw_totalbars($xSteps, $xCor, $y0, $labelStep, $prop);
}
elsif ($overlay->{type} eq 'lines')
{ $str .= $overlay->draw_lines($xSteps, $xCor, $yCor, $labelStep, $prop, $min);
}
elsif ($overlay->{type} eq 'percentbars')
{ $str .= $overlay->draw_percentbars($xSteps, $xCor, $y0, $labelStep, $prop);
}
elsif ($overlay->{type} eq 'area')
{ $str .= $overlay->draw_area($xSteps, $xCor, $y0, $labelStep, $prop);
}
}
$str .= "Q\n";
PDF::Reuse::prAdd($str);
return $self;
}
sub draw_bars
{ my $self = shift;
OverlayChart.pm view on Meta::CPAN
To force the program start with a specific max (positive) value for the scale along the y-axis.
=item initialMinY
To force the program start with a specific min (negative) value for the scale along the y-axis.
=item merge
To merge different graph-objects into one chart. The graph-objects should be put
in an anonymous array. Each graph-object should use the "overlay" method.
Ex :
$val->draw(x => 20,
y => 460,
width => 400,
height => 300,
type => 'lines',
noMarker => 1,
groupstitle => 'Left Scale',
title => 'Amazon',
yUnit => 'USD',
merge => [ $sek->overlay ( type => 'lines',
yDensity => $sekDensity,
noMarker => 1),
$spIndex->overlay( type => 'lines',
yDensity => $spDensity,
noMarker => 1),
$vol->overlay ( type => 'area',
rightScale => 1,
yDensity => $volumeDensity,
groupstitle => 'Right Scale'),] );
In the example above 4 objects are combined into 1 chart. Each object can have its'
own density (but it is not necessary) and some other characteristics described under
"overlay". The objects are painted in reversed order: $vol, $spIndex, $sek and at
last $val, which automatically gets the left scale and also the normative density
of the chart. (Interactive functions for each object are also imported.)
The merge parameter is ignored, if the type of the main object is percentbars
=item noMarker
Only for lines. No markers will be painted.
=item noGroups
OverlayChart.pm view on Meta::CPAN
To define colors to be used. The parameter to this method is a list of RGB numbers.
You can also use some predefined color arrays: 'bright', 'dark', 'gray' or 'light',
but only one at a time. Then you get 10 predefined colors ex:
$s-color('dark');
If the module needs more colors than what has been given in the script,
it creates more, just from random numbers.
=head2 overlay
Defines how an imported graph-object should be painted. See the parameter merge
under draw for an example.
Parameters:
=over 4
=item type
OverlayChart.pm view on Meta::CPAN
=head1 An example how to mix different graph types in the same chart
In this example you let a program collect historical quotes for 'Amazon', approximately
1 year back, and also values for 'S&P 100' and then you get a chart with combined
data, an area graph for volumes, and lines for the other values. (You need to have the
environment variable TZ defined somewhere, see Date::Manip, which is a module needed by
Finance::QuoteHist. TZ, time zone, could e.g. be CET or GMT in Western Europe.)
=for overlay.pl begin
use PDF::Reuse::OverlayChart;
use Finance::QuoteHist;
use PDF::Reuse;
use strict;
#################
# Some variables
#################
my (%values, @values, %volumes, @volumes, %sp100, @sp100, $startValue,
OverlayChart.pm view on Meta::CPAN
#####################
$val->draw(x => 20,
y => 460,
width => 400,
height => 300,
type => 'lines',
noMarker => 1,
groupstitle => 'Left Scale',
title => 'Amazon',
merge => [ $spIndex->overlay( type => 'lines',
yDensity => $spDensity,
noMarker => 1),
$vol->overlay ( type => 'area',
rightScale => 1,
yDensity => $volumeDensity,
groupstitle => 'Right Scale')] );
prEnd();
=for end
Comments about the example:
( run in 0.882 second using v1.01-cache-2.11-cpan-49f99fa48dc )