SVG-Template-Graph

 view release on metacpan or  search on metacpan

lib/SVG/Template/Graph.pm  view on Meta::CPAN

If type is defined, an element of $type with %attributes is defined.


 my $svg_element = $tt->_gg ($id)
 my $svg_element = $tt->_gg ($id,'rect',width=>10,height=>10,
		x=>10,y=>10,fill=>'none',stroke=>'red')

=cut

sub _gg ($$;@) {
    my $self  = shift;
    my $id    = shift || 'abc';
    my $type  = shift || 'group';
    my %attrs = @_;
    return $self->{_IDCACHE_}->{$id} if $self->{_IDCACHE_}->{$id};
    my $d = $self->D()
      || confess("E1000: Supplied SVG input  not properly parsed!!");
    my $tg = $d->getElementByID($id);
    unless ($tg) {

        carp("element $type with id '$id' not found in document when setting a text field.");
        $d->getRootElement()->comment("missing group $id added by pid $$ $0");
        $tg = $d->getRootElement()->element( $type, id => $id, %attrs );

       #        carp("element $type with id '$id' created under root element ");
    }
    $self->{_IDCACHE_}->{$id} = $tg;

    #print STDERR "Saving $tg to IDCACHE $id\n";
    return $tg;
}

=head2 _setAxisText

Internal method called by setGraphTitle and setAxisTitle to do the actual work. Not really intended to be accessed from the outside but available for advanced users.

 $tt->_setAxisText ($id,$text|\@text,%attributes)

=cut

sub _setAxisText ($$$;@) {
    my $self = shift;
    my $id   = shift;
    my $text = shift;
    my %attrs;
    %attrs = @_;

    #check if we have an array of strings
    $text = [$text] unless ( ref($text) eq 'ARRAY' );

    carp(
"No text was supplied. Either supply a string or an array reference containing strings"
      )
      unless scalar @$text;
    my $tg = $self->_gg($id);
    my $to = $tg->text(%attrs)
      || carp("Failed to generate an Axis text element within group '$id'.");
    my %args = ( x => 0 );

    foreach my $line (@$text) {
        $to->tspan(%args)->cdata($line)
          || carp(
            "Failed to generate an Axis tspan element within group '$id'.");

        #set the dy spacing for multi-line text
        $args{dy} = '1em';
    }
    return $to;
}

=head2 struct $struct 

the input structure required by sub drawTraces to generate the graph.
Refer to the examples included in this distribution in the examples
directory for working samples.

 $struct = [{
	'tracetype' => 'linegraph',
        'title'=> '1: Trace 1',
        'data' => #hash ref containing x-val and y-val array refs
                {
                'x_val' =>
                        [0, 2, 4, 
			6, 8, 10,
			12,14,16,
			18,20],
                'y_val' =>
                        [4, 2, 5, 
			3, 7, 4 , 
			9, 9, 2, 
			4, 3],
                },
        'format' =>
                {
                'x_max' => 600, #or for your case, the date value of the 1st point
                'x_min' => 0, #or for your case, the date value of the last point
                'y_max' => 0.35,
                'y_min' => -0.1,
                'x_title' => 'Calendar Year',
                'y_title' => '% Annual Performance',
		'x_axis' => 0, # do not automatically draw an x-axis
		'y_axis' => 1, #automatically draw a y-axis
                
		#define the labels that provide
                #the data context.
                'labels' =>
                        {
                        #for year labels, we have to center the axis markers
                        'x_ticks' =>
                                {
                                'label'         =>[2002,2003,2004],
                                'position'      =>[100,300,500],
                                },
                        y_ticks =>
                                {
                                #tick mark label
                                'label' => [ '-10.00%', '-5.00%', '0.00%',
					 '5.00%', '10.00%', '15.00%', 
					'20.00%', '25.00%', '30.00%', 
					'35.00%' ],
                                #tick mark location in the data space

lib/SVG/Template/Graph.pm  view on Meta::CPAN

    #convert to canvas values
    #$self->{grid}->{line}->{"c$o"} = $o eq 'y' ?
    #	$t->mapY($self->{grid}->{line}->{"d$o"} :
    #	$t->mapX($x_line);

    #handle the front and back ticks
    my %hash;
    if ( $tick->[0] ) {
        my ( $x, $y ) = ( $self->T->cx0, $self->T->cy0 );
        %hash = (

            y1 => $o eq 'y' ? $self->{grid}->{line}->{cy} : $y,
            y2 => $o eq 'y' ? $self->{grid}->{line}->{cy} : $y - $tick->[0],
            x1 => $o eq 'y' ? $x : $self->{grid}->{line}->{cx},
            x2 => $o eq 'y' ? $x - $tick->[0] : $self->{grid}->{line}->{cx},
        );
        $args->{anchor}->line( %hash, %attrs );
    }
    if ( $tick->[1] ) {
        my ( $x, $y ) = ( $self->T->cx1, $self->T->cy1 );
        %hash = (

            y1 => $o eq 'y' ? $self->{grid}->{line}->{cy} : $y,
            y2 => $o eq 'y' ? $self->{grid}->{line}->{cy} : $y + $tick->[1],
            x1 => $o eq 'y' ? $x : $self->{grid}->{line}->{cx},
            x2 => $o eq 'y' ? $x + $tick->[1] : $self->{grid}->{line}->{cx},
        );
        $args->{anchor}->line( %hash, %attrs );
    }
}

=head2 drawGridLabel()

grid lable generator 

=cut

sub drawGridLabel ($$$$) {
    my $self = shift;
    my $o    = shift;
    my $i    = shift;
    my $args = shift;

    my $c      = $self->{grid}->{line}->{"c$o"};
    my $d      = $self->{grid}->{line}->{"d$o"};
    my $string =
      defined $args->{grid}->{"${o}_u"}
      ? $self->{grid}->{"${o}_l"}->[$i] . " " . $args->{grid}->{"${o}_u"}
      : $self->{grid}->{"${o}_l"}->[$i];

    #decide what to print as a gridline label
    my $thistext = defined $self->{grid}->{"${o}_l"}
      ?    #if labels are defined
      $string
      : $self->{grid}->{line}->{"d$o"};    #use data positions instead
    $thistext =~ s/\s$//;

    return $o eq 'y'
      ? $args->{anchor}
      ->text( y => $self->{grid}->{line}->{cy}, x => $self->T->cx0, )
      ->cdata($thistext)
      : $args->{anchor}
      ->text( x => $self->{grid}->{line}->{cx}, y => $self->T->cy0, )
      ->cdata($thistext);

    #	$args->{anchor}->line(
    #		y1=> $o eq 'y' ? $self->{grid}->{line}->{cy} : $t->cy0,
    #		x1=> $o eq 'y' ? $t->cx0 : $self->{grid}->{line}->{cx},
    #		y2=> $o eq 'y' ? $self->{grid}->{line}->{cy} : $t->cy1,
    #		x2=> $o eq 'y' ? $t->cx1 : $self->{grid}->{line}->{y},
    #		);

}

=head2 getTick($label_ref $oation)

return the front and back extensions to lines based on the definition (or lack of) tickmarks in the label construct

Example of a label definition: 

    $label = {
        'y_ticks' => {
             'style' => {
                  'right' => '10'
              },
             'position' => [
                  '150',
                  '100',
                  '0',
                  '-75'
              ],
             'label' => [
                  'Much',
                  'Some',
                  'None',
                  'Lost'
              ]
         },
         'x_ticks' => {}
     };

=cut

sub getTick($$$) {
    my $self = shift;
    my $l    = shift;
    my $o    = shift;
    $o = lc($o);
    $o = 'x' unless $o eq 'y';

    my $extender = [ 0, 0 ];

    return undef unless defined $l->{"${o}_ticks"}->{style};

    my %map = (
        x => [ 'top',  'bottom' ],
        y => [ 'left', 'right' ]
    );

    my $one = $map{$o}->[0];
    my $two = $map{$o}->[1];

    #handle constant-x (vertical) gridlines
    $extender->[0] =



( run in 2.559 seconds using v1.01-cache-2.11-cpan-2398b32b56e )