Chart-Clicker

 view release on metacpan or  search on metacpan

lib/Chart/Clicker.pm  view on Meta::CPAN

    isa => 'ArrayRef',
    default => sub { [] },
    handles => {
        'dataset_count' => 'count',
        'add_to_datasets' => 'push',
        'get_dataset' => 'get'
    }
);


has 'driver' => (
    is => 'rw',
    does => 'Graphics::Primitive::Driver',
    default => sub {
        my ($self) = @_;
        my $driver = $ENV{CHART_CLICKER_DEFAULT_DRIVER} || ($^O eq 'MSWin32'?"Graphics::Primitive::Driver::GD":"Graphics::Primitive::Driver::Cairo");
        eval "require $driver;" or die "Cannot load driver $driver";
        $driver->new(
            'format' => $self->format,
        )
    },
    handles => {
        rendered_data => 'data',
        write => 'write'
    },
    lazy => 1
);


has 'format' => (
    is => 'rw',
    isa => 'Str',
    default => 'PNG'
);


has 'plot_mode' => (
    is => 'rw',
    isa => 'Str',
    default => 'slow'
);


has 'grid_over' => (
    is => 'rw',
    isa => 'Bool',
    default => 0
);


has '+height' => (
    default => 300
);


has '+layout_manager' => (
    default => sub { Layout::Manager::Compass->new }
);


has 'legend' => (
    is => 'rw',
    isa => 'Chart::Clicker::Decoration::Legend',
    default => sub {
        Chart::Clicker::Decoration::Legend->new(
            name => 'legend',
        );
    }
);


has 'legend_position' => (
    is => 'rw',
    isa => 'Str',
    default => 's'
);


has 'marker_overlay' => (
    is => 'rw',
    isa => 'Chart::Clicker::Decoration::MarkerOverlay',
    lazy => 1,
    default => sub {
        Chart::Clicker::Decoration::MarkerOverlay->new
    }
);


has 'over_decorations' => (
    traits => [ 'Array' ],
    is => 'rw',
    isa => 'ArrayRef',
    default => sub { [] },
    handles => {
        'over_decoration_count' => 'count',
        'add_to_over_decorations' => 'push',
        'get_over_decoration' => 'get'
    }
);


has '+padding' => (
    default => sub {
        Graphics::Primitive::Insets->new(
            top => 3, bottom => 3, right => 3, left => 3
        )
    }
);


has 'plot' => (
    is => 'rw',
    isa => 'Chart::Clicker::Decoration::Plot',
    default => sub {
        Chart::Clicker::Decoration::Plot->new
    }
);


has 'subgraphs' => (
    is => 'rw',
    isa => 'ArrayRef',
    default => sub { [] },
    predicate => 'has_subgraphs'
);


has 'title' => (
    is => 'rw',
    isa => 'Graphics::Primitive::TextBox',
    default => sub {
        Graphics::Primitive::TextBox->new(

lib/Chart/Clicker.pm  view on Meta::CPAN

                $self->_data->{$name}{$i} = $old_data->[$i];
            }
        }
        for my $key (keys %$data) {
            $self->_data->{$name}{$key} = $data->{$key};
        }
    } else {
        croak "Can't add scalar data after adding hashrefs"
            if ref($self->_data->{$name}) eq 'HASH';
        $self->_data->{$name} = [] unless defined($self->_data->{$name});
        push(@{ $self->_data->{$name}}, $data);
    }
}

override('prepare', sub {
    my ($self, $driver) = @_;

    return if $self->prepared;

    if(scalar(keys(%{ $self->_data }))) {

        my $ds = Chart::Clicker::Data::DataSet->new;
        foreach my $name (keys(%{ $self->_data })) {

            my $vals = $self->_data->{$name};

            if(ref($vals) eq 'ARRAY') {
                # This allows the user to add data as an array

                $ds->add_to_series(
                    Chart::Clicker::Data::Series->new(
                        name    => $name,
                        keys    => [ 0..scalar(@{ $vals }) - 1 ],
                        values  => $vals
                    )
                );
            } elsif(ref($vals) eq 'HASH') {
                # This allows the user to add data as a hashref
                my @keys = sort { $a <=> $b } keys %{ $vals };

                my @values = ();
                foreach my $k (@keys) {
                    push(@values, $vals->{$k})
                }

                $ds->add_to_series(
                    Chart::Clicker::Data::Series->new(
                        name => $name,
                        keys => \@keys,
                        values => \@values
                    )
                );
            }
        }
        $self->add_to_datasets($ds);
    }

    unless(scalar(@{ $self->components })) {
        $self->add_component($self->plot, 'c');

        my $lp = lc($self->legend_position);
        if($self->legend->visible) {
            if(($lp =~ /^e/) || ($lp =~ /^w/)) {
                $self->legend->orientation('vertical');
            }
            $self->add_component($self->legend, $self->legend_position);
        }

        # Add subgraphs
        if($self->has_subgraphs) {
            for my $subgraph (@{$self->subgraphs}) {
                $subgraph->border->width(0);
                $subgraph->padding(0);

                $self->add_component($subgraph, 'south');
            }
        }

        if(defined($self->title->text)) {
            my $tp = $self->title_position;
            if(($tp =~ /^e/) || ($tp =~ /^w/)) {
                unless(defined($self->title->angle)) {
                    $self->title->angle(-1.5707);
                }
            }
            $self->add_component($self->title, $tp);
        }
    }

    my $plot = $self->plot;

    $plot->clear_components;
    $plot->render_area->clear_components;

    # These two adds are here because the plot is too dependant on changes
    # in the axes and such to trust it across multiple prepares.  Putting all
    # of this here made it easier to digest, although this has some codestink
    # to it...
    if($plot->grid->visible && !$self->grid_over) {
        $plot->render_area->add_component($plot->grid, 'c');
    }

    $plot->render_area->add_component(
        $self->marker_overlay
    );

    # Sentinels to control the side that the axes will be drawn on.
    my $dcount = 0;
    my $rcount = 0;
    # Hashes of axes & renderers we've already seen, as we don't want to add
    # them again...
    my %xaxes;
    my %yaxes;

    # A "seen" hash to prevent us from adding multiple renderers for the same
    # context.
    my %rends;

    my $dflt_ctx = $self->get_context('default');
    die('Clicker must have a default context') unless defined($dflt_ctx);

    # Prepare the datasets and establish ranges for the axes.
    my $count = 0;
    foreach my $ds (@{ $self->datasets }) {
        unless($ds->count > 0) {
            die("Dataset $count is empty.");

lib/Chart/Clicker.pm  view on Meta::CPAN

similar things, you can use:

  # ... make your chart
  $cc->draw;
  my $image_data = $cc->rendered_data;

If you happen to be using Catalyst then take a look at
L<Catalyst::View::Graphics::Primitive>.

=head1 ATTRIBUTES

=head2 background_color

Set/Get the background L<color|Graphics::Color::RGB>. Defaults to white.

=head2 border

Set/Get the L<border|Graphics::Primitive::Border>.

=head2 color_allocator

Set/Get the L<color_allocator|Chart::Clicker::Drawing::ColorAllocator> for this chart.

=head2 contexts

Set/Get the L<contexts|Chart::Clicker::Context> for this chart.

=head2 datasets

Get/Set the datasets for this chart.

=head2 driver

Set/Get the L<driver|Graphics::Primitive::Driver> used to render this Chart. Defaults to
L<Graphics::Primitive::Driver::Cairo>.

=head2 format

Get the format for this Chart.  Required in the constructor.  Must be on of
Png, Pdf, Ps or Svg.

=head2 plot_mode

Fast or slow plot mode. When in fast mode, data elements that are deemed to be
superfluous or invisible will not be drawn. Default is 'slow'

=head2 grid_over

Flag controlling if the grid is rendered B<over> the data.  Defaults to 0.
You probably want to set the grid's background color to an alpha of 0 if you
enable this flag.

=head2 height

Set/Get the height.  Defaults to 300.

=head2 layout_manager

Set/Get the layout manager.  Defaults to L<Layout::Manager::Compass>.

=head2 legend

Set/Get the L<legend|Chart::Clicker::Decoration::Legend> that will be used with this chart.

=head2 legend_position

The position the legend will be added.  Should be one of north, south, east,
west or center as required by L<Layout::Manager::Compass>.

=head2 marker_overlay

Set/Get the L<marker overlay|Chart::Clicker::Decoration::MarkerOverlay> object that will be used if this chart
has markers.  This is lazily constructed to save time.

=head2 over_decorations

Set/Get an arrayref of "over decorations", or things that are drawn OVER the
chart.  This is an advanced feature.  See C<overaxis-bar.pl> in the examples.

=head2 padding

Set/Get the L<padding|Graphics::Primitive::Insets>. Defaults
to 3px on all sides.

=head2 plot

Set/Get the L<plot|Chart::Clicker::Decoration::Plot> on which things are drawn.

=head2 subgraphs

You can add "child" graphs to this one via C<add_subgraph>.  These must be
Chart::Clicker objects and they will be added to the bottom of the existing
chart.  This is a rather esoteric feature.

=head2 title

Set/Get the title component for this chart.  This is a
L<Graphics::Primitive::TextBox>, not a string.  To set the title of a chart
you should access the TextBox's C<text> method.

  $cc->title->text('A Title!');
  $cc->title->font->size(20);
  # etc, etc

If the title has text then it is added to the chart in the position specified
by C<title_position>.

You should consult the documentation for L<Graphics::Primitive::TextBox> for
things like padding and text rotation.  If you are adding it to the top and
want some padding between it and the plot, you can:

  $cc->title->padding->bottom(5);

=head2 title_position

The position the title will be added.  Should be one of north, south, east,
west or center as required by L<Layout::Manager::Compass>.

Note that if no angle is set for the title then it will be changed to
-1.5707 if the title position is east or west.

=head2 width

Set/Get the width.  Defaults to 500.

=head1 METHODS



( run in 0.887 second using v1.01-cache-2.11-cpan-39bf76dae61 )