Jifty::Plugin::Chart::Renderer::GoogleViz - chart renderer using Google Charts JS


Jifty-Plugin-Chart documentation Contained in the Jifty-Plugin-Chart distribution.

Index


Code Index:

NAME

Top

Jifty::Plugin::Chart::Renderer::GoogleViz - chart renderer using Google Charts JS

init

We need to load Google's JS.

render

load_params

Load the "packages" required for the visualization; define a packages_to_load method which returns a list of them.

render_data

Renders the columns and the data.

add_columns

Adds the columns to the visualization. Each column is a key-value pair; the key is the column's id and the value is either a string (the type) or a hashref. The hashref may specify type and label. If no label is given, the id is used.

It will return a hashref of canonicalized columns.

add_data

Adds the data to the chart. Each data point should be a hash reference of column id to value.

encode_value


Jifty-Plugin-Chart documentation Contained in the Jifty-Plugin-Chart distribution.
package Jifty::Plugin::Chart::Renderer::GoogleViz;
use strict;
use warnings;
use base 'Jifty::Plugin::Chart::Renderer';

use Jifty::JSON 'objToJson';

sub init {
    my $self = shift;

    Jifty->web->add_external_javascript("http://www.google.com/jsapi");
}

sub render {
    my $self = shift;
    my %args = @_;

    my $chart_id = 'chart_' . Jifty->web->serial;
    my $chart_class = $self->chart_class;
    my $load_params = objToJson($self->load_params);
    my $draw_params = objToJson($self->draw_params($args{options}));
    my $callback_name = 'callback_' . Jifty->web->serial;
    
    Jifty->web->out(<< "JS_HEADER");
        <script type="text/javascript">
            google.load('visualization', 1, $load_params);
            google.setOnLoadCallback($callback_name);
            function $callback_name() {
                var data = new google.visualization.DataTable();
JS_HEADER

    $self->render_data(%args);

    Jifty->web->out(<< "JS_FOOTER");
                var chart = new $chart_class(document.getElementById('$chart_id'));
                chart.draw(data, $draw_params);

            }
        </script>
JS_FOOTER

    Jifty->web->out(qq{
                <div
                        style="width: $args{width}; height: $args{height};"
                        id="$chart_id"
                ></div>
        }); #"

    return;
}

sub load_params {
    my $self = shift;

    return {
        packages => [ $self->packages_to_load ],
    };
}

sub render_data {
    my $self = shift;
    my %args = @_;

    my $cols = $self->add_columns(%args);
    $self->add_data(%args, columns => $cols);
}

sub add_columns {
    my $self = shift;
    my %args = @_;

    my $index = 0;
    my @cols = @{ $args{columns} };
    my %canonicalized_columns;

    while (my ($name, $column) = splice @cols, 0, 2) {
        my ($type, $label);
        if (ref($column)) {
            $type  = $column->{type};
            $label = $column->{label};
        }
        else {
            $type = $column;
        }

        $label ||= $name;

        $canonicalized_columns{$name} = {
            type  => $type,
            label => $label,
            index => $index++,
        };

        Jifty->web->out("data.addColumn('$type', '$label', '$name');\n");
    }

    return \%canonicalized_columns;
}

sub add_data {
    my $self = shift;
    my %args = @_;

    my @data = @{ $args{data} };
    my $cols = $args{columns};

    Jifty->web->out('data.addRows(' . scalar(@data) . ");\n");

    my $row = 0;
    for my $datapoint (@data) {
        for my $column (keys %$datapoint) {
            my $col = $cols->{$column}
                or die "Invalid column id '$column'";

            my $value = $self->encode_value(
                value  => $datapoint->{$column},
                column => $col,
            );
            my $cid = $col->{index};

            Jifty->web->out("data.setValue($row, $cid, $value);\n");
        }

        ++$row;
    }
}

sub encode_value {
    my $self = shift;
    my %args = @_;

    my $value  = $args{value};
    my $column = $args{column};

    if ($column->{type} eq 'date') {
        if (!ref($value)) {
            $value = Jifty::DateTime->new_from_string($value);
        }

        if (ref($value)) {
            if ($value->isa('Jifty::DateTime') && $value->is_date) {
                return sprintf 'new Date(%d, %d, %d)',
                    $value->year,
                    $value->month - 1,
                    $value->day;
            }
            elsif ($value->isa('DateTime')) {
                return sprintf 'new Date(%d, %d, %d, %d, %d, %d)',
                    $value->year,
                    $value->month - 1,
                    $value->day,
                    $value->hour,
                    $value->minute,
                    $value->second;
            }
        }

        die "Can't handle the date '$value'";
    }

    return objToJson($value);
}

1;