Ready for 7.10.29 development.
This commit is contained in:
commit
c806f99b7b
4236 changed files with 1217679 additions and 0 deletions
426
lib/WebGUI/Image/Graph/XYGraph/Bar.pm
Normal file
426
lib/WebGUI/Image/Graph/XYGraph/Bar.pm
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
package WebGUI::Image::Graph::XYGraph::Bar;
|
||||
|
||||
use strict;
|
||||
use WebGUI::Image::Graph::XYGraph;
|
||||
use List::Util;
|
||||
use POSIX;
|
||||
use WebGUI::Utility;
|
||||
|
||||
our @ISA = qw(WebGUI::Image::Graph::XYGraph);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Image::Graph::XYGraph::Bar
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Package for creating bar graphs.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
This package privides the logic for drawing 2d bar graphs, 3d bars are in the
|
||||
pipeline but not yet ready for prime time.
|
||||
|
||||
This module can draw bar graph in two forms: Stacked and Side by Side. The
|
||||
diffrence is noticable only if more multiple dataset is used, the behaviour is
|
||||
thus identical in case of one dataset.
|
||||
|
||||
Stacked graphs place the bars belonging the same index within diffrent datasets
|
||||
on top of each other given a grand total for all datasets.
|
||||
|
||||
Sid by side graphs place bars with the same index next to each other, grouped by
|
||||
index. This displays a better comaprison between datasets.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
These methods are available from this class:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 configurationForm
|
||||
|
||||
Creates the configuration form for this plugin. See WebGUI::Image::Graph for
|
||||
more information.
|
||||
|
||||
=cut
|
||||
|
||||
sub configurationForm {
|
||||
my $self = shift;
|
||||
|
||||
my $i18n = WebGUI::International->new($self->session, 'Image_Graph_XYGraph_Bar');
|
||||
|
||||
my $configForms = $self->SUPER::configurationForm;
|
||||
my $f = WebGUI::HTMLForm->new($self->session);
|
||||
$f->trClass('Graph_XYGraph_Bar');
|
||||
$f->float(
|
||||
name => 'xyGraph_bar_barSpacing',
|
||||
value => $self->getBarSpacing,
|
||||
label => $i18n->get('bar spacing'),
|
||||
hoverHelp => $i18n->get('bar spacing description'),
|
||||
);
|
||||
$f->float(
|
||||
name => 'xyGraph_bar_groupSpacing',
|
||||
value => $self->getGroupSpacing,
|
||||
label => $i18n->get('group spacing'),
|
||||
hoverHelp => $i18n->get('group spacing description'),
|
||||
);
|
||||
|
||||
$configForms->{'graph_xygraph_bar'} = $f->printRowsOnly;
|
||||
|
||||
return $configForms;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 drawBar ( bar, location, barWidth )
|
||||
|
||||
Draws a bar defined by bar and with width barWidth at location.
|
||||
|
||||
=head3 bar
|
||||
|
||||
A hashref defining the bar. Must contain keys 'height', 'strokeColor' and
|
||||
'fillColor'.
|
||||
|
||||
=head3 location
|
||||
|
||||
A hashref containing the location of the bottom-left corner of the bar. Keys 'x'
|
||||
and 'y' must specify the x- and y-coordinates respectively.
|
||||
|
||||
=head3 barWidth
|
||||
|
||||
The width of the bar in pixels.
|
||||
|
||||
=cut
|
||||
|
||||
sub drawBar {
|
||||
my $self = shift;
|
||||
my $bar = shift;
|
||||
my $location = shift;
|
||||
my $barWidth = shift;
|
||||
|
||||
my $barHeight = $bar->{height} * $self->getPixelsPerUnit;
|
||||
|
||||
$self->image->Draw(
|
||||
primitive => 'Path',
|
||||
stroke => $bar->{strokeColor},
|
||||
points =>
|
||||
" M ".$location->{x}.",".$location->{y}.
|
||||
" L ".$location->{x}.",".($location->{y}-$barHeight).
|
||||
" L ".($location->{x}+$barWidth).",".($location->{y}-$barHeight).
|
||||
" L ".($location->{x}+$barWidth).",".$location->{y},
|
||||
fill => $bar->{fillColor},
|
||||
);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 drawGraph
|
||||
|
||||
Draws all the bars.
|
||||
|
||||
=cut
|
||||
|
||||
sub drawGraph {
|
||||
my %location;
|
||||
my $self = shift;
|
||||
|
||||
$self->processDataSet;
|
||||
|
||||
my $numberOfGroups = List::Util::max(map {scalar @$_} @{$self->{_datasets}});
|
||||
my $numberOfDatasets = scalar @{$self->{_datasets}};
|
||||
my $groupWidth = ($self->getChartWidth - ($numberOfGroups-1) * $self->getGroupSpacing) / $numberOfGroups;
|
||||
|
||||
my $barWidth = $groupWidth;
|
||||
$barWidth = ($groupWidth - ($numberOfDatasets - 1) * $self->getBarSpacing) / $numberOfDatasets if ($self->getDrawMode eq 'sideBySide');
|
||||
|
||||
$location{x} = $self->getChartOffset->{x} ;
|
||||
$location{y} = $self->getChartOffset->{y} + $self->getChartHeight;
|
||||
foreach my $currentBar (@{$self->{_bars}}) {
|
||||
if ($self->getDrawMode eq 'stacked') {
|
||||
$self->drawStackedBar($currentBar, \%location, $barWidth);
|
||||
} else {
|
||||
$self->drawSideBySideBar($currentBar, \%location, $barWidth);
|
||||
}
|
||||
|
||||
$location{x} += $groupWidth + $self->getGroupSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 drawSideBySideBar ( bars, location, barWidth )
|
||||
|
||||
Draws the bars in side by side mode. Meaning that per datsetindex the bars
|
||||
representing a single dataset are grouped.
|
||||
|
||||
=head3 bars
|
||||
|
||||
An arrayref containing all the bar description hashrefs as described in drawBar.
|
||||
|
||||
=head3 location
|
||||
|
||||
Hashref containing the initial coordinates of the lower-left corner of the
|
||||
chart. Pass coords in keys 'x' and 'y'.
|
||||
|
||||
=head3 barWidth
|
||||
|
||||
The width of each bar in pixels.
|
||||
|
||||
=cut
|
||||
|
||||
sub drawSideBySideBar {
|
||||
my $self = shift;
|
||||
my $bars = shift;
|
||||
my $location = shift;
|
||||
my $barWidth = shift;
|
||||
|
||||
my %thisLocation = %$location;
|
||||
|
||||
foreach (@$bars) {
|
||||
$self->drawBar($_, \%thisLocation, $barWidth);
|
||||
$thisLocation{x} += $barWidth + $self->getBarSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 drawStackedBar ( bars, location, barWidth )
|
||||
|
||||
Draws the bars in side by side mode. Meaning that per datset-index the bars
|
||||
representing a single dataset are stacked on top of each other.
|
||||
|
||||
=head3 bars
|
||||
|
||||
An arrayref containing all the bar description hashrefs as described in drawBar.
|
||||
|
||||
=head3 location
|
||||
|
||||
Hashref containing the initial coordinates of the lower-left corner of the
|
||||
chart. Pass coords in keys 'x' and 'y'.
|
||||
|
||||
=head3 barWidth
|
||||
|
||||
The width of each bar in pixels.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
sub drawStackedBar {
|
||||
my $self = shift;
|
||||
my $bars = shift;
|
||||
my $location = shift;
|
||||
my $barWidth = shift;
|
||||
|
||||
my %thisLocation = %$location;
|
||||
foreach (@$bars) {
|
||||
$self->drawBar($_, \%thisLocation, $barWidth);
|
||||
$thisLocation{y} -= $_->{height} * $self->getPixelsPerUnit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 formNamespace
|
||||
|
||||
Returns the form namespace of this plugin. See WegBUI::Image::Graph for
|
||||
more elaborate information.
|
||||
|
||||
=cut
|
||||
|
||||
sub formNamespace {
|
||||
my $self = shift;
|
||||
|
||||
return $self->SUPER::formNamespace.'_Bar';
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getAnchorSpacing
|
||||
|
||||
Returns the distance in pixels between two anchors on the x axis that define teh
|
||||
placement of bars and labels.
|
||||
|
||||
=cut
|
||||
|
||||
sub getAnchorSpacing {
|
||||
my $self = shift;
|
||||
|
||||
my $numberOfGroups = List::Util::max(map {scalar @$_} @{$self->getDataset});
|
||||
|
||||
my $spacing = round(($self->getChartWidth - ($numberOfGroups-1) * $self->getGroupSpacing) / $numberOfGroups + $self->getGroupSpacing);
|
||||
|
||||
return {
|
||||
x => $spacing,
|
||||
y => 0,
|
||||
};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getBarSpacing
|
||||
|
||||
Returns the width of the gap between two bars within a group in pixels.
|
||||
|
||||
=cut
|
||||
|
||||
sub getBarSpacing {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{_barProperties}->{barSpacing} || 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getConfiguration
|
||||
|
||||
Returns the configuration hashref for this plugin. Refer to WebGUI::IMage::Graph
|
||||
for a more detailed description.
|
||||
|
||||
=cut
|
||||
|
||||
sub getConfiguration {
|
||||
my $self = shift;
|
||||
|
||||
my $config = $self->SUPER::getConfiguration;
|
||||
|
||||
$config->{xyGraph_bar_barSpacing} = $self->getBarSpacing;
|
||||
$config->{xyGraph_bar_groupSpacing} = $self->getGroupSpacing;
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getGroupSpacing
|
||||
|
||||
Returns the width of the gap between two groups of bars in pixels.
|
||||
|
||||
=cut
|
||||
|
||||
sub getGroupSpacing {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{_barProperties}->{groupSpacing} || $self->getBarSpacing;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getFirstAnchorLocation
|
||||
|
||||
Returns a hashref containing the location of the leftmost x-axis anchor.
|
||||
Location coordinates are encoded in keys 'x' and 'y'.
|
||||
|
||||
=cut
|
||||
|
||||
sub getFirstAnchorLocation {
|
||||
my $self = shift;
|
||||
|
||||
return {
|
||||
x => round($self->getChartOffset->{x} + ($self->getAnchorSpacing->{x} - $self->getGroupSpacing) / 2),
|
||||
y => $self->getChartOffset->{y} + $self->getChartHeight
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 processDataSet
|
||||
|
||||
Processes the dataset. Used by drawGraph.
|
||||
|
||||
=cut
|
||||
|
||||
sub processDataSet {
|
||||
my ($barProperties);
|
||||
my $self = shift;
|
||||
|
||||
my $palette = $self->getPalette;
|
||||
|
||||
my $maxElements = List::Util::max(map {scalar @$_} @{$self->{_datasets}});
|
||||
my $numberOfDatasets = scalar @{$self->{_datasets}};
|
||||
|
||||
for my $currentElement (0 .. $maxElements-1) {
|
||||
my @thisSet = ();
|
||||
for my $currentDataset (0 .. $numberOfDatasets - 1) {
|
||||
my $color = $palette->getColor($currentDataset);
|
||||
if ($numberOfDatasets == 1) {
|
||||
$color = $palette->getNextColor;
|
||||
}
|
||||
push(@thisSet, {
|
||||
height => $self->{_datasets}->[$currentDataset]->[$currentElement] || 0,
|
||||
fillColor => $color->getFillColor,
|
||||
strokeColor => $color->getStrokeColor,
|
||||
});
|
||||
}
|
||||
push(@{$self->{_bars}}, [ @thisSet ]);
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 setBarSpacing ( gap )
|
||||
|
||||
Sets the distance between two bars in a group in pixels.
|
||||
|
||||
=head3 gap
|
||||
|
||||
The distance in pixels.
|
||||
|
||||
=cut
|
||||
|
||||
sub setBarSpacing {
|
||||
my $self = shift;
|
||||
my $gap = shift;
|
||||
|
||||
$self->{_barProperties}->{barSpacing} = $gap;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 setConfiguration ( config )
|
||||
|
||||
Applies the given configuration hash to this plugin. See WebGUI::Image::Graph
|
||||
for more info.
|
||||
|
||||
=head3 config
|
||||
|
||||
The configuration hash.
|
||||
|
||||
=cut
|
||||
|
||||
sub setConfiguration {
|
||||
my $self = shift;
|
||||
my $config = shift;
|
||||
|
||||
$self->SUPER::setConfiguration($config);
|
||||
|
||||
$self->setBarSpacing($config->{xyGraph_bar_barSpacing});
|
||||
$self->setGroupSpacing($config->{xyGraph_bar_groupSpacing});
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 setGroupSpacing ( gap )
|
||||
|
||||
Sets the distance between two groups of bars in pixels.
|
||||
|
||||
=head3 gap
|
||||
|
||||
The distance in pixels.
|
||||
|
||||
=cut
|
||||
|
||||
sub setGroupSpacing {
|
||||
my $self = shift;
|
||||
my $gap = shift;
|
||||
|
||||
$self->{_barProperties}->{groupSpacing} = $gap;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
184
lib/WebGUI/Image/Graph/XYGraph/Line.pm
Normal file
184
lib/WebGUI/Image/Graph/XYGraph/Line.pm
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
package WebGUI::Image::Graph::XYGraph::Line;
|
||||
|
||||
use strict;
|
||||
use WebGUI::Image::Graph::XYGraph;
|
||||
use List::Util;
|
||||
use POSIX;
|
||||
|
||||
our @ISA = qw(WebGUI::Image::Graph::XYGraph);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Image::Graph::XYGraph::Line
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Package for creating line graphs.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
This package privides the logic for drawing 2d line graphs, 3d lines are in the
|
||||
pipeline but not yet ready for prime time.
|
||||
|
||||
The possibilities are quite limited for now but will be enhanced upon in the future.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
These methods are available from this class:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 drawGraph
|
||||
|
||||
Draws all the lines.
|
||||
|
||||
=cut
|
||||
|
||||
sub drawGraph {
|
||||
my ($currentBar, %location);
|
||||
my $self = shift;
|
||||
|
||||
$self->processDataSet;
|
||||
|
||||
my $numberOfGroups = List::Util::max(map {scalar @$_} @{$self->{_datasets}});
|
||||
my $interval = $self->getChartWidth / ($numberOfGroups - 1);
|
||||
|
||||
%location = %{$self->getChartOffset};
|
||||
$location{y} += $self->getChartHeight;
|
||||
|
||||
foreach (@{$self->{_lines}}) {
|
||||
$self->drawLine($_, \%location, $interval);
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 drawLine ( line, location, interval )
|
||||
|
||||
Draws a bar defined by bar and with width barWidth at location.
|
||||
|
||||
=head3 line
|
||||
|
||||
A hashref defining the line. Must contain keys 'strokeColor' and
|
||||
'dataset', the latter one being an arrayref containing all points of the line.
|
||||
|
||||
=head3 location
|
||||
|
||||
A hashref containing the location of the bottom-left corner of the line's
|
||||
origin. Keys 'x' and 'y' must specify the x- and y-coordinates respectively.
|
||||
|
||||
=head3 interval
|
||||
|
||||
The distance between x-axis anchors in pixels.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
sub drawLine {
|
||||
my $self = shift;
|
||||
my $line = shift;
|
||||
my $location = shift;
|
||||
my $interval = shift;
|
||||
|
||||
my %currentLocation = %$location;
|
||||
|
||||
|
||||
my $dataCounter;
|
||||
my $path;# = " M ".$currentLocation{x}.",".$currentLocation{y};
|
||||
foreach (@{$line->{dataset}}) {
|
||||
$path .= ($dataCounter++) ? " L " : " M ";
|
||||
$path .= $currentLocation{x}.",".($currentLocation{y} - $_*$self->getPixelsPerUnit);
|
||||
|
||||
$currentLocation{x} += $interval;
|
||||
}
|
||||
|
||||
$self->image->Draw(
|
||||
primitive => 'Path',
|
||||
stroke => $line->{strokeColor},
|
||||
points => $path,
|
||||
fill => 'none',
|
||||
);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 formNamespace
|
||||
|
||||
Returns the form namespace of this plugin. See WegBUI::Image::Graph for
|
||||
more elaborate information.
|
||||
|
||||
=cut
|
||||
|
||||
sub formNamespace {
|
||||
my $self = shift;
|
||||
|
||||
return $self->SUPER::formNamespace.'_Line';
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getAnchorSpacing
|
||||
|
||||
Returns the distance in pixels between two anchors on the x axis that define teh
|
||||
placement of bars and labels.
|
||||
|
||||
=cut
|
||||
|
||||
sub getAnchorSpacing {
|
||||
my $self = shift;
|
||||
|
||||
my $numberOfGroups = List::Util::max(map {scalar @$_} @{$self->getDataset});
|
||||
|
||||
my $spacing = $self->getChartWidth / ($numberOfGroups - 1);
|
||||
|
||||
return {
|
||||
x => $spacing,
|
||||
y => 0,
|
||||
};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getFirstAnchorLocation
|
||||
|
||||
Returns a hashref containing the location of the leftmost x-axis anchor.
|
||||
Location coordinates are encoded in keys 'x' and 'y'.
|
||||
|
||||
=cut
|
||||
|
||||
sub getFirstAnchorLocation {
|
||||
my $self = shift;
|
||||
|
||||
return {
|
||||
x => $self->getChartOffset->{x},
|
||||
y => $self->getChartOffset->{y} + $self->getChartHeight
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 processDataSet
|
||||
|
||||
Processes the dataset. Used by drawGraph.
|
||||
|
||||
=cut
|
||||
|
||||
sub processDataSet {
|
||||
my ($barProperties);
|
||||
my $self = shift;
|
||||
|
||||
my $palette = $self->getPalette;
|
||||
foreach (@{$self->{_datasets}}) {
|
||||
push (@{$self->{_lines}}, {
|
||||
dataset => $_,
|
||||
strokeColor => $palette->getColor->getStrokeColor,
|
||||
});
|
||||
$palette->getNextColor;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue