File Coverage

File:blib/lib/SVG/Sparkline/RangeArea.pm
Coverage:94.1%

linestmtbrancondsubtimecode
1package SVG::Sparkline::RangeArea;
2
3
3
3
3
16
4
134
use warnings;
4
3
3
3
13
4
75
use strict;
5
3
3
3
14
4
238
use Carp;
6
3
3
3
13
4
68
use SVG;
7
3
3
3
6498
4
54
use SVG::Sparkline::Utils;
8
9
3
3
3
114
6
1072
use 5.008000;
10our $VERSION = 0.35;
11
12# aliases to make calling shorter.
13*_f = *SVG::Sparkline::Utils::format_f;
14
15sub valid_param {
16
0
0
0
0
    return scalar grep { $_[1] eq $_ } qw/xrange yrange/;
17}
18
19sub make
20{
21
21
21
    my ($class, $args) = @_;
22    # validate parameters
23
21
236
    SVG::Sparkline::Utils::validate_array_param( $args, 'values' );
24
81
168
    croak "'values' must be an array of pairs.\n"
25
17
85
17
11
211
20
        if grep { 'ARRAY' ne ref $_ || 2 != @{$_} } @{$args->{values}};
26
81
66
    my $valdesc = SVG::Sparkline::Utils::summarize_xy_values(
27
16
16
81
16
10
16
258
14
        [ (map { $_->[0] } @{$args->{values}}), (reverse map { $_->[1] } @{$args->{values}}) ]
28    );
29
16
16
17
16
    $valdesc->{xrange} = $#{$args->{values}};
30
16
16
11
15
    $valdesc->{xmax} = $#{$args->{values}};
31
16
9
    my $off = $valdesc->{xrange};
32
16
16
16
19
19
27
    foreach my $v (@{$valdesc->{vals}}[($off+1) .. $#{$valdesc->{vals}}])
33    {
34
81
58
        $v->[0] = $off--;
35    }
36
37
16
203
    SVG::Sparkline::Utils::calculate_xscale( $args, $valdesc->{xrange} );
38
16
187
    SVG::Sparkline::Utils::calculate_yscale_and_offset( $args, $valdesc->{yrange}, $valdesc->{offset} );
39
16
191
    my $svg = SVG::Sparkline::Utils::make_svg( $args );
40
41
16
188
    my $points = SVG::Sparkline::Utils::xypairs_to_points_str(
42        $valdesc->{vals}, $args->{xscale}, $args->{yscale}
43    );
44
16
145
    $svg->polygon( fill=>$args->{color}, points=>$points, stroke=>'none' );
45
46
16
664
    if( exists $args->{mark} )
47    {
48
5
9
        _make_marks( $svg,
49            xscale=>$args->{xscale}, yscale=>$args->{yscale},
50            values=>$args->{values}, mark=>$args->{mark},
51            base=>$valdesc->{base}
52        );
53    }
54
55
16
200
    return $svg;
56}
57
58sub _make_marks
59{
60
5
9
    my ($svg, %args) = @_;
61
62
5
5
3
7
    my @marks = @{$args{mark}};
63
5
7
    while(@marks)
64    {
65
5
5
        my ($index,$color) = splice( @marks, 0, 2 );
66
5
59
        $index = SVG::Sparkline::Utils::range_mark_to_index( 'RangeArea', $index, $args{values} );
67
5
9
        _make_mark( $svg, %args, index=>$index, color=>$color );
68    }
69
5
5
    return;
70}
71
72sub _make_mark
73{
74
5
10
    my ($svg, %args) = @_;
75
5
5
    my $index = $args{index};
76
5
5
3
7
    my ($lo, $hi) = @{$args{values}->[$index]};
77
5
58
    my $y = _f( ($lo-$args{base}) * $args{yscale} );
78
5
57
    my $yh = _f( ($hi-$args{base}) * $args{yscale} );
79
5
55
    my $x = _f($index * $args{xscale});
80
81
5
11
    if(abs($hi-$lo) <= 0.01)
82    {
83
0
0
        $svg->circle( cx=>$x, cy=>$y, r=>1, fill=>$args{color}, stroke=>'none' );
84    }
85    else
86    {
87
5
41
        $svg->line( x1=>$x, y1=>$y, x2=>$x, y2=>$yh,
88            fill=>'none', stroke=>$args{color}, 'stroke-width'=>1
89        );
90    }
91
5
250
    return;
92}
93
941; # Magic true value required at end of module