Chart

 view release on metacpan or  search on metacpan

lib/Chart/StackedBars.pm  view on Meta::CPAN


            #cut the bars off, if needed
            if ( $data->[$j][$i] > $self->{'max_val'} )
            {
                $y3 = $y1 - ( ( $self->{'max_val'} - $mod ) * $map );
                $cut = 1;
            }
            elsif ( $data->[$j][$i] < $self->{'min_val'} )
            {
                $y3 = $y1 - ( ( $self->{'min_val'} - $mod ) * $map );
                $cut = 1;
            }
            else
            {
                $cut = 0;
            }

            # draw the bar
            ## y2 and y3 are reversed in some cases because GD's fill
            ## algorithm is lame
            if ( $data->[$j][$i] > 0 )
            {
                $self->{'gd_obj'}->filledRectangle( $x2, $y3, $x3, $y2, $color );
                if ( $self->true( $self->{'imagemap'} ) )
                {
                    $self->{'imagemap_data'}->[$j][$i] = [ $x2, $y3, $x3, $y2 ];
                }
            }
            else
            {
                $self->{'gd_obj'}->filledRectangle( $x2, $y2, $x3, $y3, $color );
                if ( $self->true( $self->{'imagemap'} ) )
                {
                    $self->{'imagemap_data'}->[$j][$i] = [ $x2, $y2, $x3, $y3 ];
                }
            }

            # now outline it. outline red if the bar had been cut off
            unless ($cut)
            {
                $self->{'gd_obj'}->rectangle( $x2, $y2, $x3, $y3, $misccolor );
            }
            else
            {
                $self->{'gd_obj'}->rectangle( $x2, $y2, $x3, $y3, $misccolor );
                $self->{'gd_obj'}->rectangle( $x2, $y1, $x3, $y3, $pink );
            }

            # now bootstrap the y values
            $y2 = $y3;
        }
    }

    # and finaly box it off
    $self->{'gd_obj'}
      ->rectangle( $self->{'curr_x_min'}, $self->{'curr_y_min'}, $self->{'curr_x_max'}, $self->{'curr_y_max'}, $misccolor );
    return;

}

## @fn private _draw_left_legend
sub _draw_left_legend
{
    my $self   = shift;
    my @labels = @{ $self->{'legend_labels'} };
    my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush );
    my $font = $self->{'legend_font'};

    # make sure we're using a real font
    unless ( ( ref($font) ) eq 'GD::Font' )
    {
        croak "The subtitle font you specified isn\'t a GD Font object";
    }

    # get the size of the font
    ( $h, $w ) = ( $font->height, $font->width );

    # get the miscellaneous color
    $misccolor = $self->_color_role_to_index('misc');

    # find out how wide the largest label is
    $width =
      ( 2 * $self->{'text_space'} ) +
      ( $self->{'max_legend_label'} * $w ) +
      $self->{'legend_example_size'} +
      ( 2 * $self->{'legend_space'} );

    # get some base x-y coordinates
    $x1 = $self->{'curr_x_min'};
    $x2 = $self->{'curr_x_min'} + $width;
    $y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
    $y2 =
      $self->{'curr_y_min'} +
      $self->{'graph_border'} +
      $self->{'text_space'} +
      ( $self->{'num_datasets'} * ( $h + $self->{'text_space'} ) ) +
      ( 2 * $self->{'legend_space'} );

    # box the legend off
    $self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );

    # leave that nice space inside the legend box
    $x1 += $self->{'legend_space'};
    $y1 += $self->{'legend_space'} + $self->{'text_space'};

    # now draw the actual legend
    for ( 0 .. $#labels )
    {

        # get the color
        my $c = $self->{'num_datasets'} - $_ - 1;

        # color of the datasets in the legend
        if ( $self->{'dataref'}[1][0] < 0 )
        {
            $color = $self->_color_role_to_index( 'dataset' . $_ );
        }
        else
        {
            $color = $self->_color_role_to_index( 'dataset' . $c );
        }

        # find the x-y coords
        $x2 = $x1;
        $x3 = $x2 + $self->{'legend_example_size'};
        $y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;

        # do the line first
        $self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );

        # reset the brush for points
        $brush = $self->_prepare_brush( $color, 'point', $self->{ 'pointStyle' . $_ } );
        $self->{'gd_obj'}->setBrush($brush);

        # draw the point
        $self->{'gd_obj'}->line( int( ( $x3 + $x2 ) / 2 ), $y2, int( ( $x3 + $x2 ) / 2 ), $y2, gdBrushed );

        # now the label
        $x2 = $x3 + ( 2 * $self->{'text_space'} );
        $y2 -= $h / 2;

        # order of the datasets in the legend
        if ( $self->{'dataref'}[1][0] < 0 )
        {
            $self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_], $color );
        }
        else
        {
            $self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$c], $color );
        }
    }

    # mark off the used space
    $self->{'curr_x_min'} += $width;

    # and return
    return 1;
}

## @fn private _draw_right_legend
sub _draw_right_legend
{
    my $self   = shift;
    my @labels = @{ $self->{'legend_labels'} };
    my ( $x1, $x2, $x3, $y1, $y2, $width, $color, $misccolor, $w, $h, $brush );
    my $font = $self->{'legend_font'};

    # make sure we're using a real font
    unless ( ( ref($font) ) eq 'GD::Font' )
    {
        croak "The subtitle font you specified isn\'t a GD Font object";
    }

    # get the size of the font
    ( $h, $w ) = ( $font->height, $font->width );

    # get the miscellaneous color
    $misccolor = $self->_color_role_to_index('misc');

    # find out how wide the largest label is
    $width =
      ( 2 * $self->{'text_space'} ) +
      ( $self->{'max_legend_label'} * $w ) +
      $self->{'legend_example_size'} +
      ( 2 * $self->{'legend_space'} );

    # get some starting x-y values
    $x1 = $self->{'curr_x_max'} - $width;
    $x2 = $self->{'curr_x_max'};
    $y1 = $self->{'curr_y_min'} + $self->{'graph_border'};
    $y2 =
      $self->{'curr_y_min'} +
      $self->{'graph_border'} +
      $self->{'text_space'} +
      ( $self->{'num_datasets'} * ( $h + $self->{'text_space'} ) ) +
      ( 2 * $self->{'legend_space'} );

    # box the legend off
    $self->{'gd_obj'}->rectangle( $x1, $y1, $x2, $y2, $misccolor );

    # leave that nice space inside the legend box
    $x1 += $self->{'legend_space'};
    $y1 += $self->{'legend_space'} + $self->{'text_space'};

    # now draw the actual legend
    for ( 0 .. $#labels )
    {

        # get the color
        my $c = $self->{'num_datasets'} - $_ - 1;

        # color of the datasets in the legend

        if ( $self->{'dataref'}[1][0] < 0 )
        {
            $color = $self->_color_role_to_index( 'dataset' . $_ );
        }
        else
        {
            $color = $self->_color_role_to_index( 'dataset' . $c );
        }

        # find the x-y coords
        $x2 = $x1;
        $x3 = $x2 + $self->{'legend_example_size'};
        $y2 = $y1 + ( $_ * ( $self->{'text_space'} + $h ) ) + $h / 2;

        # do the line first
        $self->{'gd_obj'}->line( $x2, $y2, $x3, $y2, $color );

        # reset the brush for points
        $brush = $self->_prepare_brush( $color, 'point', $self->{ 'pointStyle' . $_ } );
        $self->{'gd_obj'}->setBrush($brush);

        # draw the point
        $self->{'gd_obj'}->line( int( ( $x3 + $x2 ) / 2 ), $y2, int( ( $x3 + $x2 ) / 2 ), $y2, gdBrushed );

        # now the label
        $x2 = $x3 + ( 2 * $self->{'text_space'} );
        $y2 -= $h / 2;

        # order of the datasets in the legend
        if ( $self->{'dataref'}[1][0] < 0 )
        {
            $self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$_], $color );
        }
        else
        {
            $self->{'gd_obj'}->string( $font, $x2, $y2, $labels[$c], $color );
        }
    }

    # mark off the used space
    $self->{'curr_x_max'} -= $width;

    # and return
    return 1;
}

## be a good module and return 1
1;



( run in 0.616 second using v1.01-cache-2.11-cpan-5837b0d9d2c )