Skip Menu |

This queue is for tickets about the GDGraph CPAN distribution.

Maintainer(s)' notes

There are plenty of good ideas of what people can do published here on the queue. Turning a patch from the tracker into a pull request is not one of them. In order to get maintainers' attention way more quickier, PR should have at least a sample included. We know it's hard to test images generating software, but it doesn't mean we can not test numbers produced by intermediate algorithms used to generate these images, so either a test or a sample.

Report information
The Basics
Id: 24189
Status: open
Priority: 0/
Queue: GDGraph

People
Owner: bwarfield [...] cpan.org
Requestors: rbreiddal [...] presinet.com
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 1.4308
Fixed in: 1.44_01



Subject: PATCH - adds AA and alpha support
This patch adds truecolor, anti-aliasing and alpha support to most types of charts. Truecolor only gets used if you have libgd2 (preferably 2.27+), and I can't guarantee what happens under GD1 if you try to use AA or alpha (I'm guessing it breaks). Mostly the changes to GD::Graph are not very noticeable, although I like the effect it has on area graphs (see http://www.presinet.com/area.png, alpha => 32, aa => 1, otherwise a normal area graph). I haven't gone through it carefully, but I'm pretty sure this patch could be greatly reduced by moving alpha up to the Graph object and having the set_clr family automatically use it (from reading the library source, all calls without alpha are automatically sent to the alpha versions anyways, regardless of palette vs truecolor or anything else). I have also done the same stuff for GD::Graph3d, including improved code for 3d pies (see http://www.presinet.com/new_pie.png). I'll link these two patches together in RT once I've created the other one.
Subject: gdgraph-aaalpha.patch
Index: Graph.pm =================================================================== --- Graph.pm (.../Graph.pm) (revision 24071) +++ Graph.pm (.../GDGraph/trunk/Graph.pm) (working copy) @@ -109,7 +109,7 @@ # # PUBLIC methods, documented in pod. # -sub new # ( width, height ) optional; +sub new # ( width, height, truecolor ) optional; { my $type = shift; my $self = {}; @@ -119,10 +119,12 @@ { # If there are any parameters, they should be the size return GD::Graph->_set_error( - "Usage: GD::Graph::<type>::new(width, height)") unless @_ >= 2; + "Usage: GD::Graph::<type>::new(width, height, truecolor)") unless @_ >= 2; $self->{width} = shift; $self->{height} = shift; + $self->{truecolor} = shift; + $self->{truecolor} = 0 unless defined($self->{truecolor}); } else { @@ -283,10 +285,15 @@ { my $self = shift; return $self->{graph} if exists $self->{graph}; - $self->{graph} = 2.0 <= $GD::VERSION - ? GD::Image->newPalette($self->{width}, $self->{height}) - : GD::Image->new($self->{width}, $self->{height}); - + if (2.0 <= $GD::VERSION){ + if ($self->{truecolor}){ + $self->{graph} = GD::Image->newTrueColor($self->{width}, $self->{height}); + } else { + $self->{graph} = GD::Image->newPalette($self->{width}, $self->{height}); + } + } else { + $self->{graph} = GD::Image->new($self->{width}, $self->{height}); + } } # Initialise the graph output canvas, setting colours (and getting back @@ -298,6 +305,11 @@ my $self = shift; $self->{bgci} = $self->set_clr(_rgb($self->{bgclr})); + if ($self->{truecolor}){ + #fake up the background, since it doesn't work with the first allocated color, + #like in palette based images + $self->{graph}->filledRectangle(0,0,$self->{width},$self->{height},$self->{bgci}); + } $self->{fgci} = $self->set_clr(_rgb($self->{fgclr})); $self->{tci} = $self->set_clr(_rgb($self->{textclr})); $self->{lci} = $self->set_clr(_rgb($self->{labelclr})); @@ -387,6 +399,8 @@ return unless @_; my $gd = $self->{graph}; + return $gd->colorResolveAlpha(@_) if @_ > 3; + # All of this could potentially be done by using colorResolve # The problem is that colorResolve doesn't return an error # condition (-1) if it can't allocate a color. Instead it always @@ -399,13 +413,6 @@ # if this fails, we should use colorClosest. $i = $gd->colorClosest(@_) if $i < 0; - # TODO Deal with antialiasing here? - if (0 && $self->can("setAntiAliased")) - { - $self->setAntiAliased($i); - eval "$i = gdAntiAliased"; - } - return $i; } @@ -435,6 +442,8 @@ { my $self = shift; return unless @_; + + return $self->{graph}->colorAllocateAlpha(@_) if @_ > 3; $self->{graph}->colorAllocate(@_); } @@ -669,13 +678,32 @@ =over 4 -=item GD::Graph::chart-E<gt>new([width,height]) +=item GD::Graph::chart-E<gt>new([width,height,truecolor]) -Create a new object $graph with optional width and heigth. -Default width = 400, default height = 300. I<chart> is either -I<bars>, I<lines>, I<points>, I<linespoints>, I<area>, I<mixed> or -I<pie>. +Create a new object $graph with optional width, height and truecolor. +Default width = 400, default height = 300, default truecolor = 0. +I<chart> is either I<bars>, I<lines>, I<points>, I<linespoints>, +I<area>, I<mixed> or I<pie>. +If you pass a 3rd argument of 1 to the new method, you get a truecolor graph, +instead of palette-based. This opens up some additional options for the +3d graphs: + +=over 4 + +=item alpha + +Sets the alpha channel component of the data point colours. This only has +an effect on things coloured by dclrs. 0 is opaque (default), +becoming more transparent up to 127 (completely transparent). + +=item aa + +1 or 0 (default). If this is set to one, the data points will be +anti-aliased. This will smooth the lines/arcs used to make the graph. + +=back + =item $graph-E<gt>set_text_clr(I<colour name>) Set the colour of the text. This will set the colour of the titles, Index: Graph/area.pm =================================================================== --- Graph/area.pm (revision 24074) +++ Graph/area.pm (working copy) @@ -16,6 +16,7 @@ use strict; use GD::Graph::axestype; +use GD; @GD::Graph::area::ISA = qw( GD::Graph::axestype ); @@ -30,8 +31,14 @@ $self->{_data}->error); # Select a data colour - my $dsci = $self->set_clr($self->pick_data_clr($ds)); - my $brci = $self->set_clr($self->pick_border_clr($ds)); + my $dsci = $self->set_clr($self->pick_data_clr($ds),$self->{alpha}); + my $brci; + my @rgb = $self->pick_border_clr($ds); + if (@rgb > 0){ + $brci = $self->set_clr(@rgb,$self->{alpha}); + } else { + $brci = undef; + } # Create a new polygon my $poly = GD::Polygon->new(); @@ -84,10 +91,19 @@ } # Draw a filled and a line polygon - $self->{graph}->filledPolygon($poly, $dsci) - if defined $dsci; - $self->{graph}->polygon($poly, $brci) - if defined $brci; + if ($self->{aa}){ + $self->{graph}->setAntiAliased($dsci); + $self->{graph}->filledPolygon($poly, gdAntiAliased) + if defined $dsci; + $self->{graph}->setAntiAliased($brci); + $self->{graph}->polygon($poly, gdAntiAliased) + if defined $brci; + } else { + $self->{graph}->filledPolygon($poly, $dsci) + if defined $dsci; + $self->{graph}->polygon($poly, $brci) + if defined $brci; + } # Draw the accent lines if (defined $brci && Index: Graph/lines.pm =================================================================== --- Graph/lines.pm (revision 24074) +++ Graph/lines.pm (working copy) @@ -31,7 +31,7 @@ return $self->_set_error("Impossible illegal data set: $ds", $self->{_data}->error); - my $dsci = $self->set_clr($self->pick_data_clr($ds) ); + my $dsci = $self->set_clr($self->pick_data_clr($ds), $self->{alpha} ); my $type = $self->pick_line_type($ds); my ($xb, $yb); @@ -154,7 +154,12 @@ # Need the setstyle to reset $self->{graph}->setStyle(@pattern) if (@pattern); - $self->{graph}->line( $xs, $yslw, $xe, $yelw, $style ); + if ($self->{aa}){ + $self->{graph}->setAntiAliased($style); + $self->{graph}->line( $xs, $yslw, $xe, $yelw, gdAntiAliased); + } else { + $self->{graph}->line( $xs, $yslw, $xe, $yelw, $style ); + } } } @@ -163,7 +168,7 @@ my $self = shift; my ($n, $x, $y) = @_; - my $ci = $self->set_clr($self->pick_data_clr($n)); + my $ci = $self->set_clr($self->pick_data_clr($n),$self->{alpha}); return unless defined $ci; my $type = $self->pick_line_type($n); Index: Graph/points.pm =================================================================== --- Graph/points.pm (revision 24074) +++ Graph/points.pm (working copy) @@ -31,7 +31,7 @@ $self->{_data}->error); # Pick a colour - my $dsci = $self->set_clr($self->pick_data_clr($ds)); + my $dsci = $self->set_clr($self->pick_data_clr($ds),$self->{alpha}); my $type = $self->pick_marker($ds); for (my $i = 0; $i < @values; $i++) @@ -163,7 +163,7 @@ my $x = shift; my $y = shift; - my $ci = $self->set_clr($self->pick_data_clr($n)); + my $ci = $self->set_clr($self->pick_data_clr($n),$self->{alpha}); my $old_ms = $self->{marker_size}; my $ms = _min($self->{legend_marker_height}, $self->{legend_marker_width}); Index: Graph/bars.pm =================================================================== --- Graph/bars.pm (revision 24074) +++ Graph/bars.pm (working copy) @@ -83,7 +83,7 @@ my $self = shift; my ($ds, $i, $value, $topvalues, $l, $t, $r, $b) = @_; my $bsd = $self->{shadow_depth} or return; - my $bsci = $self->set_clr(_rgb($self->{shadowclr})); + my $bsci = $self->set_clr(_rgb($self->{shadowclr}),$self->{alpha}); if ($self->{cumulate}) { @@ -136,9 +136,15 @@ my $bar_s = $self->{bar_spacing}/2; # Pick a data colour - my $dsci = $self->set_clr($self->pick_data_clr($ds)); + my $dsci = $self->set_clr($self->pick_data_clr($ds),$self->{alpha}); # contrib "Bremford, Mike" <mike.bremford@gs.com> - my $brci = $self->set_clr($self->pick_border_clr($ds)); + my $brci; + my @rgb = $self->pick_border_clr($ds); + if (@rgb > 0){ + $brci = $self->set_clr(@rgb,$self->{alpha}); + } else { + $brci = undef; + } my @values = $self->{_data}->y_values($ds) or return $self->_set_error("Impossible illegal data set: $ds", @@ -159,9 +165,9 @@ # # cycle_clrs option sets the color based on the point, # not the dataset. - $dsci = $self->set_clr($self->pick_data_clr($i + 1)) + $dsci = $self->set_clr($self->pick_data_clr($i + 1),$self->{alpha}) if $self->{cycle_clrs}; - $brci = $self->set_clr($self->pick_data_clr($i + 1)) + $brci = $self->set_clr($self->pick_data_clr($i + 1),$self->{alpha}) if $self->{cycle_clrs} > 1; # get coordinates of right and center of bar @@ -212,9 +218,9 @@ my $bar_s = $self->{bar_spacing}/2; # Pick a data colour - my $dsci = $self->set_clr($self->pick_data_clr($ds)); + my $dsci = $self->set_clr($self->pick_data_clr($ds),$self->{alpha}); # contrib "Bremford, Mike" <mike.bremford@gs.com> - my $brci = $self->set_clr($self->pick_border_clr($ds)); + my $brci = $self->set_clr($self->pick_border_clr($ds),$self->{alpha}); my @values = $self->{_data}->y_values($ds) or return $self->_set_error("Impossible illegal data set: $ds", @@ -242,9 +248,9 @@ # # cycle_clrs option sets the color based on the point, # not the dataset. - $dsci = $self->set_clr($self->pick_data_clr($i + 1)) + $dsci = $self->set_clr($self->pick_data_clr($i + 1),$self->{alpha}) if $self->{cycle_clrs}; - $brci = $self->set_clr($self->pick_data_clr($i + 1)) + $brci = $self->set_clr($self->pick_data_clr($i + 1),$self->{alpha}) if $self->{cycle_clrs} > 1; # get coordinates of top and center of bar Index: Graph/axestype.pm =================================================================== --- Graph/axestype.pm (revision 24074) +++ Graph/axestype.pm (working copy) @@ -147,6 +147,9 @@ borderclrs => undef, + aa => 0, + alpha => 0, + # XXX # Multiple inheritance (linespoints and mixed) finally bit me. The # _has_defaults and set methods can only work correctly when the @@ -2095,7 +2098,7 @@ my $g = $s->{graph}; - my $ci = $s->set_clr($s->pick_data_clr($n)); + my $ci = $s->set_clr($s->pick_data_clr($n),$s->{slpha}); return unless defined $ci; $y += int($s->{lg_el_height}/2 - $s->{legend_marker_height}/2);
From: rbreiddal [...] presinet.com
I forgot to mention that the patch also makes the border color option work as documented in area and bars chart types.
From: rbreiddal [...] presinet.com
GD::Graph3d is where the good stuff is happening... hopefully this can be coordinated somehow :) http://rt.cpan.org/Public/Bug/Display.html?id=24191
From: rbreiddal [...] presinet.com
This revised patch moves a lot of the updated 3d pie code into pie.pm. Now if you set aa => 1 and '3d' => 1, you will get the new stuff, otherwise you'll get what previously existed. Also moved support for legends into pie.pm. See Gd-Graph3d bug for a similarly updated patch.

Message body is not shown because it is too large.

Subject: New GD::Graph co-maintainer and new release on CPAN
Hello, You recieved this message as you filed a bug report or feature request against GD::Graph module on CPAN. My name is Ruslan and I'm new co-maintainer of the module. I've updated the module to 1.45 with doc changes and released it to CPAN. See distribution status [1]. I have TODO list for several releases, so if your ticket was a patch then turning it into a nice pull request may expedite inclusion :) [1] http://search.cpan.org/~ruz/GDGraph-1.45/Graph.pm#DISTRIBUTION_STATUS -- Best regards, Ruslan.