[Jifty-commit] r3822 - in jifty/trunk: . lib/Jifty/Plugin lib/Jifty/Plugin/Chart/Renderer

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Wed Aug 8 00:54:59 EDT 2007


Author: trs
Date: Wed Aug  8 00:54:59 2007
New Revision: 3822

Added:
   jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/XMLSWF.pm
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.pm
   jifty/trunk/lib/Jifty/Plugin/Chart/View.pm

Log:
 r25997 at zot:  tom | 2007-08-08 00:54:25 -0400
 Bunch of updates to the chart plugin
 
     - Refactored dispatcher
     - Added XML SWF renderer
     - Renderers are now passed the configuration hash when init'd
 


Modified: jifty/trunk/lib/Jifty/Plugin/Chart.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/Chart.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/Chart.pm	Wed Aug  8 00:54:59 2007
@@ -76,7 +76,7 @@
     $self->renderers({});
 
     # Load the default renderer
-    $self->renderer( $self->init_renderer($args{renderer}) );
+    $self->renderer( $self->init_renderer( $args{renderer}, %args ) );
 
     push @Jifty::Web::ISA, 'Jifty::Plugin::Chart::Web';
 }
@@ -90,7 +90,7 @@
 =cut
 
 sub init_renderer {
-    my ($self, $renderer_class) = @_;
+    my ( $self, $renderer_class ) = ( shift, shift );
 
     # If it's already an object, just return that
     if ( blessed($renderer_class)
@@ -112,7 +112,7 @@
         or warn $@;
 
     # Initialize the renderer
-    $renderer = $renderer_class->new;
+    $renderer = $renderer_class->new( @_ );
 
     # Remember it
     $self->renderers->{ $renderer_class } = $renderer;

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	Wed Aug  8 00:54:59 2007
@@ -10,70 +10,35 @@
 
 Jifty::Plugin::Chart::Dispatcher - Dispatcher for the chart API plugin
 
-=head1 RULES
-
-=head2 chart/chart/*
-
-Grabs the chart configuration stored in the key indicated in C<$1> and unpacks it using L<YAML>. It then passes it to the L<Jifty::Plugin::Chart::View/chart> template.
-
 =cut
 
-on 'chart/chart/*' => run {
-    # Create a session ID to lookup the chart configuration
-    my $session_id = 'chart_' . $1;
-
-    # Unpack the data and then clear it from the session
-    my $args = Jifty::YAML::Load( Jifty->web->session->get( $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);
+my %classes = (
+    chart       => 'Chart::$TYPE',
+    gd_graph    => 'GD::Graph::$TYPE',
+    xmlswf      => 'XML::Simple',
+);
 
-    # No zeroes! Ba Ba Blacksheep.
-    $args->{width}  ||= 400;
-    $args->{height} ||= 300;
-
-    # Use the "type" to determine which class to use
-    my $class = 'Chart::' . $args->{type};
-
-    # Load that class or die if it does not exist
-    $class->require;
+=head1 RULES
 
-    # Remember the class name for the view
-    $args->{class} = $class;
+=head2 chart/*/*
 
-    # Send them on to chart the chart
-    set 'args' => $args;
-    show 'chart/chart'
-};
+Grabs the chart configuration stored in the key indicated in C<$1> and unpacks it using L<YAML>. It then passes it to the correct L<Jifty::Plugin::Chart::View> template.
 
-=head2 chart/gd_graph/*
+=cut
 
-Grabs the chart configuration stored in the key indicated in C<$1> and unpacks it using L<YAML>. It then passes it to the L<Jifty::Plugin::Chart::View/chart> template.
+on 'chart/*/*' => run {
+    my $renderer = $1;
 
-=cut
+    # No renderer?  Act like a 404.
+    last_rule if not defined $classes{$renderer};
 
-on 'chart/gd_graph/*' => run {
     # Create a session ID to lookup the chart configuration
-    my $session_id = 'chart_' . $1;
+    my $session_id = 'chart_' . $2;
 
     # Unpack the data and then clear it from the session
     my $args = Jifty::YAML::Load( Jifty->web->session->get( $session_id ) );
 
-    # XXX If there are lots of charts, this could asplode
+    # XXX if there are a lot of charts, this could asplode
     #Jifty->web->session->remove( $session_id );
 
     # No data? Act like a 404
@@ -94,8 +59,10 @@
     $args->{width}  ||= 400;
     $args->{height} ||= 300;
 
+    my $class = $classes{$renderer};
+    
     # Use the "type" to determine which class to use
-    my $class = 'GD::Graph::' . $args->{type};
+    $class =~ s/\$TYPE/$args->{type}/g;
 
     # Load that class or die if it does not exist
     $class->require;
@@ -105,7 +72,7 @@
 
     # Send them on to chart the chart
     set 'args' => $args;
-    show 'chart/gd_graph'
+    show "chart/$renderer";
 };
 
 =head1 SEE ALSO

Modified: jifty/trunk/lib/Jifty/Plugin/Chart/Renderer.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/Chart/Renderer.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/Chart/Renderer.pm	Wed Aug  8 00:54:59 2007
@@ -50,7 +50,7 @@
 sub new {
     my $class = shift;
     my $self = bless {}, $class;
-    $self->init;
+    $self->init( @_ );
     return $self;
 }
 
@@ -58,7 +58,7 @@
 
   $renderer->init();
 
-This is called by C<new> immediately after constructing the object. Subclasses should implement this method to do any required initialization such as letting Jifty know about required CSS files, JS files, etc.
+This is called by C<new> immediately after constructing the object.  It is passed a param hash from the config file.  Subclasses should implement this method to do any required initialization such as letting Jifty know about required CSS files, JS files, etc.
 
 =cut
 

Added: jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/XMLSWF.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/Chart/Renderer/XMLSWF.pm	Wed Aug  8 00:54:59 2007
@@ -0,0 +1,155 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::Chart::Renderer::XMLSWF;
+use base qw/ Jifty::Plugin::Chart::Renderer /;
+
+use Jifty::YAML;
+
+=head1 NAME
+
+Jifty::Plugin::Chart::Renderer::XMLSWF - A chart renderer using XML SWF charts
+
+=head1 DESCRIPTION
+
+This chart renderer uses the XML SWF charting tools to render charts.
+
+  Plugins:
+    - Chart:
+        renderer: XMLSWF
+        license_key: YOUR_OPTIONAL_LICENSE_KEY
+
+=head1 METHODS
+
+=head2 init
+
+Save the license key, if any
+
+=cut
+
+our $LICENSE = "";
+
+sub init {
+    my $self = shift;
+    my %args = ( @_ );
+
+    if ( defined $args{license_key} ) {
+        $LICENSE = $args{license_key};
+    }
+}
+
+=head2 render
+
+Implemented the L<Jifty::Plugin::Chart::Renderer/render> method interface.
+
+=cut
+
+sub render {
+    my $self = shift;
+    my %args = (
+        bgcolor => '#ffffff',
+        align   => 'left',
+        wmode   => 'transparent',
+        @_
+    );
+
+    # Conversion from generic types to XML SWF types -- incomplete
+    my %types = (
+        'bars'           => 'column',
+        'stackedbars'    => 'stacked column',
+        'horizontalbars' => 'bar',
+        'lines'          => 'line',
+        'pie'            => '3d pie',
+        'points'         => 'scatter',
+    );
+
+    # Make sure the type is ready to be used
+    $args{type} = $types{ $args{type} } || undef;
+
+    # Save the data for retrieval from the session later
+    my $chart_id   = Jifty->web->serial;
+    my $session_id = 'chart_' . $chart_id;
+    Jifty->web->session->set( $session_id => Jifty::YAML::Dump(\%args) );
+
+    # Build up the chart tag
+    my $src = '/static/flash/xmlswf/charts.swf?';
+
+    my $query = Jifty->web->query_string(
+                    library_path => '/static/flash/xmlswf/charts_library',
+                    xml_source   => "/chart/xmlswf/$chart_id",
+                    license      => $LICENSE
+                );
+    $query =~ s/;/&/g;
+    $src .= $query;
+
+    my $tags = {
+        embed => {
+            src             => $src,
+            quality         => 'high',
+            bgcolor         => $args{bgcolor},
+            width           => $args{width},
+            height          => $args{height},
+            name            => $session_id,
+            align           => $args{align},
+            wmode           => $args{wmode},
+            type            => 'application/x-shockwave-flash',
+            swLiveConnect   => 'true',
+            pluginspage     => 'http://www.macromedia.com/go/getflashplayer',
+        },
+        object => {
+            classid     => 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000',
+            codebase    => 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0',
+            width       => $args{width},
+            height      => $args{height},
+            id          => $session_id,
+            class       => join( ' ', @{$args{class}} ),
+            align       => $args{align},
+        },
+        params  => {
+            movie   => $src,
+            quality => 'high',
+            bgcolor => $args{bgcolor},
+            wmode   => $args{wmode},
+        },
+    };
+
+    my $html = "<div>\n";
+    $html .= "<object";
+    $html .= qq[ $_="@{[$tags->{object}{$_}]}"]
+        for keys %{ $tags->{object} };
+    $html .= ">\n";
+
+    $html .= qq[<param name="$_" value="@{[$tags->{params}{$_}]}" />\n] # /damn vim
+        for keys %{ $tags->{params} };
+
+    $html .= "<embed";
+    $html .= qq[ $_="@{[$tags->{embed}{$_}]}"]
+        for keys %{ $tags->{embed} };
+    $html .= "></embed>\n";
+    $html .= "</object>\n";
+    $html .= "</div>\n";
+
+    # Output the HTML and include the chart's configuration key
+    Jifty->web->out($html);
+
+    # Make sure we don't return anything that will get output
+    return;
+}
+
+=head1 SEE ALSO
+
+L<Jifty::Plugin::Chart>, L<Jifty::Plugin::Chart::Renderer>
+
+=head1 AUTHOR
+
+Thomas Sibley
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 Best Practical Solutions, LLC
+
+This is free software and may be modified and distributed under the same terms as Perl itself.
+
+=cut
+
+1;

Modified: jifty/trunk/lib/Jifty/Plugin/Chart/View.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/Chart/View.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/Chart/View.pm	Wed Aug  8 00:54:59 2007
@@ -71,6 +71,56 @@
     }
 };
 
+=head2 chart/xmlswf
+
+This shows a chart using XML SWF. It expects to find the arguments in the C<args> parameter, which is setup for it in L<Jifty::Plugin::Chart::Dispatcher>.
+
+This will output an XML source file unless there is an error building the chart.
+
+=cut
+
+template 'chart/xmlswf' => sub {
+    # Load the arguments
+    my $args = get 'args';
+
+    # Set the output type to the XML file type
+    Jifty->handler->apache->content_type('application/xml');
+
+    # The KeyAttr thing is a bloody hack to get ordering right
+    my $xml = $args->{class}->new(
+        RootName => 'chart',
+        KeyAttr  => { row => '+string' }
+    );
+
+    my $labels = shift @{ $args->{data} };
+
+    # Base chart options
+    my %chart = (
+        chart_type       => { content => $args->{type} },
+        axis_category    => { size => '11', color => '808080' },
+        axis_value       => { size => '11', color => '808080' },
+        axis_ticks       => { major_color => '808080' },
+        legend_label     => { size => '11' },
+        chart_value      => { position => 'cursor', size => '11', color => '666666' },
+        %{ $args->{options} },
+        chart_data       => {
+            row => [
+                {
+                    string => [ {}, @$labels ],
+                },
+            ],
+        },
+    );
+
+    for my $i ( 0 .. $#{ $args->{data} } ) {
+        push @{$chart{'chart_data'}{'row'}}, {
+            string => [ $args->{legend}[$i] || {} ],
+            number => $args->{data}[$i],
+        };
+    }
+
+    outs_raw( $xml->XMLout( \%chart ) );
+};
 =head1 SEE ALSO
 
 L<Jifty::Plugin::Chart::Dispatcher>


More information about the Jifty-commit mailing list