File Coverage

blib/lib/Excel/Writer/XLSX/Chart/Stock.pm
Criterion Covered Total %
statement 56 56 100.0
branch 13 14 92.8
condition n/a
subroutine 9 9 100.0
pod 0 1 0.0
total 78 80 97.5


line stmt bran cond sub pod time code
1              
2             ###############################################################################
3             #
4             # Stock - A class for writing Excel Stock 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 13     13   2420 use strict;
  13         38  
19 13     13   53 use warnings;
  13         19  
  13         228  
20 13     13   45 use Carp;
  13         23  
  13         264  
21 13     13   50 use Excel::Writer::XLSX::Chart;
  13         26  
  13         625  
22 13     13   62  
  13         20  
  13         5496  
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 13     13 0 722 $self->{_show_crosses} = 0;
36 13         48 $self->{_hi_low_lines} = {};
37 13         20 $self->{_date_category} = 1;
38 13         24  
39 13         26 # Override and reset the default axis values.
40             $self->{_x_axis}->{_defaults}->{num_format} = 'dd/mm/yyyy';
41             $self->{_x2_axis}->{_defaults}->{num_format} = 'dd/mm/yyyy';
42 13         39 $self->set_x_axis();
43 13         31 $self->set_x2_axis();
44 13         60  
45 13         39 # Set the available data label positions for this chart type.
46             $self->{_label_position_default} = 'right';
47             $self->{_label_positions} = {
48 13         27 center => 'ctr',
49             right => 'r',
50 13         66 left => 'l',
51             above => 't',
52             below => 'b',
53             # For backward compatibility.
54             top => 't',
55             bottom => 'b',
56             };
57              
58             bless $self, $class;
59             return $self;
60 13         29 }
61 13         37  
62              
63             ##############################################################################
64             #
65             # _write_chart_type()
66             #
67             # Override the virtual superclass method with a chart specific method.
68             #
69              
70             my $self = shift;
71              
72             # Write the c:stockChart element.
73 24     24   40 $self->_write_stock_chart( @_ );
74             }
75              
76 24         56  
77             ##############################################################################
78             #
79             # _write_stock_chart()
80             #
81             # Write the <c:stockChart> element.
82             # Overridden to add hi_low_lines(). TODO. Refactor up into the SUPER class.
83             #
84              
85             my $self = shift;
86             my %args = @_;
87              
88             my @series;
89 24     24   46 if ( $args{primary_axes} ) {
90 24         66 @series = $self->_get_primary_axes_series;
91             }
92 24         35 else {
93 24 100       74 @series = $self->_get_secondary_axes_series;
94 12         85 }
95              
96             return unless scalar @series;
97 12         67  
98             # Add default formatting to the series data.
99             $self->_modify_series_formatting();
100 24 100       74  
101             $self->xml_start_tag( 'c:stockChart' );
102              
103 13         45 # Write the series elements.
104             $self->_write_ser( $_ ) for @series;
105 13         53  
106             # Write the c:dropLines element.
107             $self->_write_drop_lines();
108 13         88  
109             # Write the c:hiLowLines element.
110             $self->_write_hi_low_lines() if $args{primary_axes};
111 13         96  
112             # Write the c:upDownBars element.
113             $self->_write_up_down_bars();
114 13 100       80  
115             # Write the c:axId elements
116             $self->_write_axis_ids( %args );
117 13         75  
118             $self->xml_end_tag( 'c:stockChart' );
119             }
120 13         90  
121              
122 13         39 ##############################################################################
123             #
124             # _modify_series_formatting()
125             #
126             # Add default formatting to the series data.
127             #
128              
129             my $self = shift;
130              
131             my $index = 0;
132             for my $series ( @{ $self->{_series} } ) {
133             if ( $index % 4 != 3 ) {
134 13     13   20 if ( !$series->{_line}->{_defined} ) {
135             $series->{_line} = {
136 13         24 width => 2.25,
137 13         20 none => 1,
  13         22  
138 39 50       92 _defined => 1,
139 39 100       94 };
140             }
141 36         100  
142             if ( !$series->{_marker} ) {
143             if ( $index % 4 == 2 ) {
144             $series->{_marker} = { type => 'dot', size => 3 };
145             }
146             else {
147 39 100       90 $series->{_marker} = { type => 'none' };
148 36 100       74  
149 12         37 }
150             }
151             }
152 24         55 $index++;
153             }
154             }
155              
156              
157 39         58 1;
158              
159              
160              
161              
162             =head1 NAME
163              
164             Stock - A class for writing Excel Stock charts.
165              
166             =head1 SYNOPSIS
167              
168             To create a simple Excel file with a Stock chart using Excel::Writer::XLSX:
169              
170             #!/usr/bin/perl -w
171              
172             use strict;
173             use Excel::Writer::XLSX;
174              
175             my $workbook = Excel::Writer::XLSX->new( 'chart.xlsx' );
176             my $worksheet = $workbook->add_worksheet();
177              
178             my $chart = $workbook->add_chart( type => 'stock' );
179              
180             # Add a series for each High-Low-Close.
181             $chart->add_series(
182             categories => '=Sheet1!$A$2:$A$6',
183             values => '=Sheet1!$B$2:$B$6'
184             );
185              
186             $chart->add_series(
187             categories => '=Sheet1!$A$2:$A$6',
188             values => '=Sheet1!$C$2:$C$6'
189             );
190              
191             $chart->add_series(
192             categories => '=Sheet1!$A$2:$A$6',
193             values => '=Sheet1!$D$2:$D$6'
194             );
195              
196             # Add the worksheet data the chart refers to.
197             # ... See the full example below.
198              
199             __END__
200              
201              
202             =head1 DESCRIPTION
203              
204             This module implements Stock charts for L<Excel::Writer::XLSX>. The chart object is created via the Workbook C<add_chart()> method:
205              
206             my $chart = $workbook->add_chart( type => 'stock' );
207              
208             Once the object is created it can be configured via the following methods that are common to all chart classes:
209              
210             $chart->add_series();
211             $chart->set_x_axis();
212             $chart->set_y_axis();
213             $chart->set_title();
214              
215             These methods are explained in detail in L<Excel::Writer::XLSX::Chart>. Class specific methods or settings, if any, are explained below.
216              
217             =head1 Stock Chart Methods
218              
219             There aren't currently any stock chart specific methods. See the TODO section of L<Excel::Writer::XLSX::Chart>.
220              
221             The default Stock chart is a High-Low-Close chart. A series must be added for each of these data sources.
222              
223              
224             =head1 EXAMPLE
225              
226             Here is a complete example that demonstrates most of the available features when creating a Stock chart.
227              
228             #!/usr/bin/perl
229              
230             use strict;
231             use warnings;
232             use Excel::Writer::XLSX;
233             use Excel::Writer::XLSX;
234              
235             my $workbook = Excel::Writer::XLSX->new( 'chart_stock.xlsx' );
236             my $worksheet = $workbook->add_worksheet();
237             my $bold = $workbook->add_format( bold => 1 );
238             my $date_format = $workbook->add_format( num_format => 'dd/mm/yyyy' );
239             my $chart = $workbook->add_chart( type => 'stock', embedded => 1 );
240              
241              
242             # Add the worksheet data that the charts will refer to.
243             my $headings = [ 'Date', 'High', 'Low', 'Close' ];
244             my $data = [
245              
246             [ '2007-01-01T', '2007-01-02T', '2007-01-03T', '2007-01-04T', '2007-01-05T' ],
247             [ 27.2, 25.03, 19.05, 20.34, 18.5 ],
248             [ 23.49, 19.55, 15.12, 17.84, 16.34 ],
249             [ 25.45, 23.05, 17.32, 20.45, 17.34 ],
250              
251             ];
252              
253             $worksheet->write( 'A1', $headings, $bold );
254              
255             for my $row ( 0 .. 4 ) {
256             $worksheet->write_date_time( $row+1, 0, $data->[0]->[$row], $date_format );
257             $worksheet->write( $row+1, 1, $data->[1]->[$row] );
258             $worksheet->write( $row+1, 2, $data->[2]->[$row] );
259             $worksheet->write( $row+1, 3, $data->[3]->[$row] );
260              
261             }
262              
263             $worksheet->set_column( 'A:D', 11 );
264              
265             # Add a series for each of the High-Low-Close columns.
266             $chart->add_series(
267             categories => '=Sheet1!$A$2:$A$6',
268             values => '=Sheet1!$B$2:$B$6',
269             );
270              
271             $chart->add_series(
272             categories => '=Sheet1!$A$2:$A$6',
273             values => '=Sheet1!$C$2:$C$6',
274             );
275              
276             $chart->add_series(
277             categories => '=Sheet1!$A$2:$A$6',
278             values => '=Sheet1!$D$2:$D$6',
279             );
280              
281             # Add a chart title and some axis labels.
282             $chart->set_title ( name => 'High-Low-Close', );
283             $chart->set_x_axis( name => 'Date', );
284             $chart->set_y_axis( name => 'Share price', );
285              
286              
287             $worksheet->insert_chart( 'E9', $chart );
288              
289             __END__
290              
291             =begin html
292              
293             <p>This will produce a chart that looks like this:</p>
294              
295             <p><center><img src="http://jmcnamara.github.io/excel-writer-xlsx/images/examples/stock1.jpg" width="483" height="291" alt="Chart example." /></center></p>
296              
297             =end html
298              
299              
300             =head1 AUTHOR
301              
302             John McNamara jmcnamara@cpan.org
303              
304             =head1 COPYRIGHT
305              
306             Copyright MM-MMXXI, John McNamara.
307              
308             All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.
309