File Coverage

blib/lib/Excel/Writer/XLSX/Chart/Bar.pm
Criterion Covered Total %
statement 72 74 97.3
branch 17 20 85.0
condition 2 2 100.0
subroutine 11 11 100.0
pod 1 2 50.0
total 103 109 94.5


line stmt bran cond sub pod time code
1              
2             ###############################################################################
3             #
4             # Bar - A class for writing Excel Bar charts.
5             #
6             # Used in conjunction with Excel::Writer::XLSX::Chart.
7             #
8             # See formatting note in Excel::Writer::XLSX::Chart.
9             #
10             # Copyright 2000-2021, John McNamara, jmcnamara@cpan.org
11             #
12             # Documentation after __END__
13             #
14              
15             # perltidy with the following options: -mbl=2 -pt=0 -nola
16              
17             use 5.008002;
18 62     62   8455 use strict;
  62         184  
19 62     62   295 use warnings;
  62         106  
  62         1090  
20 62     62   232 use Carp;
  62         101  
  62         1365  
21 62     62   256 use Excel::Writer::XLSX::Chart;
  62         107  
  62         3249  
22 62     62   308  
  62         112  
  62         36087  
23             our @ISA = qw(Excel::Writer::XLSX::Chart);
24             our $VERSION = '1.09';
25              
26              
27             ###############################################################################
28             #
29             # new()
30             #
31             #
32              
33             my $class = shift;
34             my $self = Excel::Writer::XLSX::Chart->new( @_ );
35 68     68 0 2902  
36 68         269 $self->{_subtype} = $self->{_subtype} || 'clustered';
37             $self->{_cat_axis_position} = 'l';
38 68   100     354 $self->{_val_axis_position} = 'b';
39 68         181 $self->{_horiz_val_axis} = 0;
40 68         106 $self->{_horiz_cat_axis} = 1;
41 68         134 $self->{_show_crosses} = 0;
42 68         119  
43 68         134 # Override and reset the default axis values.
44             $self->{_x_axis}->{_defaults}->{major_gridlines} = { visible => 1 };
45             $self->{_y_axis}->{_defaults}->{major_gridlines} = { visible => 0 };
46 68         185  
47 68         152 if ( $self->{_subtype} eq 'percent_stacked' ) {
48             $self->{_x_axis}->{_defaults}->{num_format} = '0%';
49 68 100       202 }
50 1         2  
51             $self->set_x_axis();
52             $self->set_y_axis();
53 68         269  
54 68         206 # Set the available data label positions for this chart type.
55             $self->{_label_position_default} = 'outside_end';
56             $self->{_label_positions} = {
57 68         111 center => 'ctr',
58             inside_base => 'inBase',
59 68         267 inside_end => 'inEnd',
60             outside_end => 'outEnd',
61             };
62              
63             bless $self, $class;
64             return $self;
65 68         145 }
66 68         219  
67              
68             ###############################################################################
69             #
70             # combine()
71             #
72             # Override parent method to add an extra check that is required for Bar
73             # charts to ensure that their combined chart is on a secondary axis.
74             #
75              
76             my $self = shift;
77             my $chart = shift;
78              
79 1     1 1 6 if (!$chart->{_is_secondary}) {
80 1         1 carp 'Charts combined with Bar charts must be on a secondary axis';
81             return;
82 1 50       4 }
83 0         0  
84 0         0 $self->{_combined} = $chart;
85             }
86              
87 1         2  
88             ##############################################################################
89             #
90             # _write_chart_type()
91             #
92             # Override the virtual superclass method with a chart specific method.
93             #
94              
95             my $self = shift;
96             my %args = @_;
97              
98             if ( $args{primary_axes} ) {
99 130     130   226  
100 130         406 # Reverse X and Y axes for Bar charts.
101             my $tmp = $self->{_y_axis};
102 130 100       376 $self->{_y_axis} = $self->{_x_axis};
103             $self->{_x_axis} = $tmp;
104              
105 65         152 if ( $self->{_y2_axis}->{_position} eq 'r' ) {
106 65         155 $self->{_y2_axis}->{_position} = 't';
107 65         138 }
108             }
109 65 50       256  
110 65         170 # Write the c:barChart element.
111             $self->_write_bar_chart( @_ );
112             }
113              
114              
115 130         373 ##############################################################################
116             #
117             # _write_bar_chart()
118             #
119             # Write the <c:barChart> element.
120             #
121              
122             my $self = shift;
123             my %args = @_;
124              
125             my @series;
126             if ( $args{primary_axes} ) {
127 130     130   215 @series = $self->_get_primary_axes_series;
128 130         266 }
129             else {
130 130         196 @series = $self->_get_secondary_axes_series;
131 130 100       315 }
132 65         470  
133             return unless scalar @series;
134              
135 65         417 my $subtype = $self->{_subtype};
136             $subtype = 'percentStacked' if $subtype eq 'percent_stacked';
137              
138 130 100       721 # Set a default overlap for stacked charts.
139             if ($self->{_subtype} =~ /stacked/) {
140 67         165 if (!defined $self->{_series_overlap_1}) {
141 67 100       208 $self->{_series_overlap_1} = 100;
142             }
143             }
144 67 100       261  
145 2 50       5 $self->xml_start_tag( 'c:barChart' );
146 2         10  
147             # Write the c:barDir element.
148             $self->_write_bar_dir();
149              
150 67         254 # Write the c:grouping element.
151             $self->_write_grouping( $subtype );
152              
153 67         212 # Write the c:ser elements.
154             $self->_write_ser( $_ ) for @series;
155              
156 67         417 if ( $args{primary_axes} ) {
157             # Write the c:gapWidth element.
158             $self->_write_gap_width( $self->{_series_gap_1} );
159 67         404  
160             # Write the c:overlap element.
161 67 100       344 $self->_write_overlap( $self->{_series_overlap_1} );
162             }
163 65         620 else {
164             # Write the c:gapWidth element.
165             $self->_write_gap_width( $self->{_series_gap_2} );
166 65         407  
167             # Write the c:overlap element.
168             $self->_write_overlap( $self->{_series_overlap_2} );
169             }
170 2         14  
171             # Write the c:axId elements
172             $self->_write_axis_ids( %args );
173 2         6  
174             $self->xml_end_tag( 'c:barChart' );
175             }
176              
177 67         624  
178             ##############################################################################
179 67         193 #
180             # _write_bar_dir()
181             #
182             # Write the <c:barDir> element.
183             #
184              
185             my $self = shift;
186             my $val = 'bar';
187              
188             my @attributes = ( 'val' => $val );
189              
190             $self->xml_empty_tag( 'c:barDir', @attributes );
191 68     68   207 }
192 68         125  
193              
194 68         161 ##############################################################################
195             #
196 68         219 # _write_err_dir()
197             #
198             # Write the <c:errDir> element. Overridden from Chart class since it is not
199             # used in Bar charts.
200             #
201              
202             1;
203              
204              
205              
206              
207       1     =head1 NAME
208              
209             Bar - A class for writing Excel Bar charts.
210              
211             =head1 SYNOPSIS
212              
213             To create a simple Excel file with a Bar chart using Excel::Writer::XLSX:
214              
215             #!/usr/bin/perl
216              
217             use strict;
218             use warnings;
219             use Excel::Writer::XLSX;
220              
221             my $workbook = Excel::Writer::XLSX->new( 'chart.xlsx' );
222             my $worksheet = $workbook->add_worksheet();
223              
224             my $chart = $workbook->add_chart( type => 'bar' );
225              
226             # Configure the chart.
227             $chart->add_series(
228             categories => '=Sheet1!$A$2:$A$7',
229             values => '=Sheet1!$B$2:$B$7',
230             );
231              
232             # Add the worksheet data the chart refers to.
233             my $data = [
234             [ 'Category', 2, 3, 4, 5, 6, 7 ],
235             [ 'Value', 1, 4, 5, 2, 1, 5 ],
236             ];
237              
238             $worksheet->write( 'A1', $data );
239              
240             __END__
241              
242             =head1 DESCRIPTION
243              
244             This module implements Bar charts for L<Excel::Writer::XLSX>. The chart object is created via the Workbook C<add_chart()> method:
245              
246             my $chart = $workbook->add_chart( type => 'bar' );
247              
248             Once the object is created it can be configured via the following methods that are common to all chart classes:
249              
250             $chart->add_series();
251             $chart->set_x_axis();
252             $chart->set_y_axis();
253             $chart->set_title();
254              
255             These methods are explained in detail in L<Excel::Writer::XLSX::Chart>. Class specific methods or settings, if any, are explained below.
256              
257             =head1 Bar Chart Subtypes
258              
259             The C<Bar> chart module also supports the following sub-types:
260              
261             stacked
262             percent_stacked
263              
264             These can be specified at creation time via the C<add_chart()> Worksheet method:
265              
266             my $chart = $workbook->add_chart( type => 'bar', subtype => 'stacked' );
267              
268             =head1 EXAMPLE
269              
270             Here is a complete example that demonstrates most of the available features when creating a chart.
271              
272             #!/usr/bin/perl
273              
274             use strict;
275             use warnings;
276             use Excel::Writer::XLSX;
277              
278             my $workbook = Excel::Writer::XLSX->new( 'chart_bar.xlsx' );
279             my $worksheet = $workbook->add_worksheet();
280             my $bold = $workbook->add_format( bold => 1 );
281              
282             # Add the worksheet data that the charts will refer to.
283             my $headings = [ 'Number', 'Batch 1', 'Batch 2' ];
284             my $data = [
285             [ 2, 3, 4, 5, 6, 7 ],
286             [ 10, 40, 50, 20, 10, 50 ],
287             [ 30, 60, 70, 50, 40, 30 ],
288              
289             ];
290              
291             $worksheet->write( 'A1', $headings, $bold );
292             $worksheet->write( 'A2', $data );
293              
294             # Create a new chart object. In this case an embedded chart.
295             my $chart = $workbook->add_chart( type => 'bar', embedded => 1 );
296              
297             # Configure the first series.
298             $chart->add_series(
299             name => '=Sheet1!$B$1',
300             categories => '=Sheet1!$A$2:$A$7',
301             values => '=Sheet1!$B$2:$B$7',
302             );
303              
304             # Configure second series. Note alternative use of array ref to define
305             # ranges: [ $sheetname, $row_start, $row_end, $col_start, $col_end ].
306             $chart->add_series(
307             name => '=Sheet1!$C$1',
308             categories => [ 'Sheet1', 1, 6, 0, 0 ],
309             values => [ 'Sheet1', 1, 6, 2, 2 ],
310             );
311              
312             # Add a chart title and some axis labels.
313             $chart->set_title ( name => 'Results of sample analysis' );
314             $chart->set_x_axis( name => 'Test number' );
315             $chart->set_y_axis( name => 'Sample length (mm)' );
316              
317             # Set an Excel chart style. Blue colors with white outline and shadow.
318             $chart->set_style( 11 );
319              
320             # Insert the chart into the worksheet (with an offset).
321             $worksheet->insert_chart( 'D2', $chart, 25, 10 );
322              
323             __END__
324              
325              
326             =begin html
327              
328             <p>This will produce a chart that looks like this:</p>
329              
330             <p><center><img src="http://jmcnamara.github.io/excel-writer-xlsx/images/examples/bar1.jpg" width="483" height="291" alt="Chart example." /></center></p>
331              
332             =end html
333              
334              
335             =head1 AUTHOR
336              
337             John McNamara jmcnamara@cpan.org
338              
339             =head1 COPYRIGHT
340              
341             Copyright MM-MMXXI, John McNamara.
342              
343             All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.
344