File Coverage

blib/lib/SVG/Sparkline.pm
Criterion Covered Total %
statement 139 141 98.5
branch 50 52 96.1
condition 8 9 88.8
subroutine 32 34 94.1
pod 4 4 100.0
total 233 240 97.0


line stmt bran cond sub pod time code
1             package SVG::Sparkline;
2              
3 31     31   508681 use warnings;
  31         82  
  31         884  
4 30     30   163 use strict;
  30         67  
  30         526  
5 30     30   153 use Carp;
  30         66  
  30         1353  
6 30     30   14161 use SVG;
  30         391078  
  30         186  
7              
8 30     30   67574 use overload '""' => \&to_string;
  30         26527  
  30         221  
9              
10 30     30   2521 use 5.008000;
  30         120  
11             our $VERSION = 1.12;
12              
13             my %valid_parms = map { $_ => 1 } qw(
14             -allns color -sized
15             height width xscale yscale pady padx
16             color bgcolor mark values
17             );
18              
19             sub new
20             {
21 226     226 1 117134 my ($class, $type, $args) = @_;
22 226 100       689 croak "No Sparkline type specified.\n" unless defined $type;
23 225 100       1243 croak "'$type' is not a valid Sparkline type.\n" unless $type =~ m/\A[A-Z]\w+\z/;
24             # Use eval to load plugin. Should be safe because of the test above.
25 224     28   12630 eval "use SVG::Sparkline::$type;"; ## no critic (ProhibitStringyEval)
  28     28   12442  
  27     26   101  
  27     26   555  
  28     20   2021  
  28     15   67  
  28     14   418  
  26     12   2095  
  26     8   74  
  26     8   358  
  26     6   813  
  26     5   56  
  26     5   351  
  20     5   631  
  20     5   54  
  20     5   267  
  15     4   98  
  15     3   34  
  15         191  
  14         464  
  14         32  
  14         172  
  12         78  
  12         26  
  12         440  
  8         50  
  8         17  
  8         94  
  8         49  
  8         17  
  8         97  
  6         39  
  6         13  
  6         73  
  5         33  
  5         11  
  5         58  
  5         31  
  5         12  
  5         58  
  5         31  
  5         11  
  5         79  
  5         30  
  5         11  
  5         57  
  5         35  
  5         12  
  5         62  
  4         25  
  4         8  
  4         50  
  3         21  
  3         6  
  3         37  
26 224 100       862 croak "Unrecognized Sparkline type '$type'.\n" if $@;
27 223 100       596 croak "Missing arguments hash.\n" unless defined $args;
28 222 100       680 croak "Arguments not supplied as a hash reference.\n" unless 'HASH' eq ref $args;
29 221         686 _no_unrecognized_parameters( $type, $args );
30              
31             my $self = bless {
32             -allns => 0,
33             color => '#000',
34             -sized => 1,
35 221         517 %{$args},
  221         968  
36             }, $class;
37              
38 221         737 $self->_validate_pos_param( 'height', 12 );
39 219         629 $self->_validate_pos_param( 'width', 0 );
40 217         534 $self->_validate_pos_param( 'xscale' );
41 215         509 $self->_validate_pos_param( 'yscale' );
42 215         532 $self->_validate_nonneg_param( 'pady', 1 );
43 214         489 $self->_validate_nonneg_param( 'padx', 0 );
44 213         560 $self->_validate_mark_param();
45 203         416 foreach my $arg (qw/color bgcolor/)
46             {
47 405 100       1052 next unless exists $self->{$arg};
48             croak "The value of $arg is not a valid color.\n"
49 212 100       505 unless _is_color( $self->{$arg} );
50             }
51              
52 201         440 $self->{xoff} = -$self->{padx};
53 201         549 $self->_make( $type );
54              
55 170         430 return $self;
56             }
57              
58 0     0 1 0 sub get_height { return $_[0]->{height}; }
59 0     0 1 0 sub get_width { return $_[0]->{width}; }
60              
61             sub to_string
62             {
63 189     189 1 5534 my ($self) = @_;
64 189         576 my $str = $self->{_SVG}->xmlify();
65             # Cleanup
66 189 100       95231 $str =~ s/ xmlns:(?:svg|xlink)="[^"]+"//g unless $self->{'-allns'};
67 189 100       599 unless( $self->{'-sized'} )
68             {
69             # If I try to keep them from being created, default '100%' values
70             # show up instead.
71 6         45 $str =~ s/(]*) height="[^"]+"/$1/;
72 6         38 $str =~ s/(]*) width="[^"]+"/$1/;
73             }
74 189         1257 return $str;
75             }
76              
77             sub _make
78             {
79 201     201   412 my ($self, $type) = @_;
80 201         801 $self->{_SVG} = "SVG::Sparkline::$type"->make( $self );
81 170         361 return;
82             }
83              
84             sub _no_unrecognized_parameters {
85 221     221   494 my ( $type, $args ) = @_;
86 221         516 my $class = "SVG::Sparkline::$type";
87 221         354 foreach my $parm (keys %{$args}) {
  221         754  
88             croak "Parameter '$parm' not recognized for '$type'\n"
89 410 50 66     1349 unless exists $valid_parms{$parm} || $class->valid_param( $parm );
90             }
91 221         489 return;
92             }
93              
94             sub _validate_pos_param
95             {
96 872     872   1549 my ($self, $name, $default) = @_;
97             croak "'$name' must have a positive numeric value.\n"
98 872 100 100     6566 if exists $self->{$name} && $self->{$name} <= 0;
99 866 100       1849 return if exists $self->{$name};
100              
101 835 100       1915 $self->{$name} = $default if defined $default;
102 835         1295 return;
103             }
104              
105             sub _validate_nonneg_param
106             {
107 429     429   785 my ($self, $name, $default) = @_;
108             croak "'$name' must be a non-negative numeric value.\n"
109 429 100 100     1203 if exists $self->{$name} && $self->{$name} < 0;
110 427 100       950 return if exists $self->{$name};
111              
112 405 50       1120 $self->{$name} = $default if defined $default;
113 405         669 return;
114             }
115              
116             sub _validate_mark_param
117             {
118 213     213   405 my ($self) = @_;
119              
120 213 100       552 return unless exists $self->{mark};
121              
122             croak "'mark' parameter must be an array reference.\n"
123 84 100       248 unless 'ARRAY' eq ref $self->{mark};
124             croak "'mark' array parameter must have an even number of elements.\n"
125 83 100       156 unless 0 == (@{$self->{mark}}%2);
  83         247  
126              
127 82         140 my @marks = @{$self->{mark}};
  82         214  
128 82         219 while(@marks)
129             {
130 84         220 my ($index, $color) = splice( @marks, 0, 2 );
131 84 100       530 croak "'$index' is not a valid mark index.\n"
132             unless $index =~ /^(?:first|last|high|low|\d+)$/;
133 77 100       182 croak "'$color' is not a valid mark color.\n"
134             unless _is_color( $color );
135             }
136 74         151 return;
137             }
138              
139             sub _is_color
140             {
141 314     314   10478 my ($color) = @_;
142 314 100       1416 return 1 if $color =~ /^#[[:xdigit:]]{3}$/;
143 101 100       232 return 1 if $color =~ /^#[[:xdigit:]]{6}$/;
144 99 100       223 return 1 if $color =~ /^rgb\(\d+,\d+,\d+\)$/;
145 98 100       224 return 1 if $color =~ /^rgb\(\d+%,\d+%,\d+%\)$/;
146 97 100       492 return 1 if $color =~ /^[[:alpha:]]+$/;
147 18         97 return;
148             }
149              
150             1;
151              
152             __END__