Author: spadkins
Date: Mon Jun 25 14:58:20 2007
New Revision: 9679

Modified:
   p5ee/trunk/App-Widget-ChartDirector/lib/App/Widget/ChartDirector.pm

Log:
improved legends

Modified: p5ee/trunk/App-Widget-ChartDirector/lib/App/Widget/ChartDirector.pm
==============================================================================
--- p5ee/trunk/App-Widget-ChartDirector/lib/App/Widget/ChartDirector.pm 
(original)
+++ p5ee/trunk/App-Widget-ChartDirector/lib/App/Widget/ChartDirector.pm Mon Jun 
25 14:58:20 2007
@@ -14,6 +14,7 @@
 use Date::Parse;  
 #use Data::Dumper;
 use strict;
+use POSIX qw(ceil floor);
 
 =head1 NAME
 
@@ -270,47 +271,57 @@
     }
     
     my $legend_pos = $spec->{legend_pos} || "default"; # Any one from default, 
top or bottom
-    my ($count, $count_uc, @length_y_value, $max_legend_length, 
$num_legend_columns, $legend_width, $margin, $textsize, $number_legend_row );
-    
-    if ($legend_pos eq "top" || $legend_pos eq "bottom") {
-        $count = 0;
-        $count_uc = 0;
-        $max_legend_length = 75;      # This is a nearyby approximation of 
number of characters inside a row in the legends
-        $num_legend_columns = $spec->{num_legend_columns} || 2; 
+    my (@length_y_value, $max_legend_length, $num_legend_columns, 
$legend_width, $margin, $textsize, $number_legend_rows, $length_labels, 
$length_labels_avg);
+    my (@length_all_labels, $diff_largest_and_avg, $gap_legends);
+    if ($legend_pos ne "default") { 
         $legend_width = $width - 2 * $right_margin; 
-        ($margin,$textsize) = (6,10);  
-        
+        ($margin,$textsize) = (6,10);
+        $max_legend_length =  ceil ( $legend_width / ($textsize * 3/4)); # 
This is a nearyby approximation of number of characters inside a row in the 
legends
+        $length_labels = 0;
         foreach my $y_value (@{$spec->{y_labels}}) {
-            push( @length_y_value, length($y_value) );
-            $count++; 
-            $count_uc++ if ($y_value !~ /[a-z]/);
+            $length_labels += length($y_value);
+            push (@length_all_labels, length($y_value) );
         }
-        @length_y_value = sort { $a <=> $b } @length_y_value;
-        $max_legend_length = 40 if ($count == $count_uc); # This is a nearyby 
approximation of number of characters inside a row in the legends
-
-        for (my $cols = 2;$cols <= 8; $cols++) { # Taking min 2 and max. 8 
colums
-            $num_legend_columns  = $cols if ($length_y_value[-1] < 
$max_legend_length / $cols);
+        @length_all_labels = sort { $a <=> $b } @length_all_labels;
+        $length_labels_avg =  ceil ($length_labels / ($#{$spec->{y_labels}} + 
1)); 
+        $diff_largest_and_avg = $length_all_labels[-1] - $length_labels_avg;
+        # Calculation of gap b/w the legends
+        $gap_legends = $margin;
+        if($diff_largest_and_avg > $gap_legends) {
+            $gap_legends += ceil ($diff_largest_and_avg / 2);
         }
-
-        $num_legend_columns  = 2 if ($#{$spec->{y_labels}} < 2);
-        $num_legend_columns  = 3 if ($length_y_value[-1] > $max_legend_length 
/ 2 && $#{$spec->{y_labels}} > 20); 
-
-        $number_legend_row = int ($count / $num_legend_columns);
-        if ($count % $num_legend_columns != 0 )  {
-            $number_legend_row += 1;
+        else {
+            $gap_legends += 1;
+            $gap_legends -= ceil ($diff_largest_and_avg - $gap_legends / 3) if 
($length_labels_avg >= $max_legend_length / 4); # Reduce gap if the average 
length of legends is higher than max. legend length by 4. 
         }
-
-        $height += (($margin + $textsize) * $number_legend_row) + (4 * 
$margin);  
+        # Calculation of number of columns
+        for (my $cols = 1; $cols <= 20; $cols++) { # Taking  min. 1 and max. 
20 columns
+            $num_legend_columns  = $cols if (($length_labels_avg + 
$gap_legends)  < ($max_legend_length / $cols));
+        }
+        $num_legend_columns  += 1  if (($length_labels_avg + $gap_legends)  > 
($max_legend_length / 2)); #Add a new column if the avg. legend length is 
greater than half of the max. permissible length      
+
+        if ($spec->{num_legend_columns} ) {
+            $num_legend_columns  = $spec->{num_legend_columns}; 
+        }
+        do {    
+            $num_legend_columns  += 1 if ($height > (2 * $spec->{height})); 
#If the legend height is greater than max. permissible limit than add a new 
column and the legends will truncate
+            $height = $spec->{height};
+            $number_legend_rows = int (($#{$spec->{y_labels}} + 1) / 
$num_legend_columns);
+            if (($#{$spec->{y_labels}} + 1) % $num_legend_columns != 0 )  {
+                $number_legend_rows += 1;
+            }
+            $height += (($margin + $textsize) * $number_legend_rows) + (4 * 
$margin); 
+        } while ($height > (2 * $spec->{height})); # Max. graph height should 
not be greater than twice of chosen graph height     
 
         if ($#{$spec->{y_labels}} <= 0) {
             $height = $spec->{height};  
         }
-    }
+    }   
     my $c = new XYChart($width, $height);
     
     my $graph_adjusted_height = $height - $spec->{height};
     my ($top_margin_adjusted,$bottom_margin_adjusted);
-    
+
     if ($legend_pos eq "top" ) {
         $top_margin_adjusted    = $top_margin+$graph_adjusted_height;
         $bottom_margin_adjusted = 
$height-$top_margin-$bottom_margin-$graph_adjusted_height;
@@ -326,7 +337,7 @@
     my $plot_area = $c->setPlotArea($left_margin , $top_margin_adjusted,
         $width-$left_margin-$right_margin,
         $bottom_margin_adjusted);
-
+ 
     $plot_area->setBackground(hex($plot_bgcolor), hex($plot_bgcolor));
 
     $c->addTitle($spec->{title}, "arialbd.ttf", 12, hex($titlecolor)) if 
($spec->{title});
@@ -344,16 +355,16 @@
         
         if (($#{$spec->{y_labels}} > 0) && ($legend_pos eq "top" || 
$legend_pos eq "bottom")) { 
             if ($legend_pos eq "top" ) {
-                $legend = $c->addLegend($left_margin/4 + $x_adj, $top_margin + 
$y_adj, 0,"arial.ttf",10);
+                $legend = $c->addLegend($right_margin, $top_margin + $y_adj, 
0,"arial.ttf",10);
             }
             elsif ($legend_pos eq "bottom" ) {
-                $legend = $c->addLegend($left_margin/4 + $x_adj, $height - 
$graph_adjusted_height - $top_margin/4 , 0,"arial.ttf",10);
+                $legend = $c->addLegend($right_margin, $height - 
$graph_adjusted_height - $top_margin/4 , 0,"arial.ttf",10);
             }
             $legend->setBackground(hex($plot_bgcolor)); 
             $legend->setMargin(5);
             $legend->setWidth($legend_width);
             $legend->setCols($num_legend_columns);
-            $legend->setTruncate("",1); 
+            $legend->setTruncate($legend_width,1); 
         }
         else {
             $legend = $c->addLegend($left_margin+$x_adj, $top_margin+$y_adj, 
0);

Reply via email to