File Coverage

blib/lib/Chart/Dygraphs.pm
Criterion Covered Total %
statement 27 67 40.3
branch 0 12 0.0
condition 0 3 0.0
subroutine 9 15 60.0
pod 2 2 100.0
total 38 99 38.3


line stmt bran cond sub pod time code
1             package Chart::Dygraphs;
2              
3 1     1   58287 use strict;
  1         2  
  1         26  
4 1     1   4 use warnings;
  1         1  
  1         25  
5 1     1   3 use utf8;
  1         5  
  1         5  
6              
7 1     1   21 use Exporter 'import';
  1         1  
  1         42  
8             our @EXPORT_OK = qw(show_plot);
9              
10 1     1   710 use JSON;
  1         12024  
  1         5  
11 1     1   705 use Params::Validate qw(:all);
  1         7234  
  1         175  
12 1     1   744 use Text::Template;
  1         2867  
  1         65  
13 1     1   472 use HTML::Show;
  1         15429  
  1         47  
14 1     1   744 use Ref::Util;
  1         878  
  1         934  
15              
16             our $VERSION = '0.006'; # VERSION
17              
18             =encoding utf-8
19              
20             =head1 NAME
21              
22             Chart::Dygraphs - Generate html/javascript charts from perl data using javascript library Dygraphs
23              
24             =head1 SYNOPSYS
25              
26             use Chart::Dygraphs qw(show_plot);
27            
28             my $data = [map {[$_, rand($_)]} 1..10 ];
29             show_plot($data);
30              
31             use Chart::Dygraphs qw(show_plot);
32             use DateTime;
33            
34             my $start_date = DateTime->now(time_zone => 'UTC')->truncate(to => 'hour');
35             my $time_series_data = [map {[$start_date->add(hours => 1)->clone(), rand($_)]} 1..1000];
36            
37             show_plot($time_series_data);
38              
39             =head1 DESCRIPTION
40              
41             Generate html/javascript charts from perl data using javascript library Dygraphs. The result
42             is html that you could see in your favourite browser.
43              
44             The interface is "sub" oriented, but the API is subject to changes.
45              
46             =head1 FUNCTIONS
47              
48             =cut
49              
50             =head2 render_full_html
51              
52             =head3 Parameters
53              
54             =over
55              
56             =item * data:
57              
58             Data to be represented. The format is the perl version of the data expected by Dygraphs: L
59              
60             =item * options:
61              
62             Hashref with options for graph. The format is the perl version of the options expected by Dygraphs: L
63             Optional
64              
65             =item * render_html_options
66              
67             Hashref with options controlling html output. With this you can inject html, javascript or styles.
68              
69             Supported options:
70              
71             =over
72              
73             =item * pre_graph_html
74              
75             =item * post_graph_html
76              
77             =item * dygraphs_div_id
78              
79             =item * dygraphs_javascript_object_name
80              
81             =item * dygraphs_div_inline_style
82              
83             =back
84              
85             =back
86              
87             =cut
88              
89             sub render_full_html {
90 0     0 1   my %params = validate( @_,
91             { data => { type => SCALAR | ARRAYREF },
92             options => { type => HASHREF, default => { showRangeSelector => 1 } },
93             render_html_options => { type => HASHREF,
94             optional => 1,
95             default => {}
96             }
97             }
98             );
99             return _render_html_wrap(
100 0           _render_cell( _process_data_and_options( @params{qw(data options)} ), $params{'render_html_options'}, '' ) );
101             }
102              
103             sub _transform_data {
104 0     0     my $data = shift;
105 0           my $string_data = "";
106 0 0 0       if ( Ref::Util::is_plain_arrayref($data) ) {
    0          
    0          
107 0           $string_data .= "[" . ( join( ',', map { _transform_data($_) } @$data ) ) . "]";
  0            
108             } elsif ( Ref::Util::is_plain_hashref($data) ) {
109 0           return "not supported";
110             } elsif ( Ref::Util::is_blessed_ref($data) && $data->isa('DateTime') ) {
111 0           return 'new Date("' . $data . '")';
112             } else {
113 0           return $data;
114             }
115 0           return $string_data;
116             }
117              
118             sub _process_data_and_options {
119 0     0     my $data = shift();
120 0           my $options = shift();
121 0           my $json_formatter = JSON->new->utf8;
122 0           return join( ',', _transform_data($data), $json_formatter->encode($options) );
123             }
124              
125             sub _render_cell {
126              
127 0     0     my $data = shift();
128 0           my $html_options = shift();
129 0           my $id = shift();
130 0           my $template = <<'TEMPLATE';
131             {$pre_graph_html}
132            
133            
142             {$post_graph_html}
143             TEMPLATE
144 0           my $template_variables = { %{$html_options}, data_and_options => $data, };
  0            
145              
146 0 0         if ( !defined $template_variables->{'dygraphs_div_id'} ) {
147 0           $template_variables->{'dygraphs_div_id'} = 'graphdiv' . $id;
148             }
149 0 0         if ( !defined $template_variables->{'dygraphs_javascript_object_name'} ) {
150 0           $template_variables->{'dygraphs_javascript_object_name'} = 'g' . $id;
151             }
152 0 0         if ( !defined $template_variables->{'dygraphs_div_inline_style'} ) {
153 0           $template_variables->{'dygraphs_div_inline_style'} = 'width: 100%';
154             }
155 0           my $renderer = Text::Template->new( TYPE => 'STRING', SOURCE => $template );
156 0           return $renderer->fill_in( HASH => $template_variables );
157             }
158              
159             sub _render_html_wrap {
160 0     0     my $body = shift();
161              
162 0           my $html_begin = <<'BEGIN_HTML';
163            
164            
165            
166            
167            
168             BEGIN_HTML
169              
170 0           my $html_end = <<'END_HTML';
171            
172            
173             END_HTML
174              
175 0           return $html_begin . $body . $html_end;
176              
177             }
178              
179             =head2 show_plot
180              
181             Opens the plot in a browser locally
182              
183             =head3 Parameters
184              
185             Data to be represented. The format is the same as the parameter data in render_full_html
186              
187             =cut
188              
189             sub show_plot {
190 0     0 1   my @data_to_plot = @_;
191              
192 0           my $rendered_cells = "";
193 0           my $numeric_id = 0;
194 0           for my $data (@data_to_plot) {
195 0           $rendered_cells .= _render_cell( _process_data_and_options( $data, { showRangeSelector => 1 } ),
196             { dygraphs_div_id => 'graphdiv' . $numeric_id,
197             dygraphs_javascript_object_name => 'g' . $numeric_id
198             },
199             'chart_' . $numeric_id++
200             );
201             }
202 0           my $plots = _render_html_wrap($rendered_cells);
203 0           HTML::Show::show($plots);
204             }
205              
206             1;
207              
208             __END__