Apache-GDGraph

 view release on metacpan or  search on metacpan

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


		die <<EOF unless $args;
Please supply arguments in the query string, see the Apache::GD::Graph man
page for details.
EOF

# Calculate Expires header based on either an "expires" parameter, the Expires
# configuration variable (via PerlSetVar) or the EXPIRES constant, in days.
# Then convert into seconds and round to an integer.
		my $expires = exists $args{expires} ?
			sprintf "%.0f", $args{expires} * SECONDS_IN_DAY
			:
			$r->dir_config('Expires') || EXPIRES;

# Determine the type of image that the graph should be.
# Allow an Accept: header with one specific image type to set it, a
# PerlSetVar, or the image_type parameter.
		my $image_type = lc($r->dir_config('ImageType')) || IMAGE_TYPE;

		my $accepts_header = $r->header_in('Accept');
		if (defined $accepts_header and
		    $accepts_header =~ m!^\s*image/(\w+)\s*$!) {
			$image_type = $1;
		}

		$image_type = $args{image_type} if $args{image_type};

		$image_type = 'jpeg' if $image_type eq 'jpg';

		die <<EOF unless GD::Image->can($image_type);
The version of GD installed on this server does not support
image_type $image_type.
EOF

		my $jpeg_quality;
		if ($image_type eq 'jpeg') {
			$jpeg_quality = $args{jpeg_quality} ||
					$r->dir_config('JpegQuality');
		}

		$args{cache} = TRUE if not exists $args{cache};

		if ($args{cache} != FALSE && $cache_size > 0 &&
		   defined(my $cached_image = $image_cache->get($args))) {
			$r->header_out (
				"Expires" => time2str(time + $expires)
			);
			$r->send_http_header (
				"image/$image_type"
			);
			$r->print($cached_image);

			return OK;
		}

		my $type   = delete $args{type}   || DEFAULT_TYPE;
		my $width  = delete $args{width}  || DEFAULT_WIDTH;
		my $height = delete $args{height} || DEFAULT_HEIGHT;

		$type =~ m/^(\w+)$/;
		$type = $1;	# untaint it!

		my @data;
		my $i = 1;
		my $key = "data$i";
		while (exists $args{$key}) {
			my ($type, $array, @rest) = (parse delete $args{$key});
			if ($type == TYPE_LIST) {
				$array = [ $array, @rest ];
			}
			arrayCheck $key, $array;
			push @data, $array;
			$key = "data".(++$i);
		}

		die "Please supply at least a data1 argument."
			if ref $data[0] ne 'ARRAY';

		my $length = scalar @{$data[0]};
		die "data1 empty!" if $length == 0;

		if (exists $args{no_axes}) {
			delete $args{x_labels};
			$args{y_number_format} = "";
			delete $args{no_axes};
		}

		my $x_labels;
		if (exists $args{x_labels}) {
			$x_labels =
				(parse delete $args{x_labels})[1];
		} else {
			$x_labels = undef;
		}
		
# Validate the sizes in order to have a more friendly error.
		if (defined $x_labels) {
			arrayCheck "x_labels" => $x_labels;
			if (scalar @$x_labels != $length) {
				die <<EOF;
Size of x_labels not the same as length of data.
EOF
			}
		} else {
# If x_labels is not an array or empty, fill it with undefs.
			for (1..$length) {
				push @$x_labels, undef;
			}
		}

		my $n = 2;
		for (@data[1..$#data]) {
			if (scalar @$_ != $length) {
				die <<EOF;
Size of data$n does not equal size of data1.
EOF
			}
			$n++;
		}

		my $graph;
		eval {
			no strict 'refs';
			require "GD/Graph/$type.pm";
			$graph = ('GD::Graph::'.$type)->new($width, $height);
		}; if ($@) {
		 die <<EOF;
Could not create an instance of class GD::Graph::$type: $@
EOF
		}

		my $to_file = (parseElement delete $args{to_file})[1];
# Untaint it!
		($to_file) = ($to_file =~ /([\w.\/]+)/);

		for my $option (keys %args) {
			my ($type, $value, @rest) = parse ($args{$option});

			if (my $method = $graph->can("set_$option")) {
				$graph->$method($value, @rest);
			} else {
				if ($type == TYPE_LIST) {
					$value = [ $value, @rest ];
				}
				$args{$option} = $value;
			}

			arrayCheck $option, $value
				if index (ARRAY_OPTIONS, $option) != -1;
		};

# Check if background image specified.
		if (exists $args{background_image}) {
			my $image = new GD::Image($args{background_image});

			die <<EOF if not defined $image;
Could not open your background image: $!
EOF
			$graph->gd->copyResized(
				$image, 0, 0,
				0, 0, $width, $height,
				$image->getBounds
			); 

			delete $args{background_image};
		}

# Check if we need to draw captions, draw them after graph is plotted.
		my @captions;
		$i = 1;
		$key = "caption$i";
		while (exists $args{$key}) {
			die <<EOF unless UNIVERSAL::isa($args{$key}, 'ARRAY');
Caption must be an array. See the Apache::GD::Graph man page or the StringTTF
method in the GD man page for details.
EOF
			push @captions, delete $args{$key};
			$key = "caption".(++$i);
		}

# Style for the special gdStyled color.
		my $gd_style = delete $args{gd_set_style};

		$graph->set(%args);

		my $image = $graph->plot([$x_labels, @data])
			or die <<EOF;
Could not create graph: @{[ $graph->error ]}
EOF

		$image->setStyle (
			map { resolveColor ($graph => $_) }
			@$gd_style



( run in 0.987 second using v1.01-cache-2.11-cpan-39bf76dae61 )