SVG-Timeline
view release on metacpan or search on metacpan
lib/SVG/Timeline.pm view on Meta::CPAN
is => 'ro',
isa => 'Str',
default => '100%',
);
=item * height - the height of the output in any format used by SVG. The
default is 100%.
=cut
has height => (
is => 'ro',
isa => 'Str',
default => '100%',
);
=item * aspect_ratio - the default is 16/9.
=cut
has aspect_ratio => (
is => 'ro',
isa => 'Num',
default => 16/9,
);
=item * viewport - a viewport definition (which is a space separated list of
four integers. Unless you know what you're doing, it's probably best to leave
the class to work this out for you.
=cut
has viewbox => (
is => 'ro',
isa => 'Str',
lazy_build => 1,
clearer => '_clear_viewbox',
);
sub _build_viewbox {
my $self = shift;
return join ' ',
$self->min_year * $self->units_per_year,
0,
$self->years * $self->units_per_year,
($self->bar_height * $self->events_in_timeline) + $self->bar_height
+ (($self->count_events - 1) * $self->bar_height * $self->bar_spacing);
}
=item * svg - an instance of the SVG class that is used to generate the final
SVG output. Unless you're using a subclass of this class for some reason,
there is no reason to set this manually.
=cut
has svg => (
is => 'ro',
isa => 'SVG',
lazy_build => 1,
clearer => '_clear_svg',
handles => [qw[xmlify line text rect cdata]],
);
sub _build_svg {
my $self = shift;
$_->{end} //= (localtime)[5] + 1900 foreach $self->all_events;
return SVG->new(
width => $self->width,
height => $self->height,
viewBox => $self->viewbox,
);
}
=item * default_colour - the colour that is used to fill the timeline
blocks. This should be defined in the RGB format used by SVG. For example,
red would be 'RGB(255,0,0)'.
=cut
has default_colour => (
is => 'ro',
isa => 'Str',
lazy_build => 1,
);
sub _build_default_colour {
return 'rgb(255,127,127)';
}
=item * years_per_grid - the number of years between vertical grid lines
in the output. The default of 10 should be fine unless your timeline covers
a really long timespan.
=cut
# The number of years between vertical grid lines
has years_per_grid => (
is => 'ro',
isa => 'Int',
default => 10, # One decade by default
);
=item * bar_height - the height of an individual timeline bar.
=cut
has bar_height => (
is => 'ro',
isa => 'Int',
default => 50,
);
=item * bar_spacing - the height if the vertical space between bars (expresssed
as a decimal fraction of the bar height).
=cut
has bar_spacing => (
is => 'ro',
lib/SVG/Timeline.pm view on Meta::CPAN
# ... multiplied by the bar height...
$calulated_height *= $self->bar_height;
# .. add spacing.
$calulated_height += $self->bar_height * $self->bar_spacing *
($self->events_in_timeline - 1);
return $calulated_height;
}
=head2 calculated_width
The width in "calulated units".
=cut
sub calculated_width {
my $self = shift;
return $self->calculated_height * $self->aspect_ratio;
}
=head2 units_per_year
The number of horizontal units that each year should take up.
=cut
sub units_per_year {
my $self = shift;
return $self->calculated_width / $self->years;
}
=head2 draw_grid
Method to draw the underlying grid.
=cut
sub draw_grid{
my $self = shift;
my $curr_year = $self->min_year;
my $units_per_year = $self->units_per_year;
# Draw the grid lines
while ( $curr_year <= $self->max_year ) {
unless ( $curr_year % $self->years_per_grid ) {
$self->line(
x1 => $curr_year * $units_per_year,
y1 => 0,
x2 => $curr_year * $units_per_year,
y2 => $self->calculated_height,
stroke => $self->decade_line_colour,
stroke_width => 1
);
$self->text(
x => ($curr_year + 1) * $units_per_year,
y => 20,
'font-size' => $self->bar_height / 2
)->cdata($curr_year);
}
$curr_year++;
}
$self->rect(
x => $self->min_year * $units_per_year,
y => 0,
width => $self->years * $units_per_year,
height => ($self->bar_height * ($self->events_in_timeline + 1))
+ ($self->bar_height * $self->bar_spacing
* ($self->events_in_timeline - 1)),
stroke => $self->bar_outline_colour,
'stroke-width' => 1,
fill => 'none',
);
return $self;
}
=head2 draw
Method to draw the timeline.
=cut
sub draw {
my $self = shift;
my %args = @_;
croak "Can't draw a timeline with no events"
unless $self->has_events;
$self->draw_grid;
my $curr_event_idx = 1;
foreach ($self->all_events) {
$_->draw_on($self);
$curr_event_idx++;
}
return $self->xmlify;
}
=head2 min_year
Returns the minimum year from all the events in the timeline.
=cut
sub min_year {
my $self = shift;
return unless $self->has_events;
my @years = map { $_->start_year } $self->all_events;
return min(@years);
}
=head2 max_year
( run in 1.660 second using v1.01-cache-2.11-cpan-d06a3f9ecfd )