view release on metacpan or search on metacpan
2.4.8 Bug repaired: rt.cpan.org #81171::Composite w/two ::Lines and xy_plot ==> undefined value when drawing ticks
(t/composite_7.t and t/composite_8.t are showing the differences)
Base.pm: defined(@array)
Chart.pod corrected for deprecated @ARR->[$i]
2.4.7 Not published
2.4.6 Number of named colors extended
Documentation.pdf explains the use of colors (Appendix added)
Corrections in base.pm, routines
_draw_bottom_legends, _draw_x_number_ticks
in LinesPoints.pm, routines _draw_data
2.4.5 Typo in _draw_x_ticks corrected
Methods scalar_png(), scalar_jpeg() corrected for result.
Test routine t/scalarImage.t added
Chart.pod corrected
2.4.4 The brush styles to points and linespoints are extended.
Not only circles represent the points but a number of different
brush styles, linke donut, Star and so on.
$chart->set( xlabels => \@labels,
xrange => [0,100] );
This options allow to set and position labels at the x-axis arbitrary.
add_dataset() and app_pt() accepts now datasets as lists and as
references to list like already mentioned in the docs
Pie.pm:
Optimized organisation of the placement of the labels.
Added flag to avoid plotting of legends at all
Using GD Version 2.0.36 as this version supports 'filledArc'
Composite.pm:
Correction due to Request 23166
write the endmost value of input array
in imagemap_data array
Lines.pm:
Correction due to Request 23166:
write the endmost value of input array
in imagemap_data array
2.4.1 Changes done by Christine Zilker, Gerhard Stuhlpfarrer, R. Dassing
Added new Options:
ring Draw a ring instead of a Pie
legend_lines Connect Pie and the description with a line
stepline Connect Lines and LinesPoints by a stepped line
stepline_mode (thanks to Gerhard Stuhlpfarrer)
brush_size1 Define Brush Size for Composite 1
brush_size2 and 2
Color problem in Pie fixed
Positioning of the description optimized in Pie
Division by zero problem fixed in Pie
Module 'Bars' checks for numeric data a input on y-axis
New Function added to Base:
minimum - determine minimal value of an array of numeric values
Some small bugs corrected:
Base::_find_y_scale
Base::_find_y_range : check for numeric values
Base::_find_x_range : check for numeric values
Latex sources for documentation included
(We hope to get a better documentation be a native english speaking person)
2.3 Changes done by Christine Zilker:
Added new Options:
in Composite:
legend_example_height changes thickness of the lines in the legend,
f_y_tick1, f_y_tick2 analog to f_y_tick
used for right and left y-axes
in Direction:
pairs
Added the possibility to add more datasets in Chart::Direction
Fixed "label space" problem in Pie
Fixed dataset order (in the legend) in StackedBars
Fixed problem of getting the right values if round2Tick is used
Fixed problem of datavalues in _find_y_scale
Some minor bugfixes
Update of the Documentation (Documentation.pdf)
The requested support of TruType fonts was currently dropped due to
missing support in GD.pm (even in new versions)
The print out of some hints and warnings where deleted not to confuse
new Modules added: ErrorBars.pm, HorizontalBars.pm, Pareto.pm,
Pie.pm, Split.pm and Direction.pm
Subdirectory "doc" contains a Acrobat Reader Documentation.pdf file.
Function add_datafile() added. It is now possible to add a complete
datafile.
Added new Options: precision, xy_plot, min_x_ticks, max_x_ticks,
skip_y_ticks, skip_int_ticks, legend_label_value, y_axes,
scale, interval, start, interval_ticks, sort, same_error, point,
line, arrow, angle_interval, min_circles, max_circles
Also added: the 'title' and 'x_label' options in the colors option
Documentation (Documentation.pdf) added.
_find_x_scale, _find_x_range and _draw_x_number_ticks added to make
xy_plots possible.
_sort_data has now a body.
Ticks on plot scales are now plotted on 'round' numbers.
The number & spacing of ticks is chosen based on the data range.
False zero graphs are now explicitly supported, and will be
generated if the data range merits it.
The instance field 'include_zero' should be set to zero to suppress this.
Added: include_zero, min_y_ticks, max_y_ticks, integer_ticks_only
1.0.1:
Fixed _draw_bottom_legend in Base.pm
0.99c-pre3 - 1.0:
Fixed _draw_data in Lines.pm: lines are limited to the frame
Added f_x_tick, f_y_tick
Added jpeg(), cgi_jpeg() to produce the format jpeg
Delete GIF support, added PNG and JPEG instead
0.99b - 0.99c-pre3:
James F Miner <jfm@winternet.com>:
Added Mountain chart type
Added Patterns. See t/mountain.t for details
Bugfix for drifting x tick
Improved internal color handling
Richard Dice <rdice@shadnet.shad.ca>:
Added brush shapes for Points, LinesPoints
Added scalar_gif
0.99a - 0.99b:
Fixed left legend in composite charts
Fixed no color problem when using composite charts w/ no legend
Fixed color handling for datasets
Added option for http header Pragma: no-cache
Netscape 4.5 has a bug that breaks it, but it works with
other browsers. Any ideas for a workaround?
0.99 - 0.99a:
Added use of undef() values to represent 'no data' for line breaks
Added ylabel*_color options
Added x_grid_lines, y_grid_lines & y2_grid_lines , and color options for each
Cache disabling in cgi header: Reiner Nippes <nippes.r@gmx.de>
Changed the API for specifying colors
Added support for printing to file handles
Added Chart::Composite
Added 'spaced_bars' to make it easy to differentiate the bars
Added 'grey_background' to make plot background grey
Added support for negative values in the datasets
Added methods to remember and dump imagemap pixel information
Included rgb.txt with distribution for WinXX users
0.93 - 0.94:
Moved the legend down to be flush with the chart
Fixed the long decimal y-tick label problem
Fixed (for the last time, hopefully) the pre-5.004 compilation problem
Fixed handling of undefined data points
Added more colors for the default data colors
Added the transparent gif option
Added the option for user-specified colors
Added the grid_lines option
0.92 - 0.93:
Fixed the sort problem
ROADMAP:
-------
3.0 rewrite complete
...
2.406 rewrite axis, tiks, label, box rendering
2.405 rewrite legend rendering with new elements
2.404 true type support and adding unifont (mountain patterns ?)
we are here <-------------------------------------------------
2.403 replaced old pdf and html with new POD documentation with embedded HML img
2.402 new, powerful color management: HSL, hex_RGB, hash_RGB, Pantone colors
2.401 reformat distribution to be based on Dist::Zilla, solve CPAN issues
TODO's:
min_val results in this error
"Use of uninitialized value in multiplication ..."
: support up to 3 chart types -
for example: Mountain, StackedBars, LinesPoints
(The number of chart types should be flexible in general)
: Add option to limit the y-ticks to just one side
: Define different brush_sizes for example with one Lines dataset
and one LinesPoints dataset.
- pie chart:
: Add a flat pie chart where the legend appears on the left
of the chart, and the chart itself is about 50% smaller
: Add an option to reduce or remove all the border elements on the left,
on the right and on the bottom
: Allow to unset the title and remove the space occupied by the title,
i.e., make the plot bigger
: Add 3D appearance to the pies
: Set arbitrary background color to the pie (and make the pie visible in
the defined colors)
: Setup the ray of the pie
lib/Chart/Bars.pm view on Meta::CPAN
#
sub _draw_data {
my $self = shift;
my $data = $self->{'dataref'};
my $misccolor = $self->_color_role_to_index('misc');
my ( $x1, $x2, $x3, $y1, $y2, $y3 );
my ( $width, $height, $delta1, $delta2, $map, $mod, $cut, $pink );
my ( $i, $j, $color );
my $temp = 0;
my $font = $self->{'legend_font'};
my $fontW = $self->{'legend_font'}->width;
my $fontH = $self->{'legend_font'}->height;
my $textcolor = $self->_color_role_to_index('text');
# init the imagemap data field if they wanted it
if ( $self->true( $self->{'imagemap'} ) )
{
$self->{'imagemap_data'} = [];
}
# find the longest label
# first we need the length of the values
lib/Chart/Base.pm view on Meta::CPAN
# use a 10 pixel border around the whole png
$self->{'png_border'} = 10;
# leave some space around the text fields
$self->{'text_space'} = 2;
# and leave some more space around the chart itself
$self->{'graph_border'} = 10;
# leave a bit of space inside the legend box
$self->{'legend_space'} = 4;
# set some default fonts
$self->{'title_font'} = gdLargeFont,
$self->{'sub_title_font'} = gdLargeFont,
$self->{'legend_font'} = gdSmallFont,
$self->{'label_font'} = gdMediumBoldFont,
$self->{'tick_label_font'} = gdSmallFont;
# put the legend on the bottom of the chart
$self->{'legend'} = 'right';
# default to an empty list of labels
$self->{'legend_labels'} = [];
# use 20 pixel length example lines in the legend
$self->{'legend_example_size'} = 20;
# Set the maximum & minimum number of ticks to use.
$self->{'y_ticks'} = 6,
$self->{'min_y_ticks'} = 6,
$self->{'max_y_ticks'} = 100,
$self->{'x_number_ticks'} = 1,
$self->{'min_x_ticks'} = 6,
$self->{'max_x_ticks'} = 100;
# make the ticks 4 pixels long
lib/Chart/Base.pm view on Meta::CPAN
# default to "normal" x_tick drawing
$self->{'x_ticks'} = 'normal';
# we're not a component until Chart::Composite says we are
$self->{'component'} = 'false';
# don't force the y-axes in a Composite chare to be the same
$self->{'same_y_axes'} = 'false';
# plot rectangeles in the legend instead of lines in a composite chart
$self->{'legend_example_height'} = 'false';
# don't force integer y-ticks
$self->{'integer_ticks_only'} = 'false';
# don't forbid a false zero scale.
$self->{'include_zero'} = 'false';
# don't waste time/memory by storing imagemap info unless they ask
$self->{'imagemap'} = 'false';
lib/Chart/Base.pm view on Meta::CPAN
# default value for skip_y_ticks for the labels
$self->{skip_y_ticks} = 1;
# default value for skip_int_ticks only for integer_ticks_only
$self->{skip_int_ticks} = 1;
# default value for precision
$self->{precision} = 3;
# default value for legend label values in pie charts
$self->{legend_label_values} = 'value';
# default value for the labels in a pie chart
$self->{label_values} = 'percent';
# default position for the y-axes
$self->{y_axes} = 'left';
# copies of the current values at the x-ticks function
$self->{temp_x_min} = 0;
$self->{temp_x_max} = 0;
lib/Chart/Base.pm view on Meta::CPAN
# The number of angel axes in a direction Chart
$self->{'angle_interval'} = 30;
# dont use different 'x_axes' in a direction Chart
$self->{'pairs'} = 'false';
# polarplot for a direction Chart (not yet tested)
$self->{'polar'} = 'false';
# guiding lines in a Pie Chart
$self->{'legend_lines'} = 'false';
# Ring Chart instead of Pie
$self->{'ring'} = 1; # width of ring; i.e. normal pie
# stepline for Lines, LinesPoints
$self->{'stepline'} = 'false';
$self->{'stepline_mode'} = 'end'; # begin, end
# used function to transform x- and y-tick labels to strings
$self->{f_x_tick} = \&_default_f_tick, $self->{f_y_tick} = \&_default_f_tick, $self->{f_z_tick} = \&_default_f_tick;
lib/Chart/Base.pm view on Meta::CPAN
# have to leave this here for backwards compatibility
$self->_draw_sub_title() if $self->{'sub_title'};
# sort the data if they want to (mainly here to make sure
# pareto charts get sorted)
$self->_sort_data() if ( $self->true( $self->{'sort'} ) );
# start drawing the data (most methods in this will be
# overridden by the derived classes)
# include _draw_legend() in this to ensure that the legend
# will be flush with the chart
$self->_plot();
# and return
return 1;
}
## @fn private int _set_colors
# specify my colors
# @return status
lib/Chart/Base.pm view on Meta::CPAN
return ( $min, $max );
}
## @fn private int _plot()
# main sub that controls all the plotting of the actual chart
# @return status
sub _plot
{
my $self = shift;
# draw the legend first
$self->_draw_legend();
# mark off the graph_border space
$self->{'curr_x_min'} += $self->{'graph_border'};
$self->{'curr_x_max'} -= $self->{'graph_border'};
$self->{'curr_y_min'} += $self->{'graph_border'};
$self->{'curr_y_max'} -= $self->{'graph_border'};
# draw the x- and y-axis labels
$self->_draw_x_label if $self->{'x_label'};
$self->_draw_y_label('left') if $self->{'y_label'};
lib/Chart/Base.pm view on Meta::CPAN
$self->_draw_y_grid_lines if ( $self->true( $self->{'y_grid_lines'} ) );
$self->_draw_y2_grid_lines if ( $self->true( $self->{'y2_grid_lines'} ) );
# plot the data
$self->_draw_data();
# and return
return 1;
}
## @fn private int _draw_legend()
# let the user know what all the pretty colors mean.\n
# The user define the position of the legend by setting option
# 'legend' to 'top', 'bottom', 'left', 'right' or 'none'.
# The legend is positioned at the defined place, respectively.
# @return status
sub _draw_legend {
my $self = shift;
my $length;
# check to see if legend type is none..
if ( $self->{'legend'} =~ /^none$/ || length( $self->{'legend'} ) == 0 )
{
return 1;
}
# check to see if they have as many labels as datasets,
# warn them if not
if ( ( $#{ $self->{'legend_labels'} } >= 0 )
&& ( ( scalar( @{ $self->{'legend_labels'} } ) ) != $self->{'num_datasets'} ) )
{
carp "The number of legend labels and datasets doesn\'t match";
}
# init a field to store the length of the longest legend label
unless ( $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = 0;
}
# fill in the legend labels, find the longest one
for ( 1 .. $self->{'num_datasets'} )
{
unless ( $self->{'legend_labels'}[ $_ - 1 ] )
{
$self->{'legend_labels'}[ $_ - 1 ] = "Dataset $_";
}
$length = length( $self->{'legend_labels'}[ $_ - 1 ] );
if ( $length > $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = $length;
}
}
# different legend types
if ( $self->{'legend'} eq 'bottom' )
{
$self->_draw_bottom_legend;
}
elsif ( $self->{'legend'} eq 'right' )
{
$self->_draw_right_legend;
}
elsif ( $self->{'legend'} eq 'left' )
{
$self->_draw_left_legend;
}
elsif ( $self->{'legend'} eq 'top' )
{
$self->_draw_top_legend;
}
elsif ( $self->{'legend'} eq 'none' || length( $self->{'legend'} ) == 0 )
{
$self->_draw_none_legend;
}
else
{
carp "I can't put a legend there (at " . $self->{'legend'} . ")\n";
}
# and return
return 1;
}
## @fn private int _draw_bottom_legend()
# put the legend on the bottom of the chart
# @return status
sub _draw_bottom_legend {
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $y1, $x2, $x3, $y2 );
my ( $empty_width, $max_label_width, $cols, $rows, $color, $brush );
my ( $col_width, $row_height, $r, $c, $index, $x, $y, $w, $h, $axes_space );
my $font = $self->{'legend_font'};
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The font you specified isn\'t a GD Font object";
}
# get the size of the font
( $h, $w ) = ( $font->height, $font->width );
lib/Chart/Base.pm view on Meta::CPAN
{
$x1 += $self->{'label_font'}->height + 2 * $self->{'text_space'};
}
if ( $self->{'y_label2'} )
{
$x2 -= $self->{'label_font'}->height + 2 * $self->{'text_space'};
}
# figure out how wide the columns need to be, and how many we
# can fit in the space available
$empty_width = ( $x2 - $x1 ) - ( 2 * $self->{'legend_space'} );
$max_label_width = $self->{'max_legend_label'} * $w + ( 4 * $self->{'text_space'} ) + $self->{'legend_example_size'};
$cols = int( $empty_width / $max_label_width );
unless ($cols)
{
$cols = 1;
}
$col_width = $empty_width / $cols;
# figure out how many rows we need, remember how tall they are
$rows = int( $self->{'num_datasets'} / $cols );
unless ( ( $self->{'num_datasets'} % $cols ) == 0 )
{
$rows++;
}
unless ($rows)
{
$rows = 1;
}
$row_height = $h + $self->{'text_space'};
# box the legend off
$y1 = $self->{'curr_y_max'} - $self->{'text_space'} - ( $rows * $row_height ) - ( 2 * $self->{'legend_space'} );
$y2 = $self->{'curr_y_max'};
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $self->_color_role_to_index('misc') );
$x1 += $self->{'legend_space'} + $self->{'text_space'};
$x2 -= $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
$y2 -= $self->{'legend_space'} + $self->{'text_space'};
my $text_color = $self->_color_role_to_index( 'text' );
# draw in the actual legend
for $r ( 0 .. $rows - 1 )
{
for $c ( 0 .. $cols - 1 )
{
$index = ( $r * $cols ) + $c; # find the index in the label array
if ( $labels[$index] )
{
# get the color
$color = $self->_color_role_to_index( 'dataset' . $index );
# get the x-y coordinate for the start of the example line
$x = $x1 + ( $col_width * $c );
$y = $y1 + ( $row_height * $r ) + $h / 2;
# now draw the example line
$self->{'gd_obj'}->line( $x, $y, $x + $self->{'legend_example_size'}, $y, $color );
# reset the brush for points
$brush = $self->_prepare_brush( $color, 'point', 'dataset' . $index );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$x3 = int( $x + $self->{'legend_example_size'} / 2 );
$self->{'gd_obj'}->line( $x3, $y, $x3, $y, gdBrushed );
# adjust the x-y coordinates for the start of the label
$x += $self->{'legend_example_size'} + ( 2 * $self->{'text_space'} );
$y = $y1 + ( $row_height * $r );
# now draw the label
$self->{'gd_obj'}->string( $font, $x, $y, $labels[$index], $text_color );
}
}
}
# mark off the space used
$self->{'curr_y_max'} -= $rows * $row_height + 2 * $self->{'text_space'} + 2 * $self->{'legend_space'};
# now return
return 1;
}
## @fn private int _draw_right_legend()
# put the legend on the right of the chart
# @return status
sub _draw_right_legend {
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush );
my $font = $self->{'legend_font'};
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The subtitle font you specified isn\'t a GD Font object";
}
# get the size of the font
( $h, $w ) = ( $font->height, $font->width );
# get the miscellaneous color
$misccolor = $self->_color_role_to_index('misc');
# find out how wide the largest label is
$width =
( 2 * $self->{'text_space'} ) +
( $self->{'max_legend_label'} * $w ) +
$self->{'legend_example_size'} +
( 2 * $self->{'legend_space'} );
# get some starting x-y values
$x1 = $self->{'curr_x_max'} - $width;
$x2 = $self->{'curr_x_max'};
$y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
$y2 =
$self->{'curr_y_min'} +
$self->{'graph_border'} +
$self->{'text_space'} +
( $self->{'num_datasets'} * ( $h + $self->{'text_space'} ) ) +
( 2 * $self->{'legend_space'} );
# box the legend off
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );
# leave that nice space inside the legend box
$x1 += $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
# now draw the actual legend
for ( 0 .. $#labels )
{
# get the color
my $c = $self->{'num_datasets'} - $_ - 1;
# color of the datasets in the legend
$color = $self->_color_role_to_index( 'dataset' . $_ );
# find the x-y coords
$x2 = $x1;
$x3 = $x2 + $self->{'legend_example_size'};
$y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;
# do the line first
$self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );
# reset the brush for points
my $offset = 0;
( $brush, $offset ) = $self->_prepare_brush( $color, 'point', 'dataset' . $_ );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$self->{'gd_obj'}->line( int( ( $x3 + $x2 ) / 2 ), $y2, int( ( $x3 + $x2 ) / 2 ), $y2, gdBrushed );
# now the label
$x2 = $x3 + ( 2 * $self->{'text_space'} );
$y2 -= $h / 2;
# order of the datasets in the legend
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_], $color );
}
# mark off the used space
$self->{'curr_x_max'} -= $width;
# and return
return 1;
}
## @fn private int _draw_top_legend()
# put the legend on top of the chart
# @return status
sub _draw_top_legend {
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $y1, $x2, $x3, $y2, $empty_width, $max_label_width );
my ( $cols, $rows, $color, $brush );
my ( $col_width, $row_height, $r, $c, $index, $x, $y, $w, $h, $axes_space );
my $font = $self->{'legend_font'};
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The subtitle font you specified isn\'t a GD Font object";
}
# get the size of the font
( $h, $w ) = ( $font->height, $font->width );
lib/Chart/Base.pm view on Meta::CPAN
{
$x2 -= $axes_space;
}
elsif ( $self->{'y_axes'} =~ /^both$/i )
{
$x2 -= $axes_space;
$x1 += $axes_space;
}
# figure out how wide the columns can be, and how many will fit
$empty_width = ( $x2 - $x1 ) - ( 2 * $self->{'legend_space'} );
$max_label_width = ( 4 * $self->{'text_space'} ) + ( $self->{'max_legend_label'} * $w ) + $self->{'legend_example_size'};
$cols = int( $empty_width / $max_label_width );
unless ($cols)
{
$cols = 1;
}
$col_width = $empty_width / $cols;
# figure out how many rows we need and remember how tall they are
$rows = int( $self->{'num_datasets'} / $cols );
unless ( ( $self->{'num_datasets'} % $cols ) == 0 )
{
$rows++;
}
unless ($rows)
{
$rows = 1;
}
$row_height = $h + $self->{'text_space'};
# box the legend off
$y1 = $self->{'curr_y_min'};
$y2 = $self->{'curr_y_min'} + $self->{'text_space'} + ( $rows * $row_height ) + ( 2 * $self->{'legend_space'} );
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $self->_color_role_to_index('misc') );
# leave some space inside the legend
$x1 += $self->{'legend_space'} + $self->{'text_space'};
$x2 -= $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
$y2 -= $self->{'legend_space'} + $self->{'text_space'};
# draw in the actual legend
for $r ( 0 .. $rows - 1 )
{
for $c ( 0 .. $cols - 1 )
{
$index = ( $r * $cols ) + $c; # find the index in the label array
if ( $labels[$index] )
{
# get the color
$color = $self->_color_role_to_index( 'dataset' . $index );
# find the x-y coords
$x = $x1 + ( $col_width * $c );
$y = $y1 + ( $row_height * $r ) + $h / 2;
# draw the line first
$self->{'gd_obj'}->line( $x, $y, $x + $self->{'legend_example_size'}, $y, $color );
# reset the brush for points
$brush = $self->_prepare_brush( $color, 'point', 'dataset' . $index );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$x3 = int( $x + $self->{'legend_example_size'} / 2 );
$self->{'gd_obj'}->line( $x3, $y, $x3, $y, gdBrushed );
# now the label
$x += $self->{'legend_example_size'} + ( 2 * $self->{'text_space'} );
$y -= $h / 2;
$self->{'gd_obj'}->string( $font, $x, $y, $labels[$index], $color );
}
}
}
# mark off the space used
$self->{'curr_y_min'} += ( $rows * $row_height ) + $self->{'text_space'} + 2 * $self->{'legend_space'};
# now return
return 1;
}
## @fn private int _draw_left_legend()
# put the legend on the left of the chart
# @return status
sub _draw_left_legend
{
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush );
my $font = $self->{'legend_font'};
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The subtitle font you specified isn\'t a GD Font object";
}
# get the size of the font
( $h, $w ) = ( $font->height, $font->width );
# get the miscellaneous color
$misccolor = $self->_color_role_to_index('misc');
# find out how wide the largest label is
$width =
( 2 * $self->{'text_space'} ) +
( $self->{'max_legend_label'} * $w ) +
$self->{'legend_example_size'} +
( 2 * $self->{'legend_space'} );
# get some base x-y coordinates
$x1 = $self->{'curr_x_min'};
$x2 = $self->{'curr_x_min'} + $width;
$y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
$y2 =
$self->{'curr_y_min'} +
$self->{'graph_border'} +
$self->{'text_space'} +
( $self->{'num_datasets'} * ( $h + $self->{'text_space'} ) ) +
( 2 * $self->{'legend_space'} );
# box the legend off
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );
# leave that nice space inside the legend box
$x1 += $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
# now draw the actual legend
for ( 0 .. $#labels )
{
# get the color
my $c = $self->{'num_datasets'} - $_ - 1;
# color of the datasets in the legend
$color = $self->_color_role_to_index( 'dataset' . $_ );
# find the x-y coords
$x2 = $x1;
$x3 = $x2 + $self->{'legend_example_size'};
$y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;
# do the line first
$self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );
# reset the brush for points
$brush = $self->_prepare_brush( $color, 'point', 'dataset' . $_ );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$self->{'gd_obj'}->line( int( ( $x3 + $x2 ) / 2 ), $y2, int( ( $x3 + $x2 ) / 2 ), $y2, gdBrushed );
# now the label
$x2 = $x3 + ( 2 * $self->{'text_space'} );
$y2 -= $h / 2;
# order of the datasets in the legend
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_], $color );
}
# mark off the used space
$self->{'curr_x_min'} += $width;
# and return
return 1;
}
## @fn private int _draw_none_legend()
# no legend to draw..
# Just return in this case. This routine may be overwritten by
# subclasses.
# @return 1
sub _draw_none_legend {
my $self = shift;
my $status = 1;
return $status;
}
## @fn private int _draw_x_label()
# draw the label for the x-axis
#
# Get font for labels\n
lib/Chart/Composite.pm view on Meta::CPAN
}
# find out how big the y-tick labels will be from sub_0 and sub_1
$self->{'y_tick_label_length1'} = $self->{'sub_0'}->{'y_tick_label_length'};
$self->{'y_tick_label_length2'} = $self->{'sub_1'}->{'y_tick_label_length'};
# now return
return;
}
## @fn private int _draw_legend()
# let the user know what all the pretty colors mean
# @return status
#
sub _draw_legend
{
my $self = shift;
my ($length);
# check to see if they have as many labels as datasets,
# warn them if not
if ( ( $#{ $self->{'legend_labels'} } >= 0 )
&& ( ( scalar( @{ $self->{'legend_labels'} } ) ) != $self->{'num_datasets'} ) )
{
carp "The number of legend labels and datasets doesn\'t match";
}
# init a field to store the length of the longest legend label
unless ( $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = 0;
}
# fill in the legend labels, find the longest one
for ( 1 .. $self->{'num_datasets'} )
{
unless ( $self->{'legend_labels'}[ $_ - 1 ] )
{
$self->{'legend_labels'}[ $_ - 1 ] = "Dataset $_";
}
$length = length( $self->{'legend_labels'}[ $_ - 1 ] );
if ( $length > $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = $length;
}
}
# different legend types
if ( $self->{'legend'} eq 'bottom' )
{
$self->_draw_bottom_legend;
}
elsif ( $self->{'legend'} eq 'right' )
{
$self->_draw_right_legend;
}
elsif ( $self->{'legend'} eq 'left' )
{
$self->_draw_left_legend;
}
elsif ( $self->{'legend'} eq 'top' )
{
$self->_draw_top_legend;
}
elsif ( $self->{'legend'} eq 'none' )
{
$self->_draw_none_legend;
}
else
{
carp "I can't put a legend there\n";
}
# and return
return 1;
}
## @fn private int _draw_top_legend()
# put the legend on the top of the data plot
#
# Overwrite the base class _draw_top_legend
#
# @return status
sub _draw_top_legend
{
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $y1, $x2, $y2, $empty_width, $max_label_width );
my ( $cols, $rows, $color );
my ( $col_width, $row_height, $i, $j, $r, $c, $index, $x, $y, $sub, $w, $h );
my ( $yh, $yi ); # for boxing legends
my $font = $self->{'legend_font'};
my ( %colors, @datasets );
my $max_legend_example = 0;
$yh = 0;
# copy the current boundaries into the sub-objects
$self->_sub_update;
# init the legend_example_height
$self->_legend_example_height_init;
## Make datasetI numbers match indexes of @{ $self->{'dataref'} }[1.....].
# # modify the dataset color table entries to avoid duplicating
# # dataset colors (this limits the number of possible data sets
# # for each component to 8)
# for (0..7) {
# $self->{'sub_1'}{'color_table'}{'dataset'.$_}
# = $self->{'color_table'}{'dataset'.($_+8)};
# }
# modify the dataset color table entries to avoid duplicating
# dataset colors.
my ( $n0, $n1 ) = map { scalar @{ $self->{'composite_info'}[$_][1] } } 0 .. 1;
for ( 0 .. $n1 - 1 )
{
$self->{'sub_1'}{'color_table'}{ 'dataset' . $_ } = $self->{'color_table'}{ 'dataset' . ( $_ + $n0 ) };
}
# make sure we use the right colors for the legend
@datasets = @{ $self->{'composite_info'}[0][1] };
$i = 0;
for ( 0 .. $#datasets )
{
$colors{ $datasets[$_] - 1 } = $self->{'color_table'}{ 'dataset' . ($i) };
$i++;
}
@datasets = @{ $self->{'composite_info'}[1][1] };
$i = 0;
for ( 0 .. $#datasets )
lib/Chart/Composite.pm view on Meta::CPAN
{
$x1 += $self->{'label_font'}->height + 2 * $self->{'text_space'};
}
if ( $self->{'y_label2'} )
{
$x2 -= $self->{'label_font'}->height + 2 * $self->{'text_space'};
}
# figure out how wide the widest label is, then figure out how many
# columns we can fit into the allotted space
$empty_width = $x2 - $x1 - ( 2 * $self->{'legend_space'} );
$max_label_width =
$self->{'max_legend_label'} * $self->{'legend_font'}->width + 4 * $self->{'text_space'} + $self->{'legend_example_size'};
$cols = int( $empty_width / $max_label_width );
unless ($cols)
{
$cols = 1;
}
$col_width = $empty_width / $cols;
# figure out how many rows we need and how tall they are
$rows = int( $self->{'num_datasets'} / $cols );
unless ( ( $self->{'num_datasets'} % $cols ) == 0 )
{
$rows++;
}
unless ($rows)
{
$rows = 1;
}
$row_height = $h + $self->{'text_space'};
# box the legend off
$y1 = $self->{'curr_y_min'};
$y2 = $self->{'curr_y_min'} + $self->{'text_space'} + ( $rows * $row_height ) + ( 2 * $self->{'legend_space'} );
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $self->_color_role_to_index('misc') );
$max_legend_example = $y2 - $y1;
# leave some space inside the legend
$x1 += $self->{'legend_space'} + $self->{'text_space'};
$x2 -= $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
$y2 -= $self->{'legend_space'} + $self->{'text_space'};
# draw in the actual legend
$r = 0; # current row
$c = 0; # current column
$yi = 0; # current dataset
for $i ( 0 .. 1 )
{
for $j ( 0 .. $#{ $self->{'component_datasets'}[$i] } )
{
# get the color
$color = $self->{ 'sub_' . $i }->{'color_table'}{ 'dataset' . $j };
$index = $self->{'component_datasets'}[$i][$j] - 1; # index in label list
# find the x-y coordinates for the beginning of the example line
$x = $x1 + ( $col_width * $c );
$y = $y1 + ( $row_height * $r ) + $h / 2;
# draw the example line if legend_example_height==1 or ==0
if ( $rows == 1 )
{
if ( $self->{ 'legend_example_height' . $yi } < $max_legend_example )
{
$yh = $self->{ 'legend_example_height' . $yi };
}
else
{
$yh = $max_legend_example;
}
}
else
{
if ( $self->{ 'legend_example_height' . $yi } < $row_height )
{
$yh = $self->{ 'legend_example_height' . $yi };
}
else
{
$yh = $row_height;
}
}
$yi++;
if ( $yh <= 1 )
{
$self->{'gd_obj'}->line( $x, $y, $x + $self->{'legend_example_size'}, $y, $color );
}
else
{
# draw the example bar if legend_example_height > 1
$yh = int( $yh / 2 );
$self->{'gd_obj'}->filledRectangle( $x, $y - $yh, $x + $self->{'legend_example_size'}, $y + $yh, $color );
}
# find the x-y coordinates for the beginning of the label
$x += $self->{'legend_example_size'} + 2 * $self->{'text_space'};
$y -= $h / 2;
# now draw the label
$self->{'gd_obj'}->string( $font, $x, $y, $labels[$index], $color );
# keep track of which row/column we're using
$r = ( $r + 1 ) % $rows;
if ( $r == 0 )
{
$c++;
}
}
}
# mark of the space used
$self->{'curr_y_min'} += $rows * $row_height + $self->{'text_space'} + 2 * $self->{'legend_space'};
return;
}
## @fn private int _draw_right_legend()
# put the legend on the right of the chart
#
# Overwrite the base class _draw_right_legend
#
# @return status
sub _draw_right_legend
{
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h );
my ($yh) = 0; # for boxing legend
my $font = $self->{'legend_font'};
my ( %colors, @datasets, $i );
my $max_legend_example = 0;
# copy the current boundaries and colors into the sub-objects
$self->_sub_update;
# init the legend exapmle height
$self->_legend_example_height_init;
# # modify the dataset color table entries to avoid duplicating
# # dataset colors (this limits the number of possible data sets
# # for each component to 8)
# for (0..7) {
# $self->{'sub_1'}{'color_table'}{'dataset'.$_}
# = $self->{'color_table'}{'dataset'.($_+8)};
# }
# modify the dataset color table entries to avoid duplicating
# dataset colors.
my ( $n0, $n1 ) = map { scalar @{ $self->{'composite_info'}[$_][1] } } 0 .. 1;
for ( 0 .. $n1 - 1 )
{
$self->{'sub_1'}{'color_table'}{ 'dataset' . $_ } = $self->{'color_table'}{ 'dataset' . ( $_ + $n0 ) };
}
# make sure we use the right colors for the legend
@datasets = @{ $self->{'composite_info'}[0][1] };
$i = 0;
for ( 0 .. $#datasets )
{
$colors{ $datasets[$_] - 1 } = $self->{'color_table'}{ 'dataset' . ($_) };
$i++;
}
@datasets = @{ $self->{'composite_info'}[1][1] };
$i = 0;
lib/Chart/Composite.pm view on Meta::CPAN
# get the size of the font
( $h, $w ) = ( $font->height, $font->width );
# get the miscellaneous color
$misccolor = $self->_color_role_to_index('misc');
# find out how wide the largest label is
$width =
( 2 * $self->{'text_space'} ) +
( $self->{'max_legend_label'} * $w ) +
$self->{'legend_example_size'} +
( 2 * $self->{'legend_space'} );
# box the thing off
$x1 = $self->{'curr_x_max'} - $width;
$x2 = $self->{'curr_x_max'};
$y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
$y2 =
$self->{'curr_y_min'} +
$self->{'graph_border'} +
$self->{'text_space'} +
( $self->{'num_datasets'} * ( $h + $self->{'text_space'} ) ) +
( 2 * $self->{'legend_space'} );
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );
# leave that nice space inside the legend box
$x1 += $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
# now draw the actual legend
for ( 0 .. $#labels )
{
# get the color
$color = $colors{$_};
# find the max_legend_example
$max_legend_example = $self->{'legend_space'} + $h;
# find the x-y coords
$x2 = $x1;
$x3 = $x2 + $self->{'legend_example_size'};
$y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;
# draw the example line if legend_example_height==1 or ==0
if ( $self->{ 'legend_example_height' . $_ } < $max_legend_example )
{
$yh = $self->{ 'legend_example_height' . $_ };
}
else
{
$yh = $max_legend_example;
}
if ( $yh <= 1 )
{
$self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );
}
else
{
$yh = int( $yh / 2 );
$self->{'gd_obj'}->filledRectangle( $x2, $y2 - $yh, $x3, $y2 + $yh, $color );
}
lib/Chart/Composite.pm view on Meta::CPAN
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_], $color );
}
# mark off the used space
$self->{'curr_x_max'} -= $width;
# and return
return;
}
## @fn private int _draw_left_legend()
# draw the legend at the left of the data plot
#
# Overwrite the base class _draw_left_legend
#
# @return status
sub _draw_left_legend
{
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h );
my $yh; # for boxing legend
my $font = $self->{'legend_font'};
my ( %colors, @datasets, $i );
my $max_legend_example = 0;
# copy the current boundaries and colors into the sub-objects
$self->_sub_update;
# init the legend_example height
$self->_legend_example_height_init;
# # modify the dataset color table entries to avoid duplicating
# # dataset colors (this limits the number of possible data sets
# # for each component to 8)
# for (0..7) {
# $self->{'sub_1'}{'color_table'}{'dataset'.$_}
# = $self->{'color_table'}{'dataset'.($_+8)};
# }
# modify the dataset color table entries to avoid duplicating
# dataset colors.
my ( $n0, $n1 ) = map { scalar @{ $self->{'composite_info'}[$_][1] } } 0 .. 1;
for ( 0 .. $n1 - 1 )
{
$self->{'sub_1'}{'color_table'}{ 'dataset' . $_ } = $self->{'color_table'}{ 'dataset' . ( $_ + $n0 ) };
}
# make sure we use the right colors for the legend
@datasets = @{ $self->{'composite_info'}[0][1] };
$i = 0;
for ( 0 .. $#datasets )
{
$colors{ $datasets[$_] - 1 } = $self->{'color_table'}{ 'dataset' . ($i) };
$i++;
}
@datasets = @{ $self->{'composite_info'}[1][1] };
$i = 0;
for ( 0 .. $#datasets )
lib/Chart/Composite.pm view on Meta::CPAN
# get the size of the font
( $h, $w ) = ( $font->height, $font->width );
# get the miscellaneous color
$misccolor = $self->_color_role_to_index('misc');
# find out how wide the largest label is
$width =
( 2 * $self->{'text_space'} ) +
( $self->{'max_legend_label'} * $w ) +
$self->{'legend_example_size'} +
( 2 * $self->{'legend_space'} );
# get some base x-y coordinates
$x1 = $self->{'curr_x_min'};
$x2 = $self->{'curr_x_min'} + $width;
$y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
$y2 =
$self->{'curr_y_min'} +
$self->{'graph_border'} +
$self->{'text_space'} +
( $self->{'num_datasets'} * ( $h + $self->{'text_space'} ) ) +
( 2 * $self->{'legend_space'} );
# box the legend off
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );
# leave that nice space inside the legend box
$x1 += $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
# now draw the actual legend
for ( 0 .. $#labels )
{
# get the color
$color = $colors{$_};
# find the max_legend_example
$max_legend_example = $self->{'legend_space'} + $h;
# find the x-y coords
$x2 = $x1;
$x3 = $x2 + $self->{'legend_example_size'};
$y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;
# draw the example line if legend_example_height==1 or ==0
if ( $self->{ 'legend_example_height' . $_ } < $max_legend_example )
{
$yh = $self->{ 'legend_example_height' . $_ };
}
else
{
$yh = $max_legend_example;
}
if ( $yh <= 1 )
{
$self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );
}
else
{
# draw the example bar if legend_example_height > 1
$yh = int( $yh / 2 );
$self->{'gd_obj'}->filledRectangle( $x2, $y2 - $yh, $x3, $y2 + $yh, $color );
}
# now the label
$x2 = $x3 + ( 2 * $self->{'text_space'} );
$y2 -= $h / 2;
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_], $color );
}
# mark off the used space
$self->{'curr_x_min'} += $width;
# and return
return 1;
}
## @fn private int _draw_bottom_legend()
# put the legend on the bottom of the chart
#
# Overwrite the base class _draw_bottom_legend
#
# @return status
sub _draw_bottom_legend
{
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $y1, $x2, $y2, $empty_width, $max_label_width, $cols, $rows, $color );
my ( $col_width, $row_height, $i, $j, $r, $c, $index, $x, $y, $sub, $w, $h );
my ( $yh, $yi ); # for boxing legend
my $font = $self->{'legend_font'};
my ( %colors, @datasets );
my $max_legend_example = 0;
$yh = 0;
# copy the current boundaries and colors into the sub-objects
$self->_sub_update;
# init the legend example height
$self->_legend_example_height_init;
# # modify the dataset color table entries to avoid duplicating
# # dataset colors (this limits the number of possible data sets
# # for each component to 8)
# for (0..7) {
# $self->{'sub_1'}{'color_table'}{'dataset'.$_}
# = $self->{'color_table'}{'dataset'.($_+8)};
# }
# modify the dataset color table entries to avoid duplicating
# dataset colors.
lib/Chart/Composite.pm view on Meta::CPAN
$self->{'tick_len'} -
( 3 * $self->{'text_space'} );
if ( $self->{'y_label'} )
{
$x1 += $self->{'label_font'}->height + 2 * $self->{'text_space'};
}
if ( $self->{'y_label2'} )
{
$x2 -= $self->{'label_font'}->height + 2 * $self->{'text_space'};
}
$empty_width = $x2 - $x1 - ( 2 * $self->{'legend_space'} );
$max_label_width =
$self->{'max_legend_label'} * $self->{'legend_font'}->width + 4 * $self->{'text_space'} + $self->{'legend_example_size'};
$cols = int( $empty_width / $max_label_width );
unless ($cols)
{
$cols = 1;
}
$col_width = $empty_width / $cols;
# figure out how many rows we need
$rows = int( $self->{'num_datasets'} / $cols );
unless ( ( $self->{'num_datasets'} % $cols ) == 0 )
{
$rows++;
}
unless ($rows)
{
$rows = 1;
}
$row_height = $h + $self->{'text_space'};
# box it off
$y1 = $self->{'curr_y_max'} - $self->{'text_space'} - ( $rows * $row_height ) - ( 2 * $self->{'legend_space'} );
$y2 = $self->{'curr_y_max'};
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $self->_color_role_to_index('misc') );
# get the max_legend_example_height
$max_legend_example = $y2 - $y1;
$x1 += $self->{'legend_space'} + $self->{'text_space'};
$x2 -= $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
$y2 -= $self->{'legend_space'} + $self->{'text_space'};
# draw in the actual legend
$r = 0;
$c = 0;
$yi = 0; # current dataset
for $i ( 0 .. 1 )
{
for $j ( 0 .. $#{ $self->{'component_datasets'}[$i] } )
{
$color = $self->{ 'sub_' . $i }->{'color_table'}{ 'dataset' . $j };
$index = $self->{'component_datasets'}[$i][$j] - 1;
$x = $x1 + ( $col_width * $c );
$y = $y1 + ( $row_height * $r ) + $h / 2;
# draw the example line if legend_example_height==1 or ==0
if ( $rows == 1 )
{
if ( $self->{ 'legend_example_height' . $yi } < $max_legend_example )
{
$yh = $self->{ 'legend_example_height' . $yi };
}
else
{
$yh = $max_legend_example;
}
}
else
{
if ( $self->{ 'legend_example_height' . $yi } < $row_height )
{
$yh = $self->{ 'legend_example_height' . $yi };
}
else
{
$yh = $row_height;
}
}
$yi++;
if ( $yh <= 1 )
{
$self->{'gd_obj'}->line( $x, $y, $x + $self->{'legend_example_size'}, $y, $color );
}
else
{
# draw the example bar if legend_example_height > 1
$yh = int( $yh / 2 );
$self->{'gd_obj'}->filledRectangle( $x, $y - $yh, $x + $self->{'legend_example_size'}, $y + $yh, $color );
}
$x += $self->{'legend_example_size'} + 2 * $self->{'text_space'};
$y -= $h / 2;
$self->{'gd_obj'}->string( $font, $x, $y, $labels[$index], $color );
# keep track of which row/column we're using
$r = ( $r + 1 ) % $rows;
if ( $r == 0 )
{
$c++;
}
}
}
# mark of the space used
$self->{'curr_y_max'} -= ( $rows * $row_height ) + 2 * $self->{'text_space'} + 2 * $self->{'legend_space'};
return;
}
## @fn private int _draw_none_legend()
# no legend to draw.. just update the color tables for subs
#
# This routine overwrites this function of the Base class
#
# @return status
sub _draw_none_legend
{
my $self = shift;
my $status = 1;
$self->_sub_update();
# for (0..7) {
# $self->{'sub_1'}{'color_table'}{'dataset'.$_}
# = $self->{'color_table'}{'dataset'.($_+8)};
# }
lib/Chart/Composite.pm view on Meta::CPAN
# draw grid_lines for y
#
# Overwrites this function of Base
sub _draw_y2_grid_lines
{
my ($self) = shift;
$self->{'sub_1'}->_draw_y2_grid_lines();
return;
}
## @fn private _legend_example_height_values
# init the legend_example_height_values
#
sub _legend_example_height_init
{
my $self = shift;
my $a = $self->{'num_datasets'};
my ( $b, $e ) = ( 0, 0 );
my $bis = '..';
if ( $self->false( $self->{'legend_example_height'} ) )
{
for my $i ( 0 .. $a )
{
$self->{ 'legend_example_height' . $i } = 1;
}
}
if ( $self->true( $self->{'legend_example_height'} ) )
{
for my $i ( 0 .. $a )
{
if ( defined( $self->{ 'legend_example_height' . $i } ) ) { }
else
{
( $self->{ 'legend_example_height' . $i } ) = 1;
}
}
for $b ( 0 .. $a )
{
for $e ( 0 .. $a )
{
my $anh = sprintf( $b . $bis . $e );
if ( defined( $self->{ 'legend_example_height' . $anh } ) )
{
if ( $b > $e )
{
croak "Please reverse the datasetnumber in legend_example_height\n";
}
for ( my $n = $b ; $n <= $e ; $n++ )
{
$self->{ 'legend_example_height' . $n } = $self->{ 'legend_example_height' . $anh };
}
}
}
}
}
}
## be a good module and return 1
1;
lib/Chart/Direction.pm view on Meta::CPAN
my $misccolor = $self->_color_role_to_index('misc');
my $textcolor = $self->_color_role_to_index('text');
my $background = $self->_color_role_to_index('background');
my @labels = @{ $self->{'y_tick_labels'} };
my ( $width, $height, $centerX, $centerY, $diameter );
my ( $pi, $font, $fontW, $fontH, $labelX, $labelY, $label_offset );
my ( $dia_delta, $dia, $x, $y, @label_degrees, $arc, $angle_interval );
# set up initial constant values
$pi = 3.14159265358979323846,
$font = $self->{'legend_font'},
$fontW = $self->{'legend_font'}->width,
$fontH = $self->{'legend_font'}->height,
$angle_interval = $self->{'angle_interval'};
if ( $self->true( $self->{'grey_background'} ) )
{
$background = $self->_color_role_to_index('grey_background');
}
# init the imagemap data field if they wanted it
if ( $self->true( $self->{'imagemap'} ) )
{
lib/Chart/Direction.pm view on Meta::CPAN
# draw the circle
$brush->arc( $radius - 1, $radius - 1, $radius, $radius, 0, 360, $newcolor );
# fill it if we're using lines
$brush->fill( $radius - 1, $radius - 1, $newcolor );
# set the new image as the main object's brush
return $brush;
}
## @fn private int _draw_legend()
# let them know what all the pretty colors mean
# @return status
#
# Overwrite corresponding function of Base
#
sub _draw_legend
{
my $self = shift;
my $length;
# check to see if legend type is none..
if ( $self->{'legend'} =~ /^none$/ )
{
return 1;
}
# check to see if they have as many labels as datasets,
# warn them if not
if ( ( $#{ $self->{'legend_labels'} } >= 0 )
&& ( ( scalar( @{ $self->{'legend_labels'} } ) ) != $self->{'num_datasets'} ) )
{
carp "The number of legend labels and datasets doesn\'t match";
}
# init a field to store the length of the longest legend label
unless ( $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = 0;
}
# fill in the legend labels, find the longest one
if ( $self->false( $self->{'pairs'} ) )
{
for ( 1 .. $self->{'num_datasets'} )
{
unless ( $self->{'legend_labels'}[ $_ - 1 ] )
{
$self->{'legend_labels'}[ $_ - 1 ] = "Dataset $_";
}
$length = length( $self->{'legend_labels'}[ $_ - 1 ] );
if ( $length > $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = $length;
}
} #end for
}
if ( $self->true( $self->{'pairs'} ) )
{
for ( 1 .. ceil( $self->{'num_datasets'} / 2 ) )
{
unless ( $self->{'legend_labels'}[ $_ - 1 ] )
{
$self->{'legend_labels'}[ $_ - 1 ] = "Dataset $_";
}
$length = length( $self->{'legend_labels'}[ $_ - 1 ] );
if ( $length > $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = $length;
}
}
}
# different legend types
if ( $self->{'legend'} eq 'bottom' )
{
$self->_draw_bottom_legend;
}
elsif ( $self->{'legend'} eq 'right' )
{
$self->_draw_right_legend;
}
elsif ( $self->{'legend'} eq 'left' )
{
$self->_draw_left_legend;
}
elsif ( $self->{'legend'} eq 'top' )
{
$self->_draw_top_legend;
}
else
{
carp "I can't put a legend there (at " . $self->{'legend'} . ")\n";
}
# and return
return 1;
}
## @fn private array _find_y_range()
# Find minimum and maximum value of y data sets.
#
# @return ( min, max, flag_all_integers )
lib/Chart/ErrorBars.pm view on Meta::CPAN
# draw the circle
$brush->arc( $radius - 1, $radius - 1, $radius, $radius, 0, 360, $newcolor );
# fill it if we're using lines
$brush->fill( $radius - 1, $radius - 1, $newcolor );
# set the new image as the main object's brush
return $brush;
}
## @fn private int _draw_legend()
# let them know what all the pretty colors mean
# @return status
## let them know what all the pretty colors mean
sub _draw_legend
{
my $self = shift;
my ( $length, $step, $temp, $post_length );
my $j = 0;
# check to see if legend type is none..
if ( $self->{'legend'} =~ /^none$/ )
{
return 1;
}
#just for later checking and warning
if ( $#{ $self->{'legend_labels'} } >= 0 )
{
$post_length = scalar( @{ $self->{'legend_labels'} } );
}
#look if every second or eyery third dataset is a set for data
if ( $self->false( $self->{'same_error'} ) )
{
$step = 3;
}
else
{
$step = 2;
}
# init a field to store the length of the longest legend label
unless ( $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = 0;
}
# fill in the legend labels, find the longest one
for ( my $i = 1 ; $i < $self->{'num_datasets'} ; $i += $step )
{
my $label = $j + 1;
unless ( $self->{'legend_labels'}[$j] )
{
$self->{'legend_labels'}[$j] = "Dataset $label";
}
$length = length( $self->{'legend_labels'}[$j] );
if ( $length > $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = $length;
}
$j++;
}
#we just have to label the datasets in the legend
#we'll reset it, to draw the sets
$temp = $self->{'num_datasets'};
$self->{'num_datasets'} = $j;
# check to see if they have as many labels as datasets,
# warn them if not
if ( ( $post_length > 0 ) && ( $post_length != $j ) )
{
carp "The number of legend labels and datasets doesn\'t match";
}
# different legend types
if ( $self->{'legend'} eq 'bottom' )
{
$self->_draw_bottom_legend;
}
elsif ( $self->{'legend'} eq 'right' )
{
$self->_draw_right_legend;
}
elsif ( $self->{'legend'} eq 'left' )
{
$self->_draw_left_legend;
}
elsif ( $self->{'legend'} eq 'top' )
{
$self->_draw_top_legend;
}
else
{
carp "I can't put a legend there (at " . $self->{'legend'} . ")\n";
}
#reset the number of dataset to make sure that everything goes right
$self->{'num_datasets'} = $temp;
# and return
return 1;
}
#find the range of the x scale, don't forget the errors!
lib/Chart/Lines.pm view on Meta::CPAN
{
$self->_draw_title;
}
#draw the sub title again
if ( $self->{'sub_title'} )
{
$self->_draw_sub_title;
}
#draw the top legend again
if ( $self->{'legend'} =~ /^top$/i )
{
$self->_draw_top_legend;
}
#reset the actual values
$self->{'curr_x_min'} = $t_x_min;
$self->{'curr_x_max'} = $t_x_max;
$self->{'curr_y_min'} = $t_y_min;
$self->{'curr_y_max'} = $t_y_max;
}
if ($repair_bottom_flag)
lib/Chart/Lines.pm view on Meta::CPAN
#get back to the point, where everything began
$self->{'curr_x_min'} = 0;
$self->{'curr_y_min'} = 0;
$self->{'curr_x_max'} = $abs_x_max;
$self->{'curr_y_max'} = $abs_y_max - 1;
# mark off the graph_border space
$self->{'curr_y_max'} -= 2 * $self->{'graph_border'};
#draw the bottom legend again
if ( $self->{'legend'} =~ /^bottom$/i )
{
$self->_draw_bottom_legend;
}
#draw the x label again
if ( $self->{'x_label'} )
{
$self->_draw_x_label;
}
#get back to the start point for the ticks
$self->{'curr_x_min'} = $self->{'temp_x_min'};
lib/Chart/LinesPoints.pm view on Meta::CPAN
{
$self->_draw_title;
}
#draw the sub title again
if ( $self->{'sub_title'} )
{
$self->_draw_sub_title;
}
#draw the top legend again
if ( $self->{'legend'} =~ /^top$/i )
{
$self->_draw_top_legend;
}
#reset the actual values
$self->{'curr_x_min'} = $t_x_min;
$self->{'curr_x_max'} = $t_x_max;
$self->{'curr_y_min'} = $t_y_min;
$self->{'curr_y_max'} = $t_y_max;
}
if ($repair_bottom_flag)
lib/Chart/LinesPoints.pm view on Meta::CPAN
#get back to the point, where everything began
$self->{'curr_x_min'} = 0;
$self->{'curr_y_min'} = 0;
$self->{'curr_x_max'} = $abs_x_max;
$self->{'curr_y_max'} = $abs_y_max - 1;
# mark off the graph_border space
$self->{'curr_y_max'} -= 2 * $self->{'graph_border'};
#draw the bottom legend again
if ( $self->{'legend'} =~ /^bottom$/i )
{
$self->_draw_bottom_legend;
}
#draw the x label again
if ( $self->{'x_label'} )
{
$self->_draw_x_label;
}
#get back to the start point for the ticks
$self->{'curr_x_min'} = $self->{'temp_x_min'};
lib/Chart/Manual/Properties.pod view on Meta::CPAN
=head2 integer
Whole numbers (without decimals) to set position, size and alike.
=head2 positive integer
Integers greater or equal zero.
=head2 string
Short texts for title, sub_title and labels on axis, tics and legend.
Line breaks (C</n>) are only acceptable inside single quotes and in the
L</title>.
=head1 BY CHART TYPE
Summary of all properties, grouped by chart type where there applicable.
Sections are named after the Chart type in question, except B<All> and B<NoPie>.
The format is: name ... L<type|/"DATA TYPES">, description; C<default value>.
lib/Chart/Manual/Properties.pod view on Meta::CPAN
L<colors-y_label|/colors> ...... L</color> of y-axis (left side) label text; C<'black'>
L<colors-y_label2|/colors> .... L</color> of y-axis (right side) label text; C<'black'>
L<colors-misc|/colors> ....... L</color> of boxes, ticks, axis and alike; C<'black'>
L</f_x_tick> ................ L</code> that transforms "would have" into actual tick label on left x-axis; C<undef>
L</f_y_tick> ............... L</code> that transforms "would have" into actual tick label on right y-axis; C<undef>
L</graph_border> .......... space between graph and title + legend in pixel; C<10>
L</grey_background> ...... L<bool|/boolean>: sets plot background to grey; C<'true'>
L</imagemap> ............ L<bool|/boolean>: enable imagemap_dump(); C<'false'>
L</label_font> .......... L</font> of axis labels; GD::Font->MediumBold
L</legend> .............. qw[left right top bottom none]: placement of the legend; C<'right'>
L</legend_font> ......... L</font> of the text in the legend; GD::Font->Small.
L</legend_labels> ....... (array ref): labels of colors in legend; C<undef>
L</png_border> .......... L<pos_int|/"positive integer">: space between graph parts and image edge in pixel; C<10>
L</sub_title> ........... L</string>: text below the L</title> in smaller letters; C<''>
L</text_space> .......... L<pos_int|/"positive integer">: extra space around any text; C<2>
L</title> ............... L</string>: text on top of a chart; C<''>
L</title_font> .......... L</font> of the title text; GD::Font->Large
lib/Chart/Manual/Properties.pod view on Meta::CPAN
L</brush_style1> ....... brush style of points associated with left y-axis; C<undef>
L</brush_style2> ....... brush style of points associated with right y-axis; C<undef>
L</composite_info> ..... (array of arrays) which data sets produce which chart types; C<undef>
L</f_y_tick1> .......... L</code> that transforms "would have" into actual label on left y-axis; C<undef>
L</f_y_tick2> .......... L</code> that transforms "would have" into actual label on right y-axis; C<undef>
L</legend_example_size> Length of the color example line in legend in pixel; C<20>
L</max_val1> ........... L</code> maximum y value on the left axis; C<undef>
L</max_val2> ........... L</code> maximum y value on the right axis; C<undef>
L</min_val1> ........... L</code> minimum y value on the left axis; C<undef>
L</min_val2> ........... L</code> minimum y value on the right axis; C<undef>
L</same_y_axes> ........ L</code> both y-axis have same min and max; C<undef>
lib/Chart/Manual/Properties.pod view on Meta::CPAN
L</brushStyle> ......... shape of the points; C<'FilledCircle'>
L</pt_size> ............ L<pos_int|/"positive integer">: radius of points in pixels; C<18>
=head2 Pie
L</label_values> ....... qw[percent value both none]: label content on pie slice label; C<'percent'>
L</legend_label_values> qw[percent value both none]: label content in the legend; C<'value'>
L</legend_lines> ....... L<bool|/boolean>: draw lines connecting pie slices and label; C<'false'>
L</ring> ............... L</real>: percentage of visible radius; C<1> (full pie)
=head2 Split
L</interval> ........... L<pos_int|/"positive integer">: interval of a plot segment; C<'undef'>
L</interval_ticks> ..... L<pos_int|/"positive integer">: number of ticks on x-axis; C<5>
lib/Chart/Manual/Properties.pod view on Meta::CPAN
'title' (color of the title)
'text' (all the text in the chart)
'x_label' (color of the x-axis label)
'y_label' (color of the first y axis label)
'y_label2' (color of the second y axis label)
'grid_lines' (color of the grid lines)
'x_grid_lines' (color of the x grid lines - for x axis ticks)
'y_grid_lines' (color of the y grid lines - for to left y axis ticks)
'y2_grid_lines' (color of the y2 grid lines - for right y axis ticks)
'dataset0'..'dataset63' (the different datasets)
'misc' (everything else, ie. axis, ticks, box around the legend)
NB. For composite charts, there is a limit of 8 datasets per component.
The colors for 'dataset8' through 'dataset15' become the colors
for 'dataset0' through 'dataset7' for the second component chart.
=head2 composite_info
L</Composite> only: information about which data set gets visualized by
which chart type. It should be a reference to an array of array references,
containing information like the following:
lib/Chart/Manual/Properties.pod view on Meta::CPAN
This option changes the L</font> of the axis labels.
Default is GD::Font->MediumBold.
=head2 label_values
L</Pie> only: What kind of value labels to show alongside the pie.
Valid values are C<'percent'>, C<'value'>, C<'both'> and C<'none'>.
Defaults to C<'percent'>.
=head2 legend
Specifies the placement of the legend. Valid values are C<'left'>,
C<'right'>, C<'top'>, C<'bottom'>. Setting this to C<'none'> tells chart
not to draw a legend. Default is C<'right'>.
=head2 legend_example_size
L</Composite> only: Length of the example line in the legend in pixels.
Defaults to C<20>.
=head2 legend_font
This option changes the L</font> of the text in the legend.
Default is GD::Font->Small.
=head2 legend_labels
Array reference containing texts, which are the labels assigned to each
color in the legend. Amount has to correspond to the amount of data sets.
@labels = ('foo', 'bar');
$obj->set ('legend_labels' => \@labels);
Default is empty, in which case C<'Dataset 1'>, C<'Dataset 2'>, etc. are
used as the labels.
=head2 legend_label_values
L</Pie> only: What labels to draw in the legend. Valid values are
c<'percent'>, C<'value'>, C<'both'> and C<'none'>. Defaults to C<'value'>.
=head2 legend_lines
L</Pie> only: L<bool|/boolean> to decide if lines connecting pie slices
and label are drawn. Default is C<'false'>.
=head2 label_values
L</Pie> only: Labels to draw beside the pie slices. Valid values are
C<'percent'>, C<'value'>, C<'both'> and C<'none'>. Defaults to C<'percent'>.
=head2 line
lib/Chart/Manual/Properties.pod view on Meta::CPAN
zero. Default is C<'undef'>.
=head2 sub_title
Write a sub-title under the L</title> in smaller letters.
Default is empty.
=head2 text_space
Sets the amount of space left on the sides (lext and right) of text,
(title, legend, label) to make it more readable. Defaults to C<2>.
=head2 tick_label_font
This is the font for the tick labels. It also needs
a GD font object as an argument. Default is GD::Font->Small.
=head2 tick_len
Sets the length of the x- and y-ticks in pixels. Default is C<4>.
lib/Chart/Manual/Types.pod view on Meta::CPAN
$g->add_dataset( 300, 310, 290, 305, 315, 290 );
$g->add_dataset( 30, 40, 20, 35, 45, 20 );
$g->set(
title => 'Direction Demo',
angle_interval => 45,
precision => 0,
arrow => 'true',
point => 'false',
include_zero => 'true',
legend => 'none',
grey_background => 'false',
pairs => 'true',
);
$g->png("direction.png");
=head2 ErrorBars
=for HTML <p>
<img src="https://raw.githubusercontent.com/lichtkind/Chart/main/dev/example/manual/error.png" alt="error bar chart">
lib/Chart/Manual/Types.pod view on Meta::CPAN
The class Chart::ErrorBars creates a point chart with error bars, which
are vertical lines, depicting the uncertainty - a range which is possible
for that value. As seen in the example, we need four data sets to define
a series of error bars. The first data set are the x-values of the error
bars, the second the y-values. The third set holds the lenght of the upper
part of the error bar and the fourth set the lower part (distance between
main point and the lower bound of the error bar). The fourth set might be
omitted, when property L<same_error|Chart::Manual::Properties/same_error>
is set C<'true'>. In this case upper and lower part of the error bar have
the same size. Because all this produced only one set of error bars
with one color, there is no need for a legend. That is why it is switched
off by setting property L<legend|Chart::Manual::Properties/legend> to
C<'none'>. The label on the x-axis are painted in the C<'staggered'> style,
so they don't overlap. L<pt_size|Chart::Manual::Properties/pt_size> refers
to the diameter in pixel of the errors bars central point.
L<brush_size|Chart::Manual::Properties/brush_size> is the thickness of the bar.
For better readability C<'both'> L<y_axes|Chart::Manual::Properties/y_axes> were labeled.
use Chart::ErrorBars;
my $g = Chart::ErrorBars->new( 500, 400 );
$g->add_dataset(qw(1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 2.4 2.5));
$g->add_dataset(qw(1 1.1 1.2 1.1 1.14 1.15 1.26 1.2 1.1 1.19 1.2 1.4 1.6 2.0 2.5 3.1));
$g->add_dataset(qw(0.4 0.1 0.2 0.1 0.14 0.15 0.26 0.27 0.1 0.19 0.2 0.1 0.1 0.2 0.1 0.3));
$g->add_dataset(qw(0.2 0.11 0.12 0.11 0.2 0.3 0.12 0.27 0.11 0.3 0.2 0.2 0.2 0.1 0.1 0.2));
$g->set(
title => 'Error Bars Demo',
legend => 'none',
y_axes => 'both',
x_ticks => 'staggered',
pt_size => 12,
brush_size => 2,
grid_lines => 'true',
colors => {
grid_lines => 'gray70',
misc => 'gray65',
},
);
lib/Chart/Manual/Types.pod view on Meta::CPAN
=for HTML <p>
<img src="https://raw.githubusercontent.com/lichtkind/Chart/main/dev/example/manual/lines.png" alt="xy chart with lines">
</p>
The class Chart::Lines creates a chart with lines that connect the would
be data points. If you want to make the points more visible,
use L</LinesPoints>. The only special property is L<brush_size|Chart::Manual::Properties/brush_size>,
the thickness of the lines, which was not even utilized in this example.
To make things nicer we put only some softer colors to the horizontal (y)
grid lines and the box and ticks (misc) and placed the legend on the bottom
so that the chart doesn't get sqeezed by it.
use Chart::Lines;
my $g = Chart::Lines->new( 600, 400 );
$g->add_dataset( 'foo', 'bar', 'whee', 'ding', 'bat', 'bit' );
$g->add_dataset( 3.2, 4.34, 9.456, 10.459, 11.24234, 14.0234 );
$g->add_dataset( -1.3, 8.4, 5.34, 3.234, 4.33, 13.09 );
$g->add_dataset( 5, 7, 2, 10, 12, 2.3445 );
$g->set(
title => 'Lines Chart',
legend => 'bottom' ,
y_label => 'y label 1',
precision => 0,
y_grid_lines => 'true',
colors => {
y_label => 'orangepeel',
y_grid_lines => [ 190, 190, 190 ],
misc => [ 100, 100, 100 ],
},
);
$g->png("lines.png");
lib/Chart/Manual/Types.pod view on Meta::CPAN
This allows you to give the x-axis none numerical, custom tick labels,
which are by accident the numbers 1 .. 17, as the first data row shows.
The purpose of this maneuver is to not have zero as the first column label.
Because the origin of coordinate system is usually in the left lower
corner, we used a trick to flip the y-axis having the smallest values up.
We negated all values in the data, so that 8 is lower than 2, because
-8 is smaller than -2. Than we transformed the y-axis labels with a function,
that negates the value of the original label, erasing the minus sign.
For additional clarity, we put the names of the teams into the legend,
which is per default on the right side. And to make the code more compact,
we packed the first (just labels) and the four real data sets (rows)
together into an array or arrays and gave it as second argument directly
to the drawing method.
use Chart::LinesPoints;
my $g = Chart::LinesPoints->new( 600, 300 );
$g->set(
title => 'Soccer Season 2002',
legend_labels => ['NY Soccer Club', 'Denver Tigers',
'Houston Spacecats', 'Washington Presidents'],
y_label => 'position in the table',
x_label => 'day of play',
grid_lines => 'true',
f_y_tick => sub { - $_[0] },
# xy_plot => 'true',
integer_ticks_only => 'true',
colors => {
grid_lines => 'gray70',
},
lib/Chart/Manual/Types.pod view on Meta::CPAN
$g->set(
title => 'Sold Tickets for Beethovens 9th',
y_label => 'Sold Tickets',
x_label => '! sold out in the first week !',
sort => 'true',
max_val => 5500,
integer_ticks_only => 'true',
skip_int_ticks => 250,
y_grid_lines => 'true',
spaced_bars => 'false',
legend => 'none',
colors => {
title => 'darkblue',
dataset0 => 'green',
dataset1 => 'aurorared',
x_label => 'aurorared',
y_grid_lines => 'white',
},
);
$g->png("pareto.png");
lib/Chart/Manual/Types.pod view on Meta::CPAN
<img src="https://raw.githubusercontent.com/lichtkind/Chart/main/dev/example/manual/pie.png" alt="pie chart">
</p>
The class Chart::Pie creates a pie or ring chart. The first added data
set must contain the labels and the second set the values. Our example
displays a ring chart with a thickness of 35% (of the radius). If the
L<ring|Chart::Manual::Properties/ring> property is omitted, the chart form
falls back to regular pie. Every ring slice is labeled with the stated label,
plus the percentage of its value, as defined with the property
L<label_values|Chart::Manual::Properties/label_values>. Connecting lines
between label and slice are drawn because L<legend_lines|Chart::Manual::Properties/legend_lines>
is set to C<'true'>. The actual legend is placed on the bottom, in order
to leave the ring as large as possible. The legend again shows the
association between color and data point and its value because
L<legend_label_values|Chart::Manual::Properties/legend_label_values>
is set to C<'values'>. Unlike other chart types, where one data set is
correlated with a color, here every slice has to have its own color.
Thats why the first data point has the color of L<dataset0|Chart::Manual::Properties/colors-datasetx>
the second of dataset1 and so forth. In most cases the default colors
are good enough, unless you have special meanings in mind. Please also
note the multi line (row) title text.
use Chart::Pie;
my $g = Chart::Pie->new( 500, 450 );
$g->add_dataset( qw/eins zwei drei vier fuenf sechs sieben acht neun zehn/ );
$g->add_dataset( 120, 50, 100, 80, 40, 45, 150, 60, 110, 50 );
$g->set( 'title' => 'Pie\nDemo Chart',
'legend' => 'bottom',
'legend_label_values' => 'value',
'label_values' => 'percent',
'legend_lines' => 'true',
'ring' => 0.35,
);
$g->png("pie.png");
=head2 Points
=for HTML <p>
<img src="https://raw.githubusercontent.com/lichtkind/Chart/main/dev/example/manual/points.png" alt="xy chart with points">
<img src="https://raw.githubusercontent.com/lichtkind/Chart/main/dev/example/test/points_5.png" alt="point styles demo">
lib/Chart/Manual/Types.pod view on Meta::CPAN
$g->add_dataset(@domain);
$g->add_dataset(@rnd);
$g->add_dataset(@diff);
$g->set(
title => "Random Numbers Test",
x_label => "4000 Random Numbers",
start => 0,
interval => 400,
brush_size => 1,
interval_ticks => 0,
legend => 'bottom',
legend_labels => ['random numbers', 'difference' ],
colors => {
title => 'darkblue',
text => 'gray45',
misc => 'gray45',
},
);
$g->png("split.png");
=head2 StackedBars
lib/Chart/Manual/Types.pod view on Meta::CPAN
use Chart::StackedBars;
my $g = Chart::StackedBars->new( 600, 400 );
$g->add_dataset( 'camel', 'dromedar', 'llama', 'vicuna');
$g->add_dataset( 3, 4, 9, 10, );
$g->add_dataset( 8, 6, 1, 12, );
$g->add_dataset( 5, 7, 2, 13, );
$g->set(
title => 'Stacked Bars',
legend => 'left',
precision => 0,
y_grid_lines => 'true',
grey_background => 'false',
colors => {
grid_lines => 'gray80',
misc => 'gray55',
text => 'gray55',
x_label => 'gray40',
y_label => 'gray40',
title => 'gray20',
lib/Chart/Mountain.pm view on Meta::CPAN
#
# If the y data value in any dataset is undef or negative for
# a given x, then all datasets are treated as missing for that x.
#
# The y minimum is always forced to zero.
#
# To avoid a dataset area "cutting into" the area of the dataset below
# it, the y pixel for each dataset point will never be below the y pixel for
# the same point in the dataset below the dataset.
# This probably should have a custom legend method, because each
# dataset is identified by the fill color (and optional pattern)
# of its area, not just a line color. So the legend shou a square
# of the color and pattern for each dataset.
use v5.12;
package Chart::Mountain;
our @ISA = qw(Chart::Base);
our $VERSION = 'v2.403.9';
use Chart::Base;
use GD;
lib/Chart/Mountain.pm view on Meta::CPAN
{
$self->_draw_title();
}
#draw the sub title again
if ( $self->{'sub_title'} )
{
$self->_draw_sub_title();
}
#draw the top legend again
if ( $self->{'legend'} =~ /^top$/i )
{
$self->_draw_top_legend();
}
#reset the actual values
$self->{'curr_x_min'} = $t_x_min;
$self->{'curr_x_max'} = $t_x_max;
$self->{'curr_y_min'} = $t_y_min;
$self->{'curr_y_max'} = $t_y_max;
}
}
lib/Chart/Pareto.pm view on Meta::CPAN
@values = sort { $b <=> $a } @values;
#save the sorted values and their labels
@{ $data->[0] } = @labels;
@{ $data->[1] } = @values;
#finally return
return 1;
}
## @fn private _draw_legend
# let them know what all the pretty colors mean
sub _draw_legend
{
my $self = shift;
my ($length);
my $num_dataset;
# check to see if legend type is none..
if ( $self->{'legend'} =~ /^none$/ )
{
return 1;
}
# check to see if they have as many labels as datasets,
# warn them if not
if ( ( $#{ $self->{'legend_labels'} } >= 0 )
&& ( ( scalar( @{ $self->{'legend_labels'} } ) ) != 2 ) )
{
carp "I need two legend labels. One for the data and one for the sum.";
}
# init a field to store the length of the longest legend label
unless ( $self->{'max_legend_label'} )
{
$self->{'max_legend_label'} = 0;
}
# fill in the legend labels, find the longest one
unless ( $self->{'legend_labels'}[0] )
{
$self->{'legend_labels'}[0] = "Dataset";
}
unless ( $self->{'legend_labels'}[1] )
{
$self->{'legend_labels'}[1] = "Running sum";
}
if ( length( $self->{'legend_labels'}[0] ) > length( $self->{'legend_labels'}[1] ) )
{
$self->{'max_legend_label'} = length( $self->{'legend_labels'}[0] );
}
else
{
$self->{'max_legend_label'} = length( $self->{'legend_labels'}[1] );
}
#set the number of datasets to 2, and store it
$num_dataset = $self->{'num_datasets'};
$self->{'num_datasets'} = 2;
# different legend types
if ( $self->{'legend'} eq 'bottom' )
{
$self->_draw_bottom_legend;
}
elsif ( $self->{'legend'} eq 'right' )
{
$self->_draw_right_legend;
}
elsif ( $self->{'legend'} eq 'left' )
{
$self->_draw_left_legend;
}
elsif ( $self->{'legend'} eq 'top' )
{
$self->_draw_top_legend;
}
else
{
carp "I can't put a legend there (at " . $self->{'legend'} . ")\n";
}
#reload the number of datasets
$self->{'num_datasets'} = $num_dataset;
# and return
return 1;
}
## @fn private _draw_data
lib/Chart/Pareto.pm view on Meta::CPAN
sub _draw_data
{
my $self = shift;
my $data = $self->{'dataref'};
my $misccolor = $self->_color_role_to_index('misc');
my ( $x1, $x2, $x3, $y1, $y2, $y3, $y1_line, $y2_line, $x1_line, $x2_line, $h, $w );
my ( $width, $height, $delta1, $delta2, $map, $mod, $cut );
my ( $i, $j, $color, $line_color, $percent, $per_label, $per_label_len );
my $sum = $self->{'sum'};
my $curr_sum = 0;
my $font = $self->{'legend_font'};
my $pink = $self->{'gd_obj'}->colorAllocate( 255, 0, 255 );
my $diff;
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The subtitle font you specified isn\'t a GD Font object";
}
# get the size of the font
lib/Chart/Pie.pm view on Meta::CPAN
my $max_val_len = 0;
my $max_label_len = 0;
# set up initial constant values
$pi = Chart::Constants::PI;
$dg2rd = $pi / 180; # Degree to Radians
$rd2dg = 180 / $pi; # Radian to Degree
$start_degrees = 0;
$end_degrees = 0;
$font = $self->{'legend_font'};
$fontW = $self->{'legend_font'}->width;
$fontH = $self->{'legend_font'}->height;
$label_degrees = $labelY_repeat_count = 0;
# init the imagemap data field if they wanted it
if ( $self->true( $self->{'imagemap'} ) )
{
$self->{'imagemap_data'} = [];
}
# find width and height of the plotting area
$width = $self->{'curr_x_max'} - $self->{'curr_x_min'};
lib/Chart/Pie.pm view on Meta::CPAN
$self->{'gd_obj'}->string( $font, $labelX, $labelY - $fontH * 0.5, $label, $textcolor );
}
else
{
# $textcolor marks everything black
$self->{'gd_obj'}->string( $font, $labelX - length($label) * $fontW, $labelY - $fontH * 0.5, $label, $textcolor );
}
if ( $self->true( $self->{'legend_lines'} ) )
{
$self->{'gd_obj'}->line(
$centerX + 0.5 * $diameter * cos( $degrees * $dg2rd ),
$centerY + 0.5 * $diameter * sin( $degrees * $dg2rd ),
$labelX, $labelY, $color
);
}
# reset starting point for next dataset and continue.
$start_degrees = $end_degrees;
lib/Chart/Pie.pm view on Meta::CPAN
}
# and finaly box it off
$self->{'gd_obj'}
->rectangle( $self->{'curr_x_min'}, $self->{'curr_y_min'}, $self->{'curr_x_max'}, $self->{'curr_y_max'}, $misccolor );
return;
}
## @fn private _draw_right_legend
# Overwrite the legend methods to get the right legend
sub _draw_right_legend
{
my $self = shift;
my $data = $self->{'dataref'};
my @labels = @{ $data->[0] };
my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush );
my $font = $self->{'legend_font'};
my $l1 = 0;
my $l2 = 0;
my ( $i, $j, $label, $dataset_sum );
my $max_label_len = 1;
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The font you specified isn\'t a GD Font object";
}
lib/Chart/Pie.pm view on Meta::CPAN
}
}
for ( my $i = 0 ; $i < ( $self->{'num_datapoints'} ) ; $i++ )
{
if ( length( $data->[1][$i] ) > $l2 )
{
$l2 = length( $data->[1][$i] );
}
}
if ( $self->{'legend_label_values'} =~ /^value$/i )
{
$max_label_len = $l1 + $l2 + 1;
}
elsif ( $self->{'legend_label_values'} =~ /^percent$/i )
{
$max_label_len = $l1 + 7;
}
elsif ( $self->{'legend_label_values'} =~ /^both$/i )
{
$max_label_len = $l1 + $l2 + 9;
}
else
{
$max_label_len = $l1;
}
# find out how wide the largest label is
$width = ( 2 * $self->{'text_space'} )
#+ ($self->{'max_legend_label'} * $w)
+ $max_label_len * $w + $self->{'legend_example_size'} + ( 2 * $self->{'legend_space'} );
# get some starting x-y values
$x1 = $self->{'curr_x_max'} - $width;
$x2 = $self->{'curr_x_max'};
$y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
$y2 =
$self->{'curr_y_min'} +
$self->{'graph_border'} +
$self->{'text_space'} +
( $self->{'num_datapoints'} * ( $h + $self->{'text_space'} ) ) +
( 2 * $self->{'legend_space'} );
# box the legend off
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );
# leave that nice space inside the legend box
$x1 += $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
# now draw the actual legend
for ( 0 .. $#labels )
{
# get the color
$color = $self->_color_role_to_index( 'dataset' . $_ );
# find the x-y coords
$x2 = $x1;
$x3 = $x2 + $self->{'legend_example_size'};
$y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;
# do the line first
$self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );
# reset the brush for points
$brush = $self->_prepare_brush( $color, 'point', $self->{ 'pointStyle' . $_ } );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$self->{'gd_obj'}->line( int( ( $x3 + $x2 ) / 2 ), $y2, int( ( $x3 + $x2 ) / 2 ), $y2, gdBrushed );
# now the label
$x2 = $x3 + ( 2 * $self->{'text_space'} );
$y2 -= $h / 2;
if ( defined $data->[1][$_] )
{
if ( $self->{'legend_label_values'} =~ /^value$/i )
{
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_] . ' ' . $data->[1][$_], $color );
}
elsif ( $self->{'legend_label_values'} =~ /^percent$/i )
{
$label = sprintf( "%s %4.2f%%", $labels[$_], $data->[1][$_] / ( $dataset_sum || 1 ) * 100 );
$self->{'gd_obj'}->string( $font, $x2, $y2, $label, $color );
}
elsif ( $self->{'legend_label_values'} =~ /^both$/i )
{
if ( $data->[1][$_] =~ /\./ )
{
$label =
sprintf( "%s %4.2f%% %.2f", $labels[$_], $data->[1][$_] / ( $dataset_sum || 1 ) * 100, $data->[1][$_] );
}
else
{
$label =
sprintf( "%s %4.2f%% %d", $labels[$_], $data->[1][$_] / ( $dataset_sum || 1 ) * 100, $data->[1][$_] );
lib/Chart/Pie.pm view on Meta::CPAN
}
}
# mark off the used space
$self->{'curr_x_max'} -= $width;
# and return
return 1;
}
## @fn private _draw_left_legend
# put the legend on the left of the chart
sub _draw_left_legend
{
my $self = shift;
my $data = $self->{'dataref'};
my @labels = @{ $data->[0] };
my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush );
my $font = $self->{'legend_font'};
my $max_label_len = 1;
my $l1 = 0;
my $l2 = 0;
my ( $dataset_sum, $label );
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The font you specified isn\'t a GD Font object";
}
lib/Chart/Pie.pm view on Meta::CPAN
}
}
for ( my $i = 0 ; $i < ( $self->{'num_datapoints'} ) ; $i++ )
{
if ( length( $data->[1][$i] ) > $l2 )
{
$l2 = length( $data->[1][$i] );
}
}
if ( $self->{'legend_label_values'} =~ /^value$/i )
{
$max_label_len = $l1 + $l2 + 1;
}
elsif ( $self->{'legend_label_values'} =~ /^percent$/i )
{
$max_label_len = $l1 + 7;
}
elsif ( $self->{'legend_label_values'} =~ /^both$/i )
{
$max_label_len = $l1 + $l2 + 9;
}
else
{
$max_label_len = $l1;
}
# find out how wide the largest label is
$width =
( 2 * $self->{'text_space'} ) +
( $max_label_len * $w ) +
$self->{'legend_example_size'} +
( 2 * $self->{'legend_space'} );
# get some base x-y coordinates
$x1 = $self->{'curr_x_min'};
$x2 = $self->{'curr_x_min'} + $width;
$y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
$y2 =
$self->{'curr_y_min'} +
$self->{'graph_border'} +
$self->{'text_space'} +
( $self->{'num_datapoints'} * ( $h + $self->{'text_space'} ) ) +
( 2 * $self->{'legend_space'} );
# box the legend off
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );
# leave that nice space inside the legend box
$x1 += $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
# now draw the actual legend
for ( 0 .. $#labels )
{
# get the color
$color = $self->_color_role_to_index( 'dataset' . $_ );
# find the x-y coords
$x2 = $x1;
$x3 = $x2 + $self->{'legend_example_size'};
$y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;
# do the line first
$self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );
# reset the brush for points
$brush = $self->_prepare_brush( $color, 'point', $self->{ 'pointStyle' . $_ } );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$self->{'gd_obj'}->line( int( ( $x3 + $x2 ) / 2 ), $y2, int( ( $x3 + $x2 ) / 2 ), $y2, gdBrushed );
# now the label
$x2 = $x3 + ( 2 * $self->{'text_space'} );
$y2 -= $h / 2;
if ( $self->{'legend_label_values'} =~ /^value$/i )
{
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_] . ' ' . $data->[1][$_], $color );
}
elsif ( $self->{'legend_label_values'} =~ /^percent$/i )
{
$label = sprintf( "%s %4.2f%%", $labels[$_], $data->[1][$_] / ( $dataset_sum || 1 ) * 100 );
$self->{'gd_obj'}->string( $font, $x2, $y2, $label, $color );
}
elsif ( $self->{'legend_label_values'} =~ /^both$/i )
{
if ( $data->[1][$_] =~ /\./ )
{
$label =
sprintf( "%s %4.2f%% %.2f", $labels[$_], $data->[1][$_] / ( $dataset_sum || 1 ) * 100, $data->[1][$_] );
}
else
{
$label = sprintf( "%s %4.2f%% %d", $labels[$_], $data->[1][$_] / ( $dataset_sum || 1 ) * 100, $data->[1][$_] );
}
lib/Chart/Pie.pm view on Meta::CPAN
}
# mark off the used space
$self->{'curr_x_min'} += $width;
# and return
return 1;
}
## @fn private _draw_bottom_legend
# put the legend on the bottom of the chart
sub _draw_bottom_legend
{
my $self = shift;
my $data = $self->{'dataref'};
my @labels = @{ $data->[0] };
my ( $x1, $y1, $x2, $x3, $y2, $empty_width, $max_label_width, $cols, $rows, $color, $brush );
my ( $col_width, $row_height, $r, $c, $index, $x, $y, $w, $h );
my $font = $self->{'legend_font'};
my $max_label_len;
my $l1 = 0;
my $l2 = 0;
my ( $dataset_sum, $j );
my $label;
my $text_color = $self->_color_role_to_index( 'text' );
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
lib/Chart/Pie.pm view on Meta::CPAN
}
}
for ( my $i = 0 ; $i < ( $self->{'num_datapoints'} ) ; $i++ )
{
if ( length( $data->[1][$i] ) > $l2 )
{
$l2 = length( $data->[1][$i] );
}
}
if ( $self->{'legend_label_values'} =~ /^value$/i )
{
$max_label_len = $l1 + $l2 + 1;
}
elsif ( $self->{'legend_label_values'} =~ /^percent$/i )
{
$max_label_len = $l1 + 7;
}
elsif ( $self->{'legend_label_values'} =~ /^both$/i )
{
$max_label_len = $l1 + $l2 + 9;
}
else
{
$max_label_len = $l1;
}
# figure out how wide the columns need to be, and how many we
# can fit in the space available
$empty_width = ( $x2 - $x1 ) - ( 2 * $self->{'legend_space'} );
$max_label_width = $max_label_len * $w
#$self->{'max_legend_label'} * $w
+ ( 4 * $self->{'text_space'} ) + $self->{'legend_example_size'};
$cols = int( $empty_width / $max_label_width );
unless ($cols)
{
$cols = 1;
}
$col_width = $empty_width / $cols;
# figure out how many rows we need, remember how tall they are
$rows = int( $self->{'num_datapoints'} / $cols );
unless ( ( $self->{'num_datapoints'} % $cols ) == 0 )
{
$rows++;
}
unless ($rows)
{
$rows = 1;
}
$row_height = $h + $self->{'text_space'};
# box the legend off
$y1 = $self->{'curr_y_max'} - $self->{'text_space'} - ( $rows * $row_height ) - ( 2 * $self->{'legend_space'} );
$y2 = $self->{'curr_y_max'};
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $self->_color_role_to_index('misc') );
$x1 += $self->{'legend_space'} + $self->{'text_space'};
$x2 -= $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
$y2 -= $self->{'legend_space'} + $self->{'text_space'};
# draw in the actual legend
for $r ( 0 .. $rows - 1 )
{
for $c ( 0 .. $cols - 1 )
{
$index = ( $r * $cols ) + $c; # find the index in the label array
if ( $labels[$index] )
{
# get the color
$color = $self->_color_role_to_index( 'dataset' . $index );
# get the x-y coordinate for the start of the example line
$x = $x1 + ( $col_width * $c );
$y = $y1 + ( $row_height * $r ) + $h / 2;
# now draw the example line
$self->{'gd_obj'}->line( $x, $y, $x + $self->{'legend_example_size'}, $y, $color );
# reset the brush for points
$brush = $self->_prepare_brush( $color, 'point', $self->{ 'pointStyle' . $index } );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$x3 = int( $x + $self->{'legend_example_size'} / 2 );
$self->{'gd_obj'}->line( $x3, $y, $x3, $y, gdBrushed );
# adjust the x-y coordinates for the start of the label
$x += $self->{'legend_example_size'} + ( 2 * $self->{'text_space'} );
$y = $y1 + ( $row_height * $r );
# now draw the label
if ( $self->{'legend_label_values'} =~ /^value$/i )
{
$self->{'gd_obj'}->string( $font, $x, $y, $labels[$index] . ' ' . $data->[1][$index], $text_color );
#$self->{'gd_obj'}->stringTTF($color, FONT, 10, 0, $x, $y+10, $labels[$index].' '.$data->[1][$index]); ############
}
elsif ( $self->{'legend_label_values'} =~ /^percent$/i )
{
$label = sprintf( "%s %4.2f%%", $labels[$index], $data->[1][$index] / ( $dataset_sum || 1 ) * 100 );
$self->{'gd_obj'}->string( $font, $x, $y, $label, $color );
}
elsif ( $self->{'legend_label_values'} =~ /^both$/i )
{
if ( $data->[1][$index] =~ /\./ )
{
$label = sprintf( "%s %4.2f%% %.2f",
$labels[$index],
$data->[1][$index] / ( $dataset_sum || 1 ) * 100,
$data->[1][$index] );
}
else
{
lib/Chart/Pie.pm view on Meta::CPAN
}
else
{
$self->{'gd_obj'}->string( $font, $x, $y, $labels[$index], $text_color );
}
}
}
}
# mark off the space used
$self->{'curr_y_max'} -= ( $rows * $row_height ) + $self->{'text_space'} + ( 2 * $self->{'legend_space'} );
# now return
return 1;
}
## @fn private _draw_top_legend
# put the legend on top of the chart
sub _draw_top_legend
{
my $self = shift;
my $data = $self->{'dataref'};
my ($max_label_len);
my $l1 = 0;
my $l2 = 0;
my @labels = @{ $data->[0] };
my ( $x1, $y1, $x2, $x3, $y2, $empty_width, $max_label_width, $cols, $rows, $color, $brush );
my ( $col_width, $row_height, $r, $c, $index, $x, $y, $w, $h, $dataset_sum, $label );
my $font = $self->{'legend_font'};
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The font you specified isn\'t a GD Font object";
}
# get the size of the font
( $h, $w ) = ( $font->height, $font->width );
lib/Chart/Pie.pm view on Meta::CPAN
}
}
for ( my $i = 0 ; $i < ( $self->{'num_datapoints'} ) ; $i++ )
{
if ( length( $data->[1][$i] ) > $l2 )
{
$l2 = length( $data->[1][$i] );
}
}
if ( $self->{'legend_label_values'} =~ /^value$/i )
{
$max_label_len = $l1 + $l2 + 1;
}
elsif ( $self->{'legend_label_values'} =~ /^percent$/i )
{
$max_label_len = $l1 + 7;
}
elsif ( $self->{'legend_label_values'} =~ /^both$/i )
{
$max_label_len = $l1 + $l2 + 9;
}
else
{
$max_label_len = $l1;
}
# figure out how wide the columns can be, and how many will fit
$empty_width = ( $x2 - $x1 ) - ( 2 * $self->{'legend_space'} );
$max_label_width = ( 4 * $self->{'text_space'} ) + $max_label_len * $w + $self->{'legend_example_size'};
$cols = int( $empty_width / $max_label_width );
unless ($cols)
{
$cols = 1;
}
$col_width = $empty_width / $cols;
# figure out how many rows we need and remember how tall they are
$rows = int( $self->{'num_datapoints'} / $cols );
unless ( ( $self->{'num_datapoints'} % $cols ) == 0 )
{
$rows++;
}
unless ($rows)
{
$rows = 1;
}
$row_height = $h + $self->{'text_space'};
# box the legend off
$y1 = $self->{'curr_y_min'};
$y2 = $self->{'curr_y_min'} + $self->{'text_space'} + ( $rows * $row_height ) + ( 2 * $self->{'legend_space'} );
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $self->_color_role_to_index('misc') );
# leave some space inside the legend
$x1 += $self->{'legend_space'} + $self->{'text_space'};
$x2 -= $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
$y2 -= $self->{'legend_space'} + $self->{'text_space'};
# draw in the actual legend
for $r ( 0 .. $rows - 1 )
{
for $c ( 0 .. $cols - 1 )
{
$index = ( $r * $cols ) + $c; # find the index in the label array
if ( $labels[$index] )
{
# get the color
$color = $self->_color_role_to_index( 'dataset' . $index );
# find the x-y coords
$x = $x1 + ( $col_width * $c );
$y = $y1 + ( $row_height * $r ) + $h / 2;
# draw the line first
$self->{'gd_obj'}->line( $x, $y, $x + $self->{'legend_example_size'}, $y, $color );
# reset the brush for points
$brush = $self->_prepare_brush( $color, 'point', $self->{ 'pointStyle' . $index } );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$x3 = int( $x + $self->{'legend_example_size'} / 2 );
$self->{'gd_obj'}->line( $x3, $y, $x3, $y, gdBrushed );
# now the label
$x += $self->{'legend_example_size'} + ( 2 * $self->{'text_space'} );
$y -= $h / 2;
if ( $self->{'legend_label_values'} =~ /^value$/i )
{
$self->{'gd_obj'}->string( $font, $x, $y, $labels[$index] . ' ' . $data->[1][$index], $color );
}
elsif ( $self->{'legend_label_values'} =~ /^percent$/i )
{
$label = sprintf( "%s %4.2f%%", $labels[$index], $data->[1][$index] / ( $dataset_sum || 1 ) * 100 );
$self->{'gd_obj'}->string( $font, $x, $y, $label, $color );
}
elsif ( $self->{'legend_label_values'} =~ /^both$/i )
{
if ( $data->[1][$index] =~ /\./ )
{
$label = sprintf( "%s %4.2f%% %.2f",
$labels[$index],
$data->[1][$index] / ( $dataset_sum || 1 ) * 100,
$data->[1][$index] );
}
else
{
lib/Chart/Pie.pm view on Meta::CPAN
}
else
{
$self->{'gd_obj'}->string( $font, $x, $y, $labels[$index], $color );
}
}
}
}
# mark off the space used
$self->{'curr_y_min'} += ( $rows * $row_height ) + $self->{'text_space'} + 2 * $self->{'legend_space'};
# now return
return 1;
}
## @fn private _draw_x_ticks
# Override the ticks methods for the pie charts.\n
# Here: do nothing
sub _draw_x_ticks
{
lib/Chart/StackedBars.pm view on Meta::CPAN
}
}
# and finaly box it off
$self->{'gd_obj'}
->rectangle( $self->{'curr_x_min'}, $self->{'curr_y_min'}, $self->{'curr_x_max'}, $self->{'curr_y_max'}, $misccolor );
return;
}
## @fn private _draw_left_legend
sub _draw_left_legend
{
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush );
my $font = $self->{'legend_font'};
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The subtitle font you specified isn\'t a GD Font object";
}
# get the size of the font
( $h, $w ) = ( $font->height, $font->width );
# get the miscellaneous color
$misccolor = $self->_color_role_to_index('misc');
# find out how wide the largest label is
$width =
( 2 * $self->{'text_space'} ) +
( $self->{'max_legend_label'} * $w ) +
$self->{'legend_example_size'} +
( 2 * $self->{'legend_space'} );
# get some base x-y coordinates
$x1 = $self->{'curr_x_min'};
$x2 = $self->{'curr_x_min'} + $width;
$y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
$y2 =
$self->{'curr_y_min'} +
$self->{'graph_border'} +
$self->{'text_space'} +
( $self->{'num_datasets'} * ( $h + $self->{'text_space'} ) ) +
( 2 * $self->{'legend_space'} );
# box the legend off
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );
# leave that nice space inside the legend box
$x1 += $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
# now draw the actual legend
for ( 0 .. $#labels )
{
# get the color
my $c = $self->{'num_datasets'} - $_ - 1;
# color of the datasets in the legend
if ( $self->{'dataref'}[1][0] < 0 )
{
$color = $self->_color_role_to_index( 'dataset' . $_ );
}
else
{
$color = $self->_color_role_to_index( 'dataset' . $c );
}
# find the x-y coords
$x2 = $x1;
$x3 = $x2 + $self->{'legend_example_size'};
$y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;
# do the line first
$self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );
# reset the brush for points
$brush = $self->_prepare_brush( $color, 'point', $self->{ 'pointStyle' . $_ } );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$self->{'gd_obj'}->line( int( ( $x3 + $x2 ) / 2 ), $y2, int( ( $x3 + $x2 ) / 2 ), $y2, gdBrushed );
# now the label
$x2 = $x3 + ( 2 * $self->{'text_space'} );
$y2 -= $h / 2;
# order of the datasets in the legend
if ( $self->{'dataref'}[1][0] < 0 )
{
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_], $color );
}
else
{
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$c], $color );
}
}
# mark off the used space
$self->{'curr_x_min'} += $width;
# and return
return 1;
}
## @fn private _draw_right_legend
sub _draw_right_legend
{
my $self = shift;
my @labels = @{ $self->{'legend_labels'} };
my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush );
my $font = $self->{'legend_font'};
# make sure we're using a real font
unless ( ( ref($font) ) eq 'GD::Font' )
{
croak "The subtitle font you specified isn\'t a GD Font object";
}
# get the size of the font
( $h, $w ) = ( $font->height, $font->width );
# get the miscellaneous color
$misccolor = $self->_color_role_to_index('misc');
# find out how wide the largest label is
$width =
( 2 * $self->{'text_space'} ) +
( $self->{'max_legend_label'} * $w ) +
$self->{'legend_example_size'} +
( 2 * $self->{'legend_space'} );
# get some starting x-y values
$x1 = $self->{'curr_x_max'} - $width;
$x2 = $self->{'curr_x_max'};
$y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
$y2 =
$self->{'curr_y_min'} +
$self->{'graph_border'} +
$self->{'text_space'} +
( $self->{'num_datasets'} * ( $h + $self->{'text_space'} ) ) +
( 2 * $self->{'legend_space'} );
# box the legend off
$self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );
# leave that nice space inside the legend box
$x1 += $self->{'legend_space'};
$y1 += $self->{'legend_space'} + $self->{'text_space'};
# now draw the actual legend
for ( 0 .. $#labels )
{
# get the color
my $c = $self->{'num_datasets'} - $_ - 1;
# color of the datasets in the legend
if ( $self->{'dataref'}[1][0] < 0 )
{
$color = $self->_color_role_to_index( 'dataset' . $_ );
}
else
{
$color = $self->_color_role_to_index( 'dataset' . $c );
}
# find the x-y coords
$x2 = $x1;
$x3 = $x2 + $self->{'legend_example_size'};
$y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;
# do the line first
$self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );
# reset the brush for points
$brush = $self->_prepare_brush( $color, 'point', $self->{ 'pointStyle' . $_ } );
$self->{'gd_obj'}->setBrush($brush);
# draw the point
$self->{'gd_obj'}->line( int( ( $x3 + $x2 ) / 2 ), $y2, int( ( $x3 + $x2 ) / 2 ), $y2, gdBrushed );
# now the label
$x2 = $x3 + ( 2 * $self->{'text_space'} );
$y2 -= $h / 2;
# order of the datasets in the legend
if ( $self->{'dataref'}[1][0] < 0 )
{
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_], $color );
}
else
{
$self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$c], $color );
}
}
t/Humidity.t view on Meta::CPAN
$graphic->set( 'grey_background' => 'false' );
$graphic->set( 'graph_border' => 18 );
$graphic->set( 'title' => $titel_name );
$graphic->set( 'sub_title' => "over Time" );
$graphic->set( 'y_grid_lines' => 'true' );
$graphic->set( 'x_grid_lines' => 'true' );
$graphic->set( 'x_ticks' => 'vertical' );
$graphic->set(
'colors' => { 'y_grid_lines' => [ 127, 127, 0 ], 'x_grid_lines' => [ 127, 127, 0 ], 'dataset0' => [ 0, 0, 200 ] } );
$graphic->set( 'legend' => 'none' );
$graphic->set( 'x_label' => 'Time (UTC)' );
$graphic->set( 'y_label' => $einheit );
if ( $graphic->can('gif') )
{
my $wettgif = "$samples/" . $gif_name . ".gif";
$graphic->gif($wettgif);
}
elsif ( $graphic->can('png') )
{
t/Math_1_over_x.t view on Meta::CPAN
#$graphic -> set ('y_ticks' => 11 );
$graphic->set( 'x_ticks' => 'vertical' );
$graphic->set( 'skip_x_ticks' => 10 );
$graphic->set( 'grey_background' => 'true' );
$graphic->set( 'graph_border' => 18 );
$graphic->set( 'title' => "1/x" );
$graphic->set( 'y_grid_lines' => 'true' );
$graphic->set( 'x_grid_lines' => 'true' );
$graphic->set( 'x_ticks' => 'vertical' );
$graphic->set( 'legend' => 'none' );
$graphic->set( 'x_label' => 'x' );
$graphic->set( 'y_label' => 'f = 1/x' );
if ( $graphic->can('gif') )
{
my $picture_file = "$samples/Math_1_over_x.gif";
$graphic->gif($picture_file);
}
if ( $graphic->can('png') )
{
'precision' => 1,
'title' => 'Bars\nChartmodul',
'y_grid_lines' => 'true',
'graph_border' => '4',
'min_val' => '0',
'text_space' => '2',
'sub_title' => 'Untertitel',
'x_label' => 'X-Achse',
'y_label' => 'Y-Achse',
'y_label2' => 'Y-Achse2',
'legend' => 'none',
'tick_len' => '3',
'x_ticks' => 'vertical',
'include_zero' => 'true',
'skip_x_ticks' => '1',
'grid_lines' => 'true',
'colors' => {
'text' => [ 100, 0, 200 ],
'y_label' => [ 2, 255, 2 ],
'y_label2' => [ 2, 255, 2 ],
'y_grid_lines' => 'black',
t/bars_10.t view on Meta::CPAN
$g->add_dataset( 0, 0, 0, 0, 0 );
$g->add_dataset( 0, 0, 0, 0, 0 );
$g->add_dataset( 0, 0, 0, 0, 0 );
$g->add_dataset( 0, 0, 0, 0, 0 );
$g->add_dataset( 0, 0, 0, 0, 0 );
$g->add_dataset( 0, 0, 0, 0, 0 );
$g->add_dataset( 0, 0, 0, 0, 0 );
%hash = (
'title' => 'Only a demo chart with zero data',
'legend' => 'bottom',
'grid_lines' => 'true',
'include_zero' => 'true',
'max_val' => '20',
'min_val' => '-20',
'colors' => {
'title' => 'red',
'x_label' => 'blue',
'y_label' => 'blue',
'background' => 'grey',
'text' => 'blue',
t/bars_11.t view on Meta::CPAN
$g->add_datafile( $file );
$g->set(
colors => { dataset0 => [ 25, 220, 147 ], },
graph_border => 0,
grey_background => 'false',
grid_lines => 'true',
include_zero => 'true',
# integer_ticks_only => 'true',
legend => 'none',
png_border => 4,
precision => 1,
skip_int_ticks => 1000,
text_space => 3,
title => "Tickets",
title_font => GD::Font->Giant,
transparent => 'false',
x_ticks => 'vertical',
y_axes => 'both',
y_label => '# Tickets',
t/bars_12.t view on Meta::CPAN
$g->add_datafile( $file );
$g->set(
colors => { dataset0 => [ 25, 220, 147 ], },
graph_border => 0,
grey_background => 'false',
grid_lines => 'true',
include_zero => 'true',
# integer_ticks_only => 'true',
legend => 'none',
png_border => 4,
precision => 1,
skip_int_ticks => 1000,
text_space => 3,
title => "Tickets",
title_font => GD::Font->Giant,
transparent => 'false',
x_ticks => 'vertical',
y_axes => 'both',
y_label => '# Tickets',
$g->add_dataset( 10, 4, 6, 8, 10 );
$g->add_dataset( 14, 5, 4, 5, 11 );
$g->add_dataset( 12, 4, 6, 6, 12 );
$g->add_dataset( 18, 2, 3, 3, 9 );
$g->add_dataset( 17, 5, 7, 2, 6 );
%hash = (
'title' => 'Sold Cars in 2001',
'x_label' => 'City',
'y_label' => 'Number of Cars',
'legend' => 'bottom',
'legend_labels' => [
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
],
'grid_lines' => 'true',
'include_zero' => 'true',
'max_val' => '20',
'colors' => {
'title' => 'red',
'x_label' => 'blue',
'y_label' => 'blue',
$g = Chart::Bars->new( 500, 500 );
$g->add_dataset( 'Reds', 'Blacks', 'Greens', 'Yellows', 'Browns', 'Others' );
$g->add_dataset( -2.4, 3.4, 1.9, 1.2, -1.1, -2.9 );
%hash = (
'title' => 'Selection 2002:\nWins and Losses in percent',
'text_space' => 5,
'y_grid_lines' => 'true',
'grey_background' => 'false',
'legend' => 'none',
'min_val' => -4,
'max_val' => 4,
'min_y_ticks' => 10,
'y_axes' => 'both',
'spaced_bars' => 'false',
'colors' => {
'background' => [ 230, 255, 230 ],
'title' => 'plum',
'dataset0' => 'mauve',
},
$graphic->add_dataset(@y_values);
$graphic->set( 'min_val' => $min_y );
$graphic->set( 'max_val' => $max_y );
$graphic->set( 'min_y_ticks' => 20 );
$graphic->set( 'skip_x_ticks' => 1000 );
$graphic->set( 'graph_border' => 18 );
$graphic->set( 'title' => "The Integral of 1/x" );
$graphic->set( 'grid_lines' => 'true' );
$graphic->set( 'x_ticks' => 'vertical' );
$graphic->set( 'legend' => 'none' );
$graphic->set( 'y_label' => 'f = 1 / x' );
$graphic->set( 'xy_plot' => 'true' );
# use a special function to convert the y values to something special
$graphic->set( 'f_y_tick' => \&formatter );
$graphic->set( 'f_x_tick' => \&formatter );
$graphic->png($picture_file);
sub formatter
srand( time() / $_ );
$hits = int( rand(100) + 401 );
push( @data, $hits );
}
$g = Chart::Bars->new( 700, 300 );
$g->add_dataset(@labels);
$g->add_dataset(@data);
%hash = (
'legend' => 'none',
'precision' => 0,
'x_ticks' => 'vertical',
'title' => 'Lottozahlenverteilung',
'y_label' => 'Häufigkeit',
'y_grid_lines' => 'true',
);
$g->set(%hash);
$g->png("$samples/bars_5.png");
print "1..1\n";
my $g = Chart::Bars->new( 580, 300 );
my @data = ( 200202, 200203, 200204, 200205, 200206, 200207, 200208, 200209, 200210, 200211, 200212, 200301 );
my @data1 = ( 6626, 7662, 7580, 7671, 8064, 8664, 6343, 5518, 6257, 5391, 5401, 6002 );
$g->add_dataset(@data);
$g->add_dataset(@data1);
my @legend_keys = ( "Actual ", "Goal" );
$g->set(
colors => { dataset0 => [ 25, 220, 147 ], },
graph_border => 0,
grey_background => 'false',
grid_lines => 'true',
# integer_ticks_only => 'true',
legend => 'none',
# min_val => 0,
# include_zero => 'true',
png_border => 4,
precision => 1,
skip_int_ticks => 1000,
spaced_bars => 'true',
text_space => 3,
title => "Tickets",
title_font => GD::Font->Giant,
$g->add_dataset(@data);
$g->add_dataset(@data1);
$g->set(
colors => { dataset0 => [ 25, 220, 147 ], },
graph_border => 0,
grey_background => 'false',
grid_lines => 'true',
include_zero => 'true',
legend => 'none',
png_border => 4,
precision => 9,
spaced_bars => 'true',
text_space => 3,
title => "Tickets",
title_font => GD::Font->Giant,
transparent => 'false',
x_ticks => 'vertical',
y_axes => 'both',
y_label => '# Tickets',
my @data1 = (
6626 * $a, -790 * $a, 7580 * $a, 7671 * $a, 8764 * $a, 8664 * $a,
6343 * $a, 5518 * $a, 6257 * $a, 5391 * $a, 5401 * $a, 6002 * $a
);
#my @data1 =(6626,-790,7580,7671,8764,8664,6343,5518,6257,5391,5401,6002);
$g->add_dataset(@data);
$g->add_dataset(@data1);
my @legend_keys = ( "Actual ", "Goal" );
$g->set(
colors => { dataset0 => [ 25, 220, 147 ], },
graph_border => 0,
grey_background => 'false',
grid_lines => 'true',
include_zero => 'true',
# integer_ticks_only => 'true',
legend => 'none',
png_border => 4,
# precision => 27,
# skip_int_ticks => 1.0e-27,
text_space => 3,
title => "Tickets",
title_font => GD::Font->Giant,
transparent => 'false',
x_ticks => 'vertical',
y_axes => 'both',
my $g = Chart::Bars->new( 600, 400 );
my @data = ( 200202, 200203, 200204, 200205, 200206, 200207, 200208, 200209, 200210, 200211, 200212, 200301 );
my @data1 = ( 6626, 7090, 7580, 7671, 8764, 8664, 6343, 5518, 6257, 5391, 5401, 6002 );
$g->add_dataset(@data);
$g->add_dataset(@data1);
my @legend_keys = ( "Actual ", "Goal" );
$g->set(
colors => { dataset0 => [ 25, 220, 147 ], },
graph_border => 0,
grey_background => 'false',
grid_lines => 'true',
include_zero => 'true',
# integer_ticks_only => 'true',
legend => 'none',
png_border => 4,
precision => 1,
skip_int_ticks => 1000,
text_space => 3,
title => "Tickets",
title_font => GD::Font->Giant,
transparent => 'false',
x_ticks => 'vertical',
y_axes => 'both',
y_label => '# Tickets',
t/composite.t view on Meta::CPAN
print "1..1\n";
$g = Chart::Composite->new();
$g->add_dataset( 'foo', 'bar', 'junk', 'whee' );
$g->add_dataset( 3, 4, 9, 10 );
$g->add_dataset( 8, 6, 1, 11 );
$g->add_dataset( 5, 7, 2, 12 );
$g->add_dataset( 2, 5, 7, 2 );
$g->set( 'legend' => 'left' );
$g->set(
'title' => 'Composite Chart',
'composite_info' => [ [ 'Bars', [ 1, 2 ] ], [ 'LinesPoints', [ 3, 4 ] ] ]
);
$g->set( 'y_label' => 'y label 1', 'y_label2' => 'y label 2' );
$g->set(
'colors' => {
'y_label' => [ 0, 0, 255 ],
y_label2 => [ 0, 255, 0 ],