File Coverage

blib/lib/Chart/Plotly/Image/Orca.pm
Criterion Covered Total %
statement 32 75 42.6
branch 2 24 8.3
condition 2 18 11.1
subroutine 9 14 64.2
pod 4 4 100.0
total 49 135 36.3


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