1package Chart::Clicker::Decoration::Legend::Tabular; 2$Chart::Clicker::Decoration::Legend::Tabular::VERSION = '2.90'; 3use Moose; 4 5extends 'Chart::Clicker::Decoration::Legend'; 6 7# ABSTRACT: Tabular version of Legend 8 9use Graphics::Primitive::Font; 10use Graphics::Primitive::Insets; 11use Graphics::Primitive::TextBox; 12use Graphics::Color::RGB; 13 14use Layout::Manager::Grid; 15 16 17has '+border' => ( 18 default => sub { 19 my $b = Graphics::Primitive::Border->new; 20 $b->color(Graphics::Color::RGB->new( red => 0, green => 0, blue => 0)); 21 $b->width(1); 22 return $b; 23 } 24); 25 26 27has '+color' => ( 28 default => sub { Graphics::Color::RGB->new( red => 0, green => 0, blue => 0) } 29); 30 31 32has 'data' => ( 33 is => 'rw', 34 isa => 'ArrayRef[ArrayRef[Str]]', 35 required => 1 36); 37 38 39has 'font' => ( 40 is => 'rw', 41 isa => 'Graphics::Primitive::Font', 42 default => sub { 43 Graphics::Primitive::Font->new 44 } 45); 46 47 48has 'header' => ( 49 is => 'rw', 50 isa => 'ArrayRef[Str]', 51 predicate => 'has_header' 52); 53 54 55has 'item_padding' => ( 56 is => 'rw', 57 isa => 'Graphics::Primitive::Insets', 58 default => sub { 59 Graphics::Primitive::Insets->new({ 60 top => 3, left => 3, bottom => 3, right => 5 61 }) 62 } 63); 64has '+layout_manager' => ( 65 default => sub { 66 my $self = shift; 67 my $header_rows = $self->has_header ? 1 : 0; 68 return Layout::Manager::Grid->new( 69 rows => scalar(@{ $self->data }) + $header_rows, 70 columns => scalar(@{ $self->data->[0] }) + 1 71 ); 72 }, 73 lazy => 1 74); 75 76override('prepare', sub { 77 my ($self, $driver) = @_; 78 79 return if $self->component_count > 0; 80 81 my $ca = $self->clicker->color_allocator; 82 83 my $font = $self->font; 84 85 my $ii = $self->item_padding; 86 87 if($self->is_vertical) { 88 # This assumes you aren't changing the layout manager... 89 $self->layout_manager->anchor('north'); 90 } 91 92 my $row_offset = 0; 93 if($self->has_header) { 94 $row_offset = 1; 95 my $count = 0; 96 # foreach my $d (@{ $self->header }) { 97 for(0..scalar(@{ $self->header }) - 1) { 98 $self->add_component( 99 Graphics::Primitive::TextBox->new( 100 color => $self->color, 101 font => $font, 102 padding => $ii, 103 text => $self->header->[$_] 104 ), 105 { row => 0, column => $_ } 106 ); 107 $count++; 108 } 109 } 110 111 my @data = @{ $self->data }; 112 113 my $count = 0; 114 foreach my $ds (@{ $self->clicker->datasets }) { 115 foreach my $s (@{ $ds->series }) { 116 117 my $color = $ca->next; 118 119 unless($s->has_name) { 120 $s->name("Series $count"); 121 } 122 123 my $tb = Graphics::Primitive::TextBox->new( 124 color => $color, 125 font => $font, 126 padding => $ii, 127 text => $s->name 128 ); 129 130 $self->add_component($tb, { row => $count + $row_offset, column => 0 }); 131 132 for(0..scalar(@{ $data[$count] }) - 1) { 133 $self->add_component( 134 Graphics::Primitive::TextBox->new( 135 color => $color, 136 font => $font, 137 padding => $ii, 138 text => $data[$count]->[$_] 139 ), 140 { row => $count + $row_offset, column => $_ + 1 } 141 ); 142 } 143 144 $count++; 145 } 146 } 147 148 super; 149 150 $ca->reset; 151}); 152 153__PACKAGE__->meta->make_immutable; 154 155no Moose; 156 1571; 158 159__END__ 160 161=pod 162 163=head1 NAME 164 165Chart::Clicker::Decoration::Legend::Tabular - Tabular version of Legend 166 167=head1 VERSION 168 169version 2.90 170 171=head1 SYNOPSIS 172 173 my $cc = Chart::Clicker->new; 174 175 my $series1 = Chart::Clicker::Data::Series->new; 176 my $series2 = Chart::Clicker::Data::Series->new; 177 178 $cc->legend(Chart::Clicker::Decoration::Legend::Tabular->new( 179 header => [ qw(Name Min Max) ], 180 data => [ 181 [ min(@{ $series1->values }), max(@{ $series1->values }) ], 182 [ min(@{ $series2->values }), max(@{ $series2->values }) ] 183 ] 184 )); 185 186=head1 DESCRIPTION 187 188Chart::Clicker::Decoration::Legend::Tabular draws a legend on a Chart with 189tabular data display. 190 191The Tabular legend is a legend with a few extra attributes that allow you to 192pass it data to display. The attributes are c<header> and c<data>. The 193C<header> (optional) allows you to specify the strings to display at the top 194of the table and the C<data> attribute allows you to pass in arrayrefs of 195strings for display aside each of the series. 196 197B<Note>: The first string in the C<header> arrayref should be the header for 198the column above the name of the series. This code does not do anything 199to verify that you've given the appropriate counts of data. It is expected 200that you will provide C<data> with one arrayref for every series, each 201containing n elements. Having that, C<header> will expect n + 1 elements 202with one for the series name and the remaining (n) matching the number of 203elements in each of C<data>'s arrayrefs. 204 205=head1 ATTRIBUTES 206 207=head2 border 208 209Set/Get this Legend's L<border|Graphics::Primitive::Border>. 210 211=head2 color 212 213Set/Get the L<color|Graphics::Color::RGB> to use as the foreground for the legend. 214 215=head2 data 216 217Set/Get the data for this legend. Expects an arrayref of arrayrefs, with 218one inner arrayref for every series charted. 219 220=head2 font 221 222Set/Get the L<font|Graphics::Primitive::Font> used for this legend's items. 223 224=head2 header 225 226Set/Get the header data used for this legend. Expects an arrayref of Strings. 227 228=head2 insets 229 230Set/Get this Legend's insets. 231 232=head2 item_padding 233 234Set/Get the L<padding|Graphics::Primitive::Insets> for this legend's items. 235 236=head1 METHODS 237 238=head2 has_header 239 240Predicate returning true of this legend has a header, else 1. 241 242=head1 AUTHOR 243 244Cory G Watson <gphat@cpan.org> 245 246=head1 COPYRIGHT AND LICENSE 247 248This software is copyright (c) 2016 by Cory G Watson. 249 250This is free software; you can redistribute it and/or modify it under 251the same terms as the Perl 5 programming language system itself. 252 253=cut 254