GD-Graph3d

 view release on metacpan or  search on metacpan

lib/GD/Graph/axestype3d.pm  view on Meta::CPAN

# 2000JAN19 Converted to GD::Graph sublcass                              JW
# 2000FEB21 Fixed bug in y-labels' height                                JW
# 2000APR18 Updated for compatibility with GD::Graph 1.30                JW
# 2000AUG21 Added 3d shading                                             JW
# 2000SEP04 Allowed box_clr without box axis                             JW
# 06Dec2001 Fixed bug in rendering of x tick when x_tick_number is set   JW
#==========================================================================
# TODO
#		* Modify to use true 3-d extrusions at any theta and phi
#==========================================================================
package GD::Graph::axestype3d;

use strict;
 
use GD::Graph;
use GD::Graph::axestype;
use GD::Graph::utils qw(:all);
use GD::Graph::colour qw(:colours);
use Carp;

@GD::Graph::axestype3d::ISA = qw(GD::Graph::axestype);
$GD::Graph::axestype3d::VERSION = '0.63';

# Commented inheritance from GD::Graph::axestype unless otherwise noted.

use constant PI => 4 * atan2(1,1);

my %Defaults = (
	depth_3d           => 20,
	'3d_shading'       => 1,

	# the rest are inherited
);

# Inherit _has_default 


# Can't inherit initialise, because %Defaults is referenced file-
# specific, not class specific.
sub initialise
{
	my $self = shift;

	my $rc = $self->SUPER::initialise();

	while( my($key, $val) = each %Defaults ) { 
		$self->{$key} = $val 
	} # end while

	return $rc;
} # end initialise

# PUBLIC
# Inherit plot
# Inherit set
# Inherit setup_text
# Inherit set_x_label_font
# Inherit set_y_label_font
# Inherit set_x_axis_font
# Inherit set_y_axis_font
# Inherit set_legend
# Inherit set_legend_font



# ----------------------------------------------------------
# Sub: init_graph
#
# Args: (None)
#
# Description: 
# Override GD::Graph::init_graph to add 3d shading colors, 
# if requested
#
# [From GD::Graph]
# Initialise the graph output canvas, setting colours (and 
# getting back index numbers for them) setting the graph to 
# transparent, and interlaced, putting a logo (if defined) 
# on there.
# ----------------------------------------------------------
# Date      Modification                              Author
# ----------------------------------------------------------
# 20Aug2000 Added to support 3d graph extensions          JW
# ----------------------------------------------------------
sub init_graph {
	my $self = shift;

	# Sets up the canvas and color palette
	$self->SUPER::init_graph( @_ );	

	# Now create highlights and showdows for each color
	# in the palette
	if( $self->{'3d_shading'} ) {
		$self->{'3d_highlights'} = [];
		$self->{'3d_shadows'} = [];
		$self->{'3d_highlights'}[$self->{bgci}] = $self->set_clr( $self->_brighten( _rgb($self->{bgclr}) ) );
		$self->{'3d_shadows'}[$self->{bgci}]    = $self->set_clr( $self->_darken( _rgb($self->{bgclr}) ) );

		$self->{'3d_highlights'}[$self->{fgci}] = $self->set_clr( $self->_brighten( _rgb($self->{fgclr}) ) );
		$self->{'3d_shadows'}[$self->{fgci}]    = $self->set_clr( $self->_darken( _rgb($self->{fgclr}) ) );

		$self->{'3d_highlights'}[$self->{tci}] = $self->set_clr( $self->_brighten( _rgb($self->{textclr}) ) );
		$self->{'3d_shadows'}[$self->{tci}]    = $self->set_clr( $self->_darken( _rgb($self->{textclr}) ) );

		$self->{'3d_highlights'}[$self->{lci}] = $self->set_clr( $self->_brighten( _rgb($self->{labelclr}) ) );
		$self->{'3d_shadows'}[$self->{lci}]    = $self->set_clr( $self->_darken( _rgb($self->{labelclr}) ) );

		$self->{'3d_highlights'}[$self->{alci}] = $self->set_clr( $self->_brighten( _rgb($self->{axislabelclr}) ) );
		$self->{'3d_shadows'}[$self->{alci}]    = $self->set_clr( $self->_darken( _rgb($self->{axislabelclr}) ) );

		$self->{'3d_highlights'}[$self->{acci}] = $self->set_clr( $self->_brighten( _rgb($self->{accentclr}) ) );
		$self->{'3d_shadows'}[$self->{acci}]    = $self->set_clr( $self->_darken( _rgb($self->{accentclr}) ) );

		$self->{'3d_highlights'}[$self->{valuesci}] = $self->set_clr( $self->_brighten( _rgb($self->{valuesclr}) ) );
		$self->{'3d_shadows'}[$self->{valuesci}]    = $self->set_clr( $self->_darken( _rgb($self->{valuesclr}) ) );

		$self->{'3d_highlights'}[$self->{legendci}] = $self->set_clr( $self->_brighten( _rgb($self->{legendclr}) ) );
		$self->{'3d_shadows'}[$self->{legendci}]    = $self->set_clr( $self->_darken( _rgb($self->{legendclr}) ) );

		if( $self->{boxclr} ) {
			$self->{'3d_highlights'}[$self->{boxci}] = $self->set_clr( $self->_brighten( _rgb($self->{boxclr}) ) );
			$self->{'3d_shadows'}[$self->{boxci}]    = $self->set_clr( $self->_darken( _rgb($self->{boxclr}) ) );
		} # end if
	} # end if

	return $self;
} # end init_graph


# PRIVATE

# ----------------------------------------------------------
# Sub: _brighten
#
# Args: $r, $g, $b
#	$r, $g, $b	The Red, Green, and Blue components of a color
#
# Description: Brightens the color by adding white
# ----------------------------------------------------------
# Date      Modification                              Author
# ----------------------------------------------------------
# 21AUG2000 Created to build 3d highlights table          JW
# ----------------------------------------------------------
sub _brighten {
	my $self = shift;
	my( $r, $g, $b ) = @_;
	my $p = ($r + $g + $b) / 70;
	$p = 3 if $p < 3;
	my $f = _max( $r / $p, _max( $g / $p, $b / $p ) );
	$r = _min( 255, int( $r + $f ) );
	$g = _min( 255, int( $g + $f ) );
	$b = _min( 255, int( $b + $f ) );
	return( $r, $g, $b );
} # end _brighten

# ----------------------------------------------------------
# Sub: _darken
#
# Args: $r, $g, $b
#	$r, $g, $b	The Red, Green, and Blue components of a color
#
# Description: Darkens the color by adding black
# ----------------------------------------------------------
# Date      Modification                              Author
# ----------------------------------------------------------
# 21AUG2000 Created to build 3d shadows table          JW
# ----------------------------------------------------------
sub _darken {
	my $self = shift;
	my( $r, $g, $b ) = @_;
	my $p = ($r + $g + $b) / 70;
	$p = 3 if $p < 3;
	my $f = _max( $r / $p, _max( $g / $p, $b / $p) );
	$r = _max( 0, int( $r - $f ) );
	$g = _max( 0, int( $g - $f ) );
	$b = _max( 0, int( $b - $f ) );
	return( $r, $g, $b );
} # end _darken

lib/GD/Graph/axestype3d.pm  view on Meta::CPAN

				                      $x, 
				                      $y, 
				                      $self->{fgci} 
				);
			}
			else
			{
				$self->{graph}->line($x, $y, 
					$x, $y - $self->{x_tick_length}, $self->{fgci} );
				# CONTRIB Jeremy Wadsack
				# Draw conector ticks
				$self->{graph}->line( $x - $self->{depth_3d}, 
				                      $y + $self->{depth_3d},
				                      $x, - $self->{depth_3d} + $self->{tick_length}, 
				                      $y, + $self->{depth_3d} - $self->{tick_length},
				                      $self->{fgci} 
				);
			} # end if -- x_long_ticks
		} # end if -- x_ticks

		# If we have to skip labels, we'll do it here.
		# Make sure to always draw the last one.
		next if $i % $self->{x_label_skip} && $i != $self->{x_tick_number};

		$self->{gdta_x_axis}->set_text($self->{x_labels}[$i]);

		# CONTRIB Jeremy Wadsack
		# Subtract 3-d extrusion width from left label
		# Add 3-d extrusion height to left label
		# (they were changed for ticks)
		$x -= $self->{depth_3d};
		$y += $self->{depth_3d};

		if ($self->{x_labels_vertical})
		{
			$self->{gdta_x_axis}->set_align('center', 'right');
			my $yt = $y + $self->{text_space}/2;
			$self->{gdta_x_axis}->draw($x, $yt, PI/2);
		}
		else
		{
			$self->{gdta_x_axis}->set_align('top', 'center');
			my $yt = $y + $self->{text_space}/2;
			$self->{gdta_x_axis}->draw($x, $yt);
		} # end if
	} # end for

	return $self;
	
} # end draw_x_tick_number

# Inherit draw_ticks
# Inherit draw_data
# Inherit draw_data_set
# Inherit set_max_min
# Inherit get_max_y
# Inherit get_min_y
# Inherit get_max_min_y_all
# Inherit _get_bottom
# Inherit val_to_pixel
# Inherit setup_legend


# [JW] Override draw_legend and reverse the drawing order
# if cumulate is enabled so legend matches data on chart
sub draw_legend
{
	my $self = shift;

	return unless defined $self->{legend};

	my $xl = $self->{lg_xs} + $self->{legend_spacing};
	my $y  = $self->{lg_ys} + $self->{legend_spacing} - 1;

	# If there's a frame, offset by the size and margin
	$xl += $self->{legend_frame_margin} + $self->{legend_frame_size} if $self->{legend_frame_size};
	$y += $self->{legend_frame_margin} + $self->{legend_frame_size} if $self->{legend_frame_size};

	my $i = 0;
	my $row = 1;
	my $x = $xl;	# start position of current element
	my @legends = @{$self->{legend}};
	my $i_step = 1;
	
	# If we are working in cumulate mode, then reverse the drawing order
	if( $self->{cumulate} ) {
		@legends = reverse @legends;
		$i = scalar(@legends);
		$i = $self->{_data}->num_sets if $self->{_data}->num_sets < $i;
		$i++;
		$i_step = -1;
	} # end if
	
	foreach my $legend (@legends)
	{
		$i += $i_step;

		# Legend for Pie goes over first set, and all points
		# Works in either direction
		last if $i > $self->{_data}->num_sets;
		last if $i < 1;

		my $xe = $x;	# position within an element

		next unless defined($legend) && $legend ne "";

		$self->draw_legend_marker($i, $xe, $y);

		$xe += $self->{legend_marker_width} + $self->{legend_spacing};
		my $ys = int($y + $self->{lg_el_height}/2 - $self->{lgfh}/2);

		$self->{gdta_legend}->set_text($legend);
		$self->{gdta_legend}->draw($xe, $ys);

		$x += $self->{lg_el_width};

		if (++$row > $self->{lg_cols})
		{
			$row = 1;
			$y += $self->{lg_el_height};
			$x = $xl;
		}
	}
	
	# If there's a frame, draw it now
	if( $self->{legend_frame_size} ) {
		$x = $self->{lg_xs} + $self->{legend_spacing};
		$y = $self->{lg_ys} + $self->{legend_spacing} - 1;
		
		for $i ( 0 .. $self->{legend_frame_size} - 1 ) {
			$self->{graph}->rectangle(
				$x + $i,
				$y + $i, 
				$x + $self->{lg_x_size} + 2 * $self->{legend_frame_margin} - $i - 1,
				$y + $self->{lg_y_size} + 2 * $self->{legend_frame_margin} - $i - 1,
				$self->{acci},
			);
		} # end for
	} # end if
	
}



# Inherit draw_legend_marker

1;



( run in 2.146 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )