[Jifty-commit] r3767 - in jifty/trunk: . lib/Jifty/Plugin lib/Jifty/Plugin/Chart lib/Jifty/Plugin/Chart/Renderer/GD share/plugins/Jifty/Plugin/Chart/web/static/js t/TestApp-Plugin-Chart/lib/TestApp/Plugin/Chart t/TestApp-Plugin-Chart/t

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Fri Aug 3 12:10:44 EDT 2007


Author: sterling
Date: Fri Aug  3 12:10:43 2007
New Revision: 3767

Added:
   jifty/trunk/share/plugins/Jifty/Plugin/Chart/web/static/js/chart_img_behaviour.js
Modified:
   jifty/trunk/   (props changed)
   jifty/trunk/lib/Jifty/Plugin/Chart.pm
   jifty/trunk/lib/Jifty/Plugin/Chart/Dispatcher.pm
   jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/Chart.pm
   jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/GD/Graph.pm
   jifty/trunk/lib/Jifty/Plugin/Chart/Web.pm
   jifty/trunk/t/TestApp-Plugin-Chart/lib/TestApp/Plugin/Chart/View.pm
   jifty/trunk/t/TestApp-Plugin-Chart/t/chart.t
   jifty/trunk/t/TestApp-Plugin-Chart/t/gd_graph.t

Log:
 r8325 at riddle:  andrew | 2007-08-03 11:09:49 -0500
 Making the IMG-based chart renderers capable of handling CSS styling with some added behaviour.


Modified: jifty/trunk/lib/Jifty/Plugin/Chart.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/Chart.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/Chart.pm	Fri Aug  3 12:10:43 2007
@@ -90,6 +90,10 @@
         ));
     }
 
+    else {
+        Jifty->web->add_javascript('chart_img_behaviour.js');
+    }
+
     push @Jifty::Web::ISA, 'Jifty::Plugin::Chart::Web';
 }
 

Modified: jifty/trunk/lib/Jifty/Plugin/Chart/Dispatcher.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/Chart/Dispatcher.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/Chart/Dispatcher.pm	Fri Aug  3 12:10:43 2007
@@ -24,11 +24,24 @@
 
     # Unpack the data and then clear it from the session
     my $args = Jifty::YAML::Load( Jifty->web->session->get( $session_id ) );
-    Jifty->web->session->remove( $session_id );
+
+    # XXX if there are a lot of charts, this could asplode
+    #Jifty->web->session->remove( $session_id );
 
     # No data? Act like a 404
     last_rule unless defined $args;
 
+    # Request might override width/height:
+    $args->{width}  = get 'width'  if get 'width';
+    $args->{height} = get 'height' if get 'height';
+
+    # XXX TODO Is there a better way to guess the pixel heights when using CSS
+    # heights initially?
+
+    # Remove 'px' from width/height and set to 400/300 if not in pixels
+    ($args->{width}  =~ s/px$//) or ($args->{width}  = 400);
+    ($args->{height} =~ s/px$//) or ($args->{height} = 300);
+
     # Use the "type" to determine which class to use
     my $class = 'Chart::' . $args->{type};
 
@@ -55,11 +68,24 @@
 
     # Unpack the data and then clear it from the session
     my $args = Jifty::YAML::Load( Jifty->web->session->get( $session_id ) );
-    Jifty->web->session->remove( $session_id );
+
+    # XXX If there are lots of charts, this could asplode
+    #Jifty->web->session->remove( $session_id );
 
     # No data? Act like a 404
     last_rule unless defined $args;
 
+    # Request might override width/height:
+    $args->{width}  = get 'width'  if get 'width';
+    $args->{height} = get 'height' if get 'height';
+
+    # XXX TODO Is there a better way to guess the pixel heights when using CSS
+    # heights initially?
+
+    # Remove 'px' from width/height and set to 400/300 if not in pixels
+    ($args->{width}  =~ s/px$//) or ($args->{width}  = 400);
+    ($args->{height} =~ s/px$//) or ($args->{height} = 300);
+
     # Use the "type" to determine which class to use
     my $class = 'GD::Graph::' . $args->{type};
 

Modified: jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/Chart.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/Chart.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/Chart.pm	Fri Aug  3 12:10:43 2007
@@ -34,8 +34,21 @@
     my $session_id = 'chart_' . $chart_id;
     Jifty->web->session->set( $session_id => Jifty::YAML::Dump(\%args) );
 
+    # Build up the chart tag
+    my $img;
+    $img  = qq{<img};
+    $img .= qq{ src="/chart/chart/$chart_id"};
+    $img .= qq{ class="@{[ join ' ', @{ $args{class} } ]}"};
+
+    my @styles;
+    push @styles, "width:$args{width}"   if defined $args{width};
+    push @styles, "height:$args{height}" if defined $args{height};
+
+    $img .= qq{ style="@{[ join ';', @styles ]}"} if @styles;
+    $img .= qq{/>};
+    
     # Output the <img> tag and include the chart's configuration key
-    Jifty->web->out(qq{<img src="/chart/chart/$chart_id" width="$args{width}" height="$args{height}"/>});
+    Jifty->web->out($img);
 
     # Make sure we don't return anything that will get output
     return;

Modified: jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/GD/Graph.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/GD/Graph.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/GD/Graph.pm	Fri Aug  3 12:10:43 2007
@@ -40,8 +40,21 @@
     my $session_id = 'chart_' . $chart_id;
     Jifty->web->session->set( $session_id => Jifty::YAML::Dump(\%args) );
 
+    # Build up the chart tag
+    my $img;
+    $img  = qq{<img};
+    $img .= qq{ src="/chart/gd_graph/$chart_id"};
+    $img .= qq{ class="@{[ join ' ', @{ $args{class} } ]}"};
+
+    my @styles;
+    push @styles, "width:$args{width}"   if defined $args{width};
+    push @styles, "height:$args{height}" if defined $args{height};
+
+    $img .= qq{ style="@{[ join ';', @styles ]}"} if @styles;
+    $img .= qq{/>};
+
     # Output the <img> tag and include the chart's configuration key
-    Jifty->web->out(qq{<img src="/chart/gd_graph/$chart_id" width="$args{width}" height="$args{height}"/>});
+    Jifty->web->out($img);
 
     # Make sure we don't return anything that will get output
     return;

Modified: jifty/trunk/lib/Jifty/Plugin/Chart/Web.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/Chart/Web.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/Chart/Web.pm	Fri Aug  3 12:10:43 2007
@@ -3,6 +3,8 @@
 
 package Jifty::Plugin::Chart::Web;
 
+use Scalar::Util qw/ looks_like_number /;
+
 =head1 NAME
 
 Jifty::Plugin::Chart::Web - Base class to add to Jifty::Web's ISA
@@ -55,11 +57,15 @@
 
 =item width
 
-The width, in pixels, the chart should take on the page. Defaults to 400.
+This is the width the chart should take when rendered. This may be a number, indicating the width in pixels. It may also be any value that would be appropriate for the C<width> CSS property.
+
+Defaults to C<undef>, which indicates that the chart will take on whatever size the box it is in will be. See L</CSS FOR CHARTS>.
 
 =item height
 
-The height, in pixels, the chart should take on the page. Defaults to 300.
+This is the height the chart should take when rendered. This may be a number, indicating the height in pixels. It may also be any value that would be appropriate for the C<height> CSS property.
+
+Defaults to C<undef>, which indicates that the chart will take on whatever size the box it is in will be. See L</CSS FOR CHARTS>.
 
 =item data
 
@@ -67,20 +73,25 @@
 
 Defaults to no data (i.e., it must be given if anything useful is to happen).
 
+=item class
+
+This allows you to associated an additional class or classes to the element containing the chart. This can be a string containing on or more class names separated by spaces or an array of class names.
+
 =back
 
 Here's an example:
 
   <% Jifty->web->chart(
       type   => 'Pie',
-      width  => 400,
-      height => 300,
+      width  => '100%',
+      height => '300px',
       data   => sub {
           [
               [ 2004, 2005, 2006, 2007 ],
               [ 26, 37, 12, 42 ]
           ];
       },
+      class => 'visualizeronimicon',
   ) %>
 
 Be sure to output anything returned by the method (unless it returns undef).
@@ -94,13 +105,26 @@
     # TODO It might be a good idea to make this config.yml-able
     # Setup the defaults
     my %args = (
-        type   => 'points',
-        width  => 400,
-        height => 300,
-        data   => [],
+        type       => 'points',
+        width      => undef,
+        height     => undef,
+        data       => [],
+        class      => [],
         @_,
     );
 
+    # canonicalize the width/height
+    $args{width}  .= 'px' if looks_like_number($args{width});
+    $args{height} .= 'px' if looks_like_number($args{height});
+
+    # canonicalize the class argument
+    if (not ref $args{class}) {
+        $args{class} = defined $args{class} ? [ $args{class} ] : [];
+    }
+
+    # Add the chart class, which is always present
+    push @{ $args{class} }, 'chart';
+
     # Turn any subs into values returned
     for my $key (keys %args) {
         $args{$key} = $args{$key}->(\%args) if ref $args{$key} eq 'CODE';
@@ -110,6 +134,18 @@
     return $plugin->renderer->render(%args);
 }
 
+=head1 CSS FOR CHARTS
+
+The chart API allows you to build the charts without explicit pixel widths and heights. In fact, you can not specify C<width> and C<height> and perform the styling in your regular CSS stylesheets by using the "chart" class associated with every chart or by using custom classes with the C<class> argument.
+
+See your renderer class documentation for further details.
+
+=head1 JAVASCRIPT FOR CHARTS
+
+Charts typically require JavaScript to render properly. If the client does not have JavaScript available, the chart may not work or could look very bad. 
+
+If you are using one of the image based renderers like L<Jifty::Plugin::Chart::Renderer::Chart>, it is recommended that you stick with pixel widths if you expect clients with limited or no JavaScript support. 
+
 =head1 SEE ALSO
 
 L<Jifty::Plugin::Chart>, L<Jifty::Plugin::Chart::Renderer>

Added: jifty/trunk/share/plugins/Jifty/Plugin/Chart/web/static/js/chart_img_behaviour.js
==============================================================================
--- (empty file)
+++ jifty/trunk/share/plugins/Jifty/Plugin/Chart/web/static/js/chart_img_behaviour.js	Fri Aug  3 12:10:43 2007
@@ -0,0 +1,16 @@
+/*
+ * chart_behaviour.js
+ *
+ * Helper to make charts more designer friendly.
+ */
+
+Behaviour.register({
+    'img.chart': function(e) {
+        var dim = Element.getDimensions(e);
+        var url = e.src;
+        url += url.indexOf('?') >= 0 ? '&' : '?';
+        url += 'width=' + dim.width + 'px';
+        url += '&height=' + dim.height + 'px';
+        e.src = url;
+    },
+});

Modified: jifty/trunk/t/TestApp-Plugin-Chart/lib/TestApp/Plugin/Chart/View.pm
==============================================================================
--- jifty/trunk/t/TestApp-Plugin-Chart/lib/TestApp/Plugin/Chart/View.pm	(original)
+++ jifty/trunk/t/TestApp-Plugin-Chart/lib/TestApp/Plugin/Chart/View.pm	Fri Aug  3 12:10:43 2007
@@ -7,8 +7,8 @@
 template '/graphit' => page {
     Jifty->web->chart(
         type   => 'Pie',
-        width  => 400,
-        height => 300,
+        width  => '100%',
+        height => 500,
         data   => sub {
             [
                 [ 2004, 2005, 2006, 2007 ],

Modified: jifty/trunk/t/TestApp-Plugin-Chart/t/chart.t
==============================================================================
--- jifty/trunk/t/TestApp-Plugin-Chart/t/chart.t	(original)
+++ jifty/trunk/t/TestApp-Plugin-Chart/t/chart.t	Fri Aug  3 12:10:43 2007
@@ -33,7 +33,7 @@
 my $mech = Jifty::Test::WWW::Mechanize->new;
 
 $mech->get_ok($url . '/graphit', 'try getting /graphit');
-my $img_match = qr{<img src="(/chart/chart/S\d+)" width="400" height="300"/>};
+my $img_match = qr{<img src="(/chart/chart/S\d+)" };
 $mech->content_like($img_match, 'has an img tag');
 my ($chart_path) = $mech->content =~ $img_match;
 
@@ -53,6 +53,6 @@
 
     is($info->{file_ext}, 'png', 'it is a png file');
     is($info->{width}, 400, 'it is 400 pixels wide');
-    is($info->{height}, 300, 'it is 300 pixels tall');
+    is($info->{height}, 500, 'it is 500 pixels tall');
 };
 

Modified: jifty/trunk/t/TestApp-Plugin-Chart/t/gd_graph.t
==============================================================================
--- jifty/trunk/t/TestApp-Plugin-Chart/t/gd_graph.t	(original)
+++ jifty/trunk/t/TestApp-Plugin-Chart/t/gd_graph.t	Fri Aug  3 12:10:43 2007
@@ -33,7 +33,7 @@
 my $mech = Jifty::Test::WWW::Mechanize->new;
 
 $mech->get_ok($url . '/graphit', 'try getting /graphit');
-my $img_match = qr{<img src="(/chart/gd_graph/S\d+)" width="400" height="300"/>};
+my $img_match = qr{<img src="(/chart/gd_graph/S\d+)" };
 $mech->content_like($img_match, 'has an img tag');
 my ($chart_path) = $mech->content =~ $img_match;
 
@@ -53,6 +53,6 @@
 
     is($info->{file_ext}, 'png', 'it is a png file');
     is($info->{width}, 400, 'it is 400 pixels wide');
-    is($info->{height}, 300, 'it is 300 pixels tall');
+    is($info->{height}, 500, 'it is 500 pixels tall');
 };
 


More information about the Jifty-commit mailing list