/usr/local/CPAN/CGIGraph/CGI/Graph/Plot/bars/string.pm
package CGI::Graph::Plot::bars::string;
use CGI::Graph::Plot::bars;
@ISA = ("CGI::Graph::Plot::bars");
my %default = (label_size => 12,
max_x_values => 50);
sub new {
my ($pkg, $vars) = @_;
my $class = ref($pkg) || $pkg;
my $self=$class->SUPER::new($vars);
if ($self->{rand}) {
return bless $self,$class;
}
$self->graphBounds;
if ($self->{select} || $self->{select_list} eq 'Visible' || $self->{unselect_list} eq 'Visible') {
my @selected = split("",$self->{selected});
my @row = $self->{table}->col('_row');
my ($Xref) = $self->valuesInRange();
my @X = @$Xref;
# obtain X value for selected bar
my $X1 = ($self->{select})?$X[$self->{select}-1]:$X[0];
my $X2 = ($self->{select})?$X[$self->{select}-1]:$X[-1];
# update selection values for selected elements
foreach (0..$self->{table}->nofRow()-1) {
last if ($self->{table}->elm($_,$self->{X}) gt $X2);
if ($self->{table}->elm($_,$self->{X}) ge $X1) {
if ($self->{select}) {
$selected[$row[$_]-1] =
($self->{select_type} eq 'select')?1:0;
}
else {
$selected[$row[$_]-1] =
($self->{select_list} eq 'Visible')?1:0;
}
}
}
$self->{selected} = join("",@selected);
$self->write_selected();
}
return bless $self,$class;
}
sub count{
my $self = shift;
my @S = $self->{table}->col($self->{X});
my @X = $S[0];
my @Y = (1); # represents number of X values at index
# count number of identical X values
for ($i=1; $i < scalar(@S); $i++) {
# X different than previous
if ($S[$i] ne $S[$i-1]) {
push @X, $S[$i];
push @Y, 1;
}
# same as previous X
else {
$Y[$#Y]++;
}
}
return (\@X,\@Y);
}
sub valuesInRange {
my $self = shift;
my $max_x_values = shift || $default{max_x_values};
my @row = $self->{table}->col('_row');
my @selected = split("",$self->{selected});
my ($Xref,$Yref) = $self->count;
my @X = @$Xref;
my @Y = @$Yref;
my (@dataX,@dataY,@selectDraw);
my $last=0;
my $count=0; # number of bars
# determine which values are in range
for ($i=0; $i<=$#X; $i++) {
if ( (($i+1)/($#X+2) >= $self->{x_min}) &&
(($i+1)/($#X+2) <= $self->{x_max}) ) {
push (@dataX, $X[$i]);
push (@dataY, $Y[$i]);
# find first occurrence of x label
for ($first=$last; $first<$self->{table}->nofRow;
$first++) {
last if ($X[$i] eq
$self->{table}->elm($first,$self->{X}));
}
# determine number of selected elements in this bar
for ($row=$first; $row < scalar(@selected); $row++) {
last if ($self->{table}->elm($row,$self->{X})
ne $X[$i]);
if ($selected[$row[$row]-1] == 1) {
$selectDraw[$count]++;
}
}
$last=$first;
$count++;
}
}
# avoid returning more X values than can be handled
if ($#dataX > $max_x_values) {
my (@tempX,@tempY,@tempS);
for ($i=0; $i<=$#dataX; $i+=($#dataX/$max_x_values)) {
push(@tempX,$dataX[$i]);
push(@tempY,$dataY[$i]);
push(@tempS,$selectDraw[$i]);
}
@dataX = @tempX;
@dataY = @tempY;
@selectDraw = @tempS;
}
# shorten labels
foreach (0..$#dataX) {
$drawX[$_] = sprintf("%.".$default{label_size}."s",$dataX[$_]);
}
return (\@dataX,\@drawX,\@dataY,\@selectDraw);
}
1;