File Coverage

blib/lib/Catalyst/View/Chart/Strip.pm
Criterion Covered Total %
statement 15 50 30.0
branch 0 12 0.0
condition 0 10 0.0
subroutine 5 7 71.4
pod 2 2 100.0
total 22 81 27.1


line stmt bran cond sub pod time code
1             package Catalyst::View::Chart::Strip;
2              
3 1     1   934 use strict;
  1         3  
  1         50  
4 1     1   6 use base qw/Catalyst::View/;
  1         3  
  1         754  
5 1     1   1103 use UNIVERSAL::require;
  1         2060  
  1         12  
6 1     1   30 use Carp;
  1         2  
  1         65  
7 1     1   1969 use NEXT;
  1         5797  
  1         17  
8              
9             our $VERSION = '0.05';
10              
11             =head1 NAME
12              
13             Catalyst::View::Chart::Strip - A Catalyst View for Chart::Strip graphics
14              
15             =head1 SYNOPSIS
16              
17             package MyApp::View::ChartStrip;
18              
19             use strict;
20             use base 'Catalyst::View::Chart::Strip';
21              
22             __PACKAGE__->config(
23             cs_package => 'Chart::Strip',
24             height => 192,
25             width => 720,
26             limit_factor => 1,
27             transparent => 0,
28             img_type => 'png',
29             palette => [qw/
30             FF0000
31             00CC00
32             0000FF
33             CC00CC
34             /],
35             );
36              
37             1;
38              
39             # A controller method which generates a chart:
40             sub thechart : Local {
41             my ( $self, $c ) = @_;
42              
43             [ ... generate $data and $opts somehow or other ... ]
44             $c->stash->{chart_opts} = $opts;
45             $c->stash->{chart_data} = $data;
46             $c->forward('MyApp::View::ChartStrip');
47             }
48              
49             =head1 DESCRIPTION
50              
51             This view allows the serving of Chart::Strip stripchart graphics
52             via Catalyst. The raw numeric data and various chart options are
53             placed in C<$c-Estash>.
54              
55             Instances of L, like
56             C shown in the synopsis above, can be thought
57             of as basically a collection of common defaults for the various chart
58             options. You should probably create a seperate View class for each
59             distinct style of charts your application commonly generates.
60              
61             All of the standard constructor arguments documented by L
62             are supported as C<-Econfig> parameters in your View class, and are
63             also overrideable at chart generation time via
64             C<$c-Estash-E{chart_opts}>.
65              
66             L adds a few new options in addition to
67             the ones that are standard in L, which are detailed below.
68              
69             =head1 CONFIGURATION PARAMETERS
70              
71             (See L for a complete list of options. Any L
72             option can be passed through as a C<-Econfig> parameter).
73              
74             All of these options are valid both a C<-Econfig> time, or at chart
75             generation time via C<$c-Estash-E{chart_opts}>.
76              
77             =head2 img_type
78              
79             Sets the output image type. Values currently supported by L
80             and L beneath it are C and C. The default is C if
81             unspecified.
82              
83             =head2 quality
84              
85             This is the quality parameter for the output graphics data, as documented
86             in detail by L's documentation. Valid quality ranges are 0-100 for
87             C and 0-9 for C. Completely optional, and defaults to a
88             reasonably normal value in both cases.
89              
90             =head2 palette
91              
92             An optional arrayref of colors as six-digit hexidecimal strings, like
93             C or C<4A5C2D>. The various datasets in your graph will be
94             colored with the colors of this array in order, recycling to the top
95             of the list if there are more data items than colors specified. The default
96             is a reasonable 9-color high-contrast palette designed for a white
97             background, which happens to also be the default.
98              
99             =head2 cs_package
100              
101             This allows choosing an alternative but compatible C
102             implementation, such as L. Defaults to
103             the original L.
104              
105             =head1 STASH VARIABLES
106              
107             As shown in the synopsis at the top, your chart is ultimately defined
108             by the contents of two stash variables: C<$c-Estash-E{chart_opts}>,
109             and C<$c-Estash-E{chart_data}>.
110              
111             C is analogous to the configuration options described above for
112             the View-wide C<-Econfig> settings. Valid things here are all of the
113             documented arguments to L's C method, as well as
114             the configuration parameters specifically details above.
115              
116             C should be an arrayref of sets of data to be charted. Each
117             item in the arrayref should in turn be a hashref consisting of two keys:
118             C and C. These two keys are analogous to the two arguments
119             of L's C method.
120              
121             In other words, the following example standard L code:
122              
123             my $chart = Chart::Strip‐>new( title => 'Happiness of our Group' );
124             $chart‐>add_data( $davey_data, { style => 'line',
125             color => 'FF0000',
126             label => 'Davey' } );
127              
128             $chart‐>add_data( $jenna_data, { style => 'line',
129             color => '00FF88',
130             label => 'Jenna' } );
131              
132             Becomes this in terms of stash variables:
133              
134             $c->stash->{chart_opts}->{title} = 'Happiness of our Group';
135             $c->stash->{chart_data} = [
136             { data => $davey_data, opts => { style => 'line',
137             color => 'FF0000',
138             label => 'Davey' }
139             },
140             { data => $jenna_data, opts => { style => 'line',
141             color => '00FF88',
142             label => 'Jenna' }
143             },
144              
145             ];
146              
147             Note that colors are completely optional for us, since we have a reasonable
148             default palette. You need only neccesarily supply the style and label options
149             for a reasonable chart.
150              
151             See L for a full-fledged controller
152             action you can copy and paste as a working example.
153              
154             =cut
155              
156             # This default palette is hand-tweaked for contrast
157             # against white background on an RGB monitor for human eyes.
158             # The first 7 colors are very good, and the last 2 are decent
159             # enough for most purposes. There is no perfect 9+ color
160             # high-constrast palette, and this is probably as good as it gets.
161              
162             our $def_pal = [qw/
163             FF0000
164             00CC00
165             0000FF
166             CC00CC
167             00BBDD
168             DDBB00
169             000000
170             666666
171             557700
172             /];
173              
174             =head1 METHODS
175              
176             =head2 new
177              
178             Constructor for these Views. Mainly just defaults the above-documented
179             View-specific options, and loads the selected C package.
180              
181             =cut
182              
183             sub new {
184 0     0 1   my $self = shift->NEXT::new(@_);
185              
186 0   0       $self->{cs_package} ||= 'Chart::Strip';
187 0   0       $self->{img_type} ||= 'png';
188 0   0       $self->{palette} ||= $def_pal;
189 0 0         $self->{cs_package}->require
190             or croak "Cannot load Chart::Strip module '$self->{cs_package}'";
191              
192 0           $self;
193             }
194              
195             =head2 process
196              
197             This does the chart generation itself. The bulk of the code is
198             concerned with applying the palette to your data before constructing
199             the L object and using it to generate the output
200             binary image data.
201              
202             =cut
203              
204             sub process {
205 0     0 1   my ($self, $c) = @_;
206              
207 0           my $opts = $c->stash->{chart_opts};
208 0           my $data = $c->stash->{chart_data};
209              
210 0           my $chart = $self->{cs_package}->new( %$self, %$opts );
211 0           my $palette = $chart->{palette};
212              
213             # This is all in support of defaulted color palettes
214 0           my $is_stacked = ($data->[0]->{opts}->{style} eq 'stacked');
215 0 0         if($is_stacked) {
216 0           my $stack = $data->[0];
217 0 0         if( ! @{ $stack->{opts}->{colors} || [] } ) {
  0 0          
218 0           my @stacked_colors;
219 0           my $cnum = 0;
220 0           my $ncolors_wanted = @{$stack->{data}->[0]->{values}};
  0            
221 0           foreach (1..$ncolors_wanted) {
222 0           unshift(@stacked_colors, $palette->[$cnum]);
223 0           $cnum++;
224 0 0         $cnum = 0 if $cnum > $#$palette;
225             }
226 0           $stack->{opts}->{colors} = \@stacked_colors;
227 0           $chart->add_data($stack->{data}, $stack->{opts});
228             }
229             }
230             else {
231 0           my $cnum = 0;
232 0           foreach (@$data) {
233 0   0       $_->{opts}->{color} ||= $palette->[$cnum];
234 0           $chart->add_data($_->{data}, $_->{opts});
235 0           $cnum++;
236 0 0         $cnum = 0 if $cnum > $#$palette;
237             }
238             }
239              
240 0           my $itype = $chart->{img_type};
241 0           $c->response->content_type("image/$itype");
242 0           $c->response->body($chart->$itype($chart->{quality}));
243             }
244              
245             =head1 SEE ALSO
246              
247             L, L, L,
248             L, L,
249             L
250              
251             =head1 AUTHOR
252              
253             Brandon L Black, C
254              
255             =head1 LICENSE
256              
257             You may distribute this code under the same terms as Perl itself.
258              
259             =cut
260              
261             1;