Permalink
Browse files

First release

  • Loading branch information...
1 parent bb94453 commit fc0ece89d96e2f702dc33d11c0009b50bd489717 sheriff committed Mar 1, 2010
Showing with 1,078 additions and 0 deletions.
  1. +3 −0 CHANGES
  2. +11 −0 MANIFEST
  3. +11 −0 Makefile.PL
  4. +183 −0 README
  5. +1 −0 TODO
  6. +57 −0 eg/twitter.cgi
  7. +18 −0 eg/twitter.tt2
  8. +597 −0 lib/Data/Google/Visualization/DataTable.pm
  9. +7 −0 t/000_use.t
  10. +111 −0 t/010_add_columns.t
  11. +79 −0 t/020_common_exceptions.t
View
@@ -0,0 +1,3 @@
+0.01 Mon Mar 01 12:50:00 2010
+ - Initial release
+
View
@@ -0,0 +1,11 @@
+eg/twitter.cgi
+eg/twitter.tt2
+README
+TODO
+t/000_use.t
+t/010_add_columns.t
+t/020_common_exceptions.t
+Makefile.PL
+lib/Data/Google/Visualization/DataTable.pm
+MANIFEST
+CHANGES
View
@@ -0,0 +1,11 @@
+use ExtUtils::MakeMaker;
+
+&WriteMakefile(
+ NAME => 'Data::Google::Visualization::DataTable',
+ DISTNAME => 'Data-Google-Visualization-DataTable',
+ VERSION_FROM => 'lib/Data/Google/Visualization/DataTable.pm',
+ PREREQ_PM => {
+ 'JSON::XS' => '2.0',
+ }
+);
+
View
183 README
@@ -0,0 +1,183 @@
+NAME
+ Data::Google::Visualization::DataTable - Easily create Google DataTable
+ objects
+
+DESCRIPTION
+ Easily create Google DataTable objects without worrying too much about
+ typed data
+
+OVERVIEW
+ Google's excellent Visualization suite requires you to format your
+ Javascript data very carefully. It's entirely possible to do this by
+ hand, especially with the help of the most excellent JSON::XS but it's a
+ bit fiddly, largely because Perl doesn't natively support data types and
+ Google's API accepts a super-set of JSON.
+
+ This module is attempts to hide the gory details of preparing your data
+ before sending it to a JSON serializer - more specifically, hiding some
+ of the hoops that have to be jump through for making sure your data
+ serializes to the right data types.
+
+ More about the <Google Visualization API>.
+
+ Every effort has been made to keep naming conventions as close as
+ possible to those in the API itself.
+
+ To use this module, a reasonable knowledge of Perl is assumed. You
+ should be familiar with Perl references and Perl objects.
+
+SYNOPSIS
+ use Data::Google::Visualization::DataTable;
+
+ my $datatable = Data::Google::Visualization::DataTable->new();
+
+ $datatable->add_columns(
+ { id => 'date', label => "A Date", type => 'date', p => {}},
+ { id => 'datetime', label => "A Datetime", type => 'datetime' },
+ { id => 'timeofday',label => "A Time of Day", type => 'timeofday' },
+ { id => 'bool', label => "True or False", type => 'boolean' },
+ { id => 'number', label => "Number", type => 'number' },
+ { id => 'string', label => "Some String", type => 'string' },
+ );
+
+ $datatable->add_rows(
+
+ # Add as array-refs
+ [
+ { v => DateTime->new() },
+ { v => Time::Piece->new(), f => "Right now!" },
+ { v => [6, 12, 1], f => '06:12:01' },
+ { v => 1, f => 'YES' },
+ 15.6, # If you're getting lazy
+ { v => 'foobar', f => 'Foo Bar', p => { display => 'none' } },
+ ],
+
+ # And/or as hash-refs (but only if you defined id's for each of your columns)
+ {
+ date => DateTime->new(),
+ datetime => { v => Time::Piece->new(), f => "Right now!" },
+ timeofday => [6, 12, 1],
+ bool => 1,
+ number => 15.6,
+ string => { v => 'foobar', f => 'Foo Bar' },
+ },
+
+ );
+
+ # Get the data...
+
+ # Fancy-pants
+ my $output = $self->output_json(
+ columns => ['date','number','string' ],
+ pretty => 1,
+ );
+
+ # Vanilla
+ my $output = $self->output_json();
+
+COLUMNS, ROWS AND CELLS
+ We've tried as far as possible to stay as close as possible to the
+ underlying API, so make sure you've had a good read of: <Google
+ Visualization API>.
+
+ Columns
+ *Columns* are specified using a hashref, and follow exactly the format
+ of the underlying API itself. All of "type", "id", "label", "pattern",
+ and "p" are supported. The contents of "p" will be passed directly to
+ JSON::XS to serialize as a whole.
+
+ Rows
+ A row is either a hash-ref where the keys are column IDs and the values
+ are *cells*, or an array-ref where the values are *cells*.
+
+ Cells
+ *Cells* can be specified in several ways, but the best way is using a
+ hash-ref that exactly conforms to the API. "v" is NOT checked against
+ your data type - but we will attempt to convert it. "f" needs to be a
+ string if you provide it. "p" will be bassed directly to JSON::XS.
+
+ For any of the date-like fields ("date", "datetime", "timeofday"), you
+ can pass in 4 types of values. We accept DateTime objects, Time::Piece
+ objects, epoch seconds (as a string - converted internally using
+ localtime), or an array-ref of values that will be passed directly to
+ the resulting Javascript Date object eg:
+
+ Perl:
+ date => [ 5, 4, 3 ]
+ JS:
+ new Date( 5, 4, 3 )
+
+ Remember that JS dates 0-index the month.
+
+ For non-date fields, if you specify a cell using a string or number,
+ rather than a hashref, that'll be mapped to a cell with "v" set to the
+ string you specified.
+
+ "boolean": we test the value you pass in for truth, the Perl way.
+
+METHODS
+ new
+ Constructor. Accepts no arguments, returns a new object.
+
+ add_columns
+ Accepts zero or more columns, in the format specified above, and adds
+ them to our list of columns. Returns the object. You can't call this
+ method after you've called "add_rows" for the first time.
+
+ add_rows
+ Accepts zero or more rows, either as a list of hash-refs or a list of
+ array-refs. If you've provided hash-refs, we'll map the key name to the
+ column via its ID (you must have given every column an ID if you want to
+ do this, or it'll cause a fatal error).
+
+ If you've provided array-refs, we'll assume each cell belongs in
+ subsequent columns - your array-ref must have the same number of members
+ as you have set columns.
+
+ pedantic
+ We do some data checking for sanity, and we'll issue warnings about
+ things the API considers bad data practice - using reserved words or
+ fancy characters on IDs so far. If you don't want that, simple say:
+
+ $object->pedantic(0);
+
+ Defaults to true.
+
+ json_xs_object
+ You may want to configure your JSON::XS object in some magical way. This
+ is a read/write accessor to it. If you didn't understand that, or why
+ you'd want to do that, you can ignore this method.
+
+ output_json
+ Returns a JSON serialization of your object. You can optionally specify
+ two parameters:
+
+ "pretty" - *bool* - defaults to false - that specifies if you'd like
+ your JSON spread-apart with whitespace. Useful for debugging.
+
+ "columns" - *array-ref of strings* - pick out certain columns only (and
+ in the order you specify). If you don't provide an argument here, we'll
+ use them all and in the order set in "add_columns".
+
+BUG BOUNTY
+ Find a reproducible bug, file a bug report, and I (Peter Sergeant) will
+ donate $10 to The Perl Foundation (or Wikipedia). Feature Requests are
+ not bugs :-) Offer subject to author's discretion...
+
+AUTHOR
+ Peter Sergeant "pete@clueball.com" on behalf of <Investor Dynamics> -
+ *Letting you know what your market is thinking*.
+
+SEE ALSO
+ <Python library that does the same thing>
+
+ JSON::XS - The underlying module
+
+ <Google Visualization API>.
+
+COPYRIGHT
+ Copyright 2010 Investor Dynamics Ltd, some rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the same terms as Perl itself.
+
View
1 TODO
@@ -0,0 +1 @@
+Suggestions welcome: pete@clueball.com
View
@@ -0,0 +1,57 @@
+#!/usr/bin/perl
+
+# Slightly contrived example CGI showing Data::Google::Visualization::DataTable
+# usage.
+
+use strict;
+use warnings;
+
+use Template;
+use DateTime;
+use DateTime::Format::Mail;
+use Net::Twitter::Lite;
+use Data::Google::Visualization::DataTable;
+
+my $template = 'eg/twitter.tt2';
+my @tweeters = qw( PlanetPerl shadowcat_mst perl_api );
+
+my $dt = Data::Google::Visualization::DataTable->new();
+$dt->add_columns(
+ { id => 'name', label => 'Name', type => 'string' },
+ { id => 'followers', label => 'Followers', type => 'number' },
+ { id => 'posted', label => 'Last Updated', type => 'datetime' },
+ { id => 'tweet', label => 'Last Tweet', type => 'string' },
+ { id => 'retweet', label => 'Retweet?', type => 'boolean' },
+);
+
+my $nt = Net::Twitter::Lite->new();
+
+# Get the Twitter Data
+for my $twitter_name ( @tweeters ) {
+
+ # Get the user data
+ my $user = $nt->show_user( $twitter_name );
+
+ my $row = {};
+ $row->{'name'} = { v => $twitter_name, f => $user->{'name'} };
+ $row->{'followers'} = $user->{'followers_count'};
+ $row->{'tweet'} = $user->{'status'}->{'text'};
+ my $raw_posted = $user->{'status'}->{'created_at'};
+ $raw_posted =~ s/^(...) (...) (..) (........) (.....) (....)/$1, $3 $2 $6 $4 $5/;
+ $row->{'posted'} = DateTime::Format::Mail->parse_datetime( $raw_posted );
+ $row->{'retweet'} = (
+ $user->{'status'}->{'in_reply_to_user_id'} ||
+ $user->{'status'}->{'in_reply_to_status_id'} ||
+ $user->{'status'}->{'in_reply_to_screen_name'}
+ ) ? 1 : 0;
+
+ $dt->add_rows( $row );
+}
+
+my $data = $dt->output_json( pretty => 1 );
+
+print "Content-type: text/html\n\n";
+Template->new->process( $template, { data => $data } );
+
+exit;
+
View
@@ -0,0 +1,18 @@
+<html>
+ <head>
+ <script type='text/javascript' src='http://www.google.com/jsapi'></script>
+ <script type='text/javascript'>
+ google.load('visualization', '1', {packages:['table']});
+ google.setOnLoadCallback(drawTable);
+ function drawTable() {
+ var data = new google.visualization.DataTable( [% data %] );
+ var table = new google.visualization.Table(document.getElementById('table_div'));
+ table.draw(data, {showRowNumber: true});
+ }
+ </script>
+ </head>
+
+ <body>
+ <div id='table_div'></div>
+ </body>
+</html>
Oops, something went wrong.

0 comments on commit fc0ece8

Please sign in to comment.