package Lire::Report::ColumnInfo;
use strict;
use Carp;
use POSIX qw/ ceil /;
use Lire::DataTypes qw/ check_type check_xml_name /;
use Lire::Utils qw/ check_param check_object_param /;
=pod
=head1 NAME
Lire::Report::ColumnInfo - Object that holds column meta-data.
=head1 SYNOPSIS
my $info = $subreport->column_info_by_idx( 0 );
print "Column's name: ", $info->name(), "\n";
print "Column's index: ", $info->index(), "\n";
print "Column's type: ", $info->type(), "\n";
print "Column's label: ", $info->label(), "\n";
=head1 DESCRIPTION
The Lire::Report::ColumnInfo object contains meta-data information on
the columns of a subreport.
=head1 CONSTRUCTOR
=head2 new( $group, $name, $class, $type, [$label]])
Creates a new Lire::Report::ColumnInfo object. The column info
attributes are initialized based on $name, $class, $type and $label.
=cut
sub new {
my ( $class, $group, $name, $type_class, $type, $label ) = @_;
check_object_param( $group, 'group_info', 'Lire::Report::GroupInfo' );
check_param( $name, 'name', \&check_xml_name,
"'name' parameter isn't a valid XML name" );
check_param( $type_class, 'class', qr/^(numerical|categorical)$/,
"'class' parameter should either be 'numerical' or 'categorical'" );
check_param( $type, 'type', \&check_type,
"'type' parameter isn't a valid Lire type" );
my $self = bless {
'name' => $name,
'class' => $type_class,
'type' => $type,
'col_width' => 0,
'max_chars' => undef,
'avg_chars' => undef,
'padding' => 0,
'index' => undef,
'group_info' => $group,
}, $class;
$self->label( $label )
if ( defined $label );
return $self;
}
=pod
=head1 OBJECT METHODS
=pod
=head2 name()
Returns the name of this column. This name can be used to find the
group operation (from the report specification) that is responsible
for the column's content.
=cut
sub name {
return $_[0]{'name'};
}
=pod
=head2 class()
Returns the column's class of data. This will be either 'numerical' or
'categorical'.
=cut
sub class {
return $_[0]{'class'};
}
=pod
=head2 type()
Returns the column's type. This referes to the type of the DLF field
that was usd to generate this column's values.
=cut
sub type {
return $_[0]{'type'};
}
=pod
=head2 group_info()
Returns the GroupInfo object which contains this column.
=cut
sub group_info {
return $_[0]{'group_info'};
}
=pod
=head2 index()
Returns the column's index in the table. This will be undef until the
column info object is added to a Lire::Subreport or Lire::Group
object.
=cut
sub index {
$_[0]{'index'} = $_[1] if @_ == 2;
return $_[0]{'index'};
}
=pod
=head2 col_start()
Returns the display column which is the start of the cell span that
should be used to render this column's values.
=cut
sub col_start {
$_[0]{'col_start'} = $_[1] if @_ == 2;
return $_[0]{'col_start'};
}
=pod
=head2 col_end()
Returns the display column which is the end of the cell span that
should be used to render this column's values.
=cut
sub col_end {
$_[0]{'col_end'} = $_[1] if @_ == 2;
return $_[0]{'col_end'};
}
=pod
=head2 col_width()
Returns the suggested column width for this column in characters.
=cut
sub col_width {
$_[0]{'col_width'} = $_[1] if @_ == 2;
return $_[0]{'col_width'};
}
=pod
=head2 max_chars()
This method returns the length of the longest string in that column
(including the label).
=cut
sub max_chars {
my $self = $_[0];
$self->{'max_chars'} = $_[1] if @_ == 2;
croak "max_chars() called while stat is undefined. Was subreport's finalize() called?"
unless defined $self->{'max_chars'};
return $self->{'max_chars'};
}
=pod
=head2 avg_chars()
This method returns the average length of strings in that column
(including the label). This will be round up to the next integer (1.3
-> 2).
=cut
sub avg_chars {
my $self = $_[0];
$self->{'avg_chars'} = $_[1] if @_ == 2;
croak "avg_chars() called while stat is undefined. Was subreport's finalize() called?"
unless defined $self->{'avg_chars'};
return $self->{'avg_chars'};
}
sub init_chars_stats {
my ( $self ) = @_;
$self->{'total_chars'} = 0;
$self->{'column_count'} = 0;
$self->{'max_chars'} = length( $self->label() );
return;
}
sub update_chars_stats {
my ( $self, $value ) = @_;
my $len = length $value;
$self->{'total_chars'} += $len;
$self->{'column_count'}++;
$self->{'max_chars'} = $len
if $len > $self->{'max_chars'};
return;
}
sub finish_chars_stats {
my $self = $_[0];
my $len = length $self->label();
$self->{'avg_chars'} = ceil( ($self->{'total_chars'} + $len) /
($self->{'column_count'} + 1) );
delete $self->{'total_chars'};
delete $self->{'column_count'};
return;
}
=pod
=head2 label( [$label] )
Returns the column's label. If the $label parameter is defined, the
column's label will be set to this new value.
=cut
sub label {
my ( $self, $label ) = @_;
$self->{'label'} = $label
if ( @_ == 2 );
return ( $self->{'label'} ? $self->{'label'} : $self->{'name'} );
}
sub write_report {
my ( $self, $fh, $indent ) = @_;
$fh ||= *STDOUT;
my $pfx = ' ' x $indent;
print $fh $pfx, qq{<lire:column-info name="$self->{'name'}" class="$self->{'class'}" type="$self->{'type'}"};
print $fh qq{ col-start="$self->{'col_start'}" col-end="$self->{'col_end'}" col-width="$self->{'col_width'}"};
print $fh qq{ label="$self->{'label'}"}
if $self->{'label'};
print $fh qq{ max-chars="$self->{'max_chars'}" avg-chars="},
$self->avg_chars, qq{"/>\n};
return;
}
#------------------------------------------------------------------------
# Method delete()
#
# Remove circular references
sub delete {
my ( $self ) = @_;
%$self = ();
return;
}
# keep perl happy
1;
__END__
=pod
=head1 SEE ALSO
Lire::Report::Subreport(3pm) Lire::Report::GroupInfo(3pm)
=head1 VERSION
$Id: ColumnInfo.pm,v 1.15 2006/07/23 13:16:31 vanbaal Exp $
=head1 COPYRIGHT
Copyright (C) 2002 Stichting LogReport Foundation LogReport@LogReport.org
This file is part of Lire.
Lire is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program (see COPYING); if not, check with
http://www.gnu.org/copyleft/gpl.html.
=head1 AUTHOR
Francis J. Lacoste <flacoste@logreport.org>
=cut
syntax highlighted by Code2HTML, v. 0.9.1