File Coverage

blib/lib/Chart/Plotly/Image/Orca.pm
Criterion Covered Total %
statement 38 75 50.6
branch 4 24 16.6
condition 5 21 23.8
subroutine 10 14 71.4
pod 4 4 100.0
total 61 138 44.2


line stmt bran cond sub pod time code
1             package Chart::Plotly::Image::Orca;
2              
3             # ABSTRACT: Export static images of Plotly charts using orca
4              
5 2     2   859 use 5.010;
  2         8  
6 2     2   11 use strict;
  2         4  
  2         41  
7 2     2   12 use warnings;
  2         3  
  2         56  
8              
9 2     2   10 use Config;
  2         4  
  2         79  
10 2     2   941 use File::Which;
  2         1854  
  2         131  
11 2     2   15 use Path::Tiny;
  2         4  
  2         91  
12 2     2   12 use File::ShareDir qw(dist_file);
  2         4  
  2         106  
13 2     2   11 use utf8;
  2         5  
  2         12  
14              
15             our $VERSION = '0.041'; # VERSION
16              
17             my $ORCA_COMMAND = 'orca';
18              
19             # have this in a sub to avoid breaking auto-generated tests like pod-coverage.
20             sub _plotlyjs {
21 0     0   0 state $plotlyjs = dist_file( 'Chart-Plotly', 'plotly.js/plotly.min.js' );
22 0         0 return $plotlyjs;
23             }
24              
25             sub _check_alien {
26 2     2   115 my ($force_check) = @_;
27              
28 2         4 state $has_alien;
29              
30 2 50 33     10 if ( !defined $has_alien or $force_check ) {
31 2         5 $has_alien = undef;
32 2         6 eval { require Alien::Plotly::Orca; };
  2         383  
33 2 50 33     16 if ( !$@ and Alien::Plotly::Orca->install_type eq 'share' ) {
34 0         0 $ENV{PATH} = join( $Config{path_sep}, Alien::Plotly::Orca->bin_dir, $ENV{PATH} );
35 0         0 $has_alien = 1;
36             } else {
37 2         5 $has_alien = 0;
38             }
39             }
40 2         14 return $has_alien;
41             }
42              
43             sub orca {
44 0     0 1 0 my %params = @_;
45              
46 0 0       0 if ( orca_available() ) {
47 0         0 my $plot = $params{plot};
48 0         0 my $file = path( $params{file} );
49 0         0 my $format = $params{format};
50 0 0       0 unless ( defined $format ) {
51 0         0 ($format) = $file =~ /\.([^\.]+)$/;
52             }
53 0   0     0 my $plotlyjs = $params{plotlyjs} // $params{plotly} // _plotlyjs;
      0        
54              
55 0         0 my $tmp_json = Path::Tiny->tempfile( SUFFIX => '.json' );
56 0         0 $tmp_json->spew_raw( $plot->to_json_text );
57              
58             # For now have to explicitly specify -d as otherwise orca would
59             # not be able to store output to a different path other than cwd.
60             # See https://github.com/plotly/orca/issues/101
61 0 0       0 my @orca_line = (
62             $ORCA_COMMAND, 'graph', $tmp_json, '--plotlyjs', $plotlyjs, '-d', $file->parent, '-o', $file->basename,
63             ( $format ? ( '--format', $format ) : () ) );
64 0         0 for my $arg (qw(mathjax scale width height)) {
65 0 0       0 if ( my $val = $params{$arg} ) {
66 0         0 push @orca_line, ( "--${arg}", $val );
67             }
68             }
69 0         0 for my $arg (qw(safe verbose debug)) {
70 0 0       0 if ( $params{$arg} ) {
71 0         0 push @orca_line, "--${arg}";
72             }
73             }
74              
75 0         0 my $rc = system(@orca_line);
76 0 0       0 return 1 unless ( $rc >> 8 );
77             }
78 0         0 return;
79             }
80              
81             sub correct_orca {
82 0     0 1 0 my $orca_help = `$ORCA_COMMAND --help`;
83 0         0 return ( $orca_help =~ /plotly/i );
84             }
85              
86             sub orca_available {
87 1     1 1 3 my ($force_check) = @_;
88              
89 1         2 state $available;
90              
91 1 50 33     7 if ( !defined $available or $force_check ) {
92 1         9 $available = undef;
93 1 50 33     5 if ( not _check_alien($force_check)
      33        
94             and ( not which($ORCA_COMMAND) or not correct_orca() ) )
95             {
96 1         304 die "Orca tool (its 'orca' command) must be installed and in "
97             . "PATH in order to export images. "
98             . "Either install Alien::Plotly::Orca from CPAN, or install "
99             . "it manually (see https://github.com/plotly/orca#installation)";
100             }
101 0           $available = 1;
102             }
103 0           return $available;
104             }
105              
106             sub orca_version {
107 0     0 1   my ($force_check) = @_;
108              
109 0           state $version;
110              
111 0 0         if ( _check_alien($force_check) ) {
112 0           return Alien::Plotly::Orca->version;
113             }
114 0 0         if ( orca_available($force_check) ) {
115 0           $version = `$ORCA_COMMAND --version`;
116 0           chomp($version);
117 0           return $version;
118             }
119 0           return;
120             }
121              
122             1;
123              
124             __END__
125              
126             =pod
127              
128             =encoding utf-8
129              
130             =head1 NAME
131              
132             Chart::Plotly::Image::Orca - Export static images of Plotly charts using orca
133              
134             =head1 VERSION
135              
136             version 0.041
137              
138             =head1 SYNOPSIS
139              
140             #!/usr/bin/env perl
141            
142             use strict;
143             use warnings;
144             use utf8;
145            
146             use Chart::Plotly::Plot;
147             use Chart::Plotly::Trace::Scatter;
148             use Chart::Plotly::Image::Orca;
149            
150             my $plot = Chart::Plotly::Plot->new(traces => [ Chart::Plotly::Trace::Scatter->new( x => [ 1 .. 5 ], y => [ 1 .. 5 ] )]);
151            
152             Chart::Plotly::Image::Orca::orca(plot => $plot, file => "TestOrca.png");
153              
154             =head1 DESCRIPTION
155              
156             This module generate static images of Plotly charts without a browser using
157             L<Orca|https://github.com/plotly/orca>
158              
159             Orca is an L<Electron|https://electronjs.org/> app that must be installed before
160             using this module. You can either,
161              
162             =over 4
163              
164             =item *
165              
166             Install the L<Alien::Plotly::Orca> module from CPAN. Or,
167              
168             =item *
169              
170             Install plotly-orca yourself and have a C<orca> command findable via the
171             C<PATH> env var in your system, see also
172             L<https://github.com/plotly/orca#installation>.
173              
174             =back
175              
176             =head1 FUNCTIONS
177              
178             =head2 orca
179              
180             orca(plot => $plot, file => $file, %rest)
181              
182             Export L<Chart::Plotly::Plot> as a static image file.
183              
184             This function is a wrapper over the plotly orca command.
185             Most of its named parameters are mapped to orca's command line options.
186             See also the output of C<orca graph --help>.
187              
188             Returns a true value if the orca command is successful.
189              
190             =over 4
191              
192             =item plot
193              
194             Object to export
195              
196             =item file
197              
198             Filename (with or without path) to export
199              
200             =item format
201              
202             Sets the output format (png, jpeg, webp, svg, pdf, eps).
203             By default it's inferred from the specified file name extension.
204              
205             =item scale
206              
207             Sets the image scale.
208              
209             =item width
210              
211             Sets the image width.
212              
213             =item height
214              
215             Sets the image height.
216              
217             =item plotlyjs
218              
219             Sets plotlyjs file path. Default is the bundled plotly.min.js file.
220              
221             =item plotly
222              
223             This is same as the C<plotlyjs> parameter mentioned above.
224              
225             =item mathjax
226              
227             Sets path to MathJax files. Required to export LaTeX characters.
228              
229             =item safe
230              
231             Turns on safe mode: where figures likely to make browser window hang
232             during image generating are skipped.
233              
234             =item verbose
235              
236             Turn on verbose logging on stdout.
237              
238             =item debug
239              
240             Starts app in debug mode and turn on verbose logs on stdout.
241              
242             =back
243              
244             =head2 correct_orca
245              
246             Checks that orca command available is the plotly image exporter,
247             as there may be some other different command also named "orca", like
248             L<https://help.gnome.org/users/orca/stable/>
249              
250             =head2 orca_available
251              
252             Checks that orca command is available and the plotly image exporter
253              
254             =head2 orca_version
255              
256             Returns the orca version
257              
258             =head1 BUGS
259              
260             Please report any bugs or feature requests via github: L<https://github.com/pablrod/p5-Chart-Plotly/issues>
261              
262             =head1 DISCLAIMER
263              
264             This is an unofficial Plotly Perl module. Currently I'm not affiliated in any way with Plotly.
265             But I think plotly.js is a great library and I want to use it with perl.
266              
267             If you like plotly.js please consider supporting them purchasing a pro subscription: L<https://plot.ly/products/cloud/>
268              
269             =head1 SEE ALSO
270              
271             L<Alien::Plotly::Orca>
272              
273             =head1 AUTHOR
274              
275             Pablo Rodríguez González <pablo.rodriguez.gonzalez@gmail.com>
276              
277             =head1 COPYRIGHT AND LICENSE
278              
279             This software is Copyright (c) 2020 by Pablo Rodríguez González.
280              
281             This is free software, licensed under:
282              
283             The MIT (X11) License
284              
285             =cut