From f50e1358281572d078c0d44917b54e62459bf587 Mon Sep 17 00:00:00 2001 From: simbabque Date: Tue, 10 Oct 2017 22:08:42 +0200 Subject: [PATCH 1/2] make years floating point to support greater granularity in dates and amend docs Closes #1 --- lib/SVG/Timeline.pm | 29 ++++++++++++++++++++++++++--- lib/SVG/Timeline/Event.pm | 4 ++-- t/01-basic.t | 8 +++++++- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/SVG/Timeline.pm b/lib/SVG/Timeline.pm index 03995bd..11033cb 100644 --- a/lib/SVG/Timeline.pm +++ b/lib/SVG/Timeline.pm @@ -15,8 +15,8 @@ SVG::Timeline - Create SVG timeline charts }); $tl->add_event({ - start => 1939, - end => 1945, + start => 1939.66575, # 1 Sep 1939 + end => 1945.34795, # 8 May 1945 text => 'World War II', }); @@ -263,6 +263,29 @@ sub events_in_timeline { return $_[0]->count_events; } +=head2 add_event + +Takes a hash reference with event details and adds an L +to the timeline. The following details are supported: + +=over 4 + +=item * text - the name of the event that is displayed on the bar. This is required. + +=item * start - the start year of the event. Can be an integer for a full year, +or a floating point value where the decimal fraction is how far through the year +the date falls. For example, C<2017.5> is roughly the 2nd of July 2017, or the +middle of the year. This is required. + +=item * end - the end year of the event. Can be an integer or a floating point value. +This is required. + +=item * colour - the colour that is used to fill the timeline block. This should be +defined in the RGB format used by SVG. For example, red would be 'RGB(255,0,0)'. +This is optional. If not provided, the C is used. + +=back + =head2 calculated_height The height of the timeline in "calculated units". @@ -287,7 +310,7 @@ sub calculated_height { =head2 calculated_width -The widtn in "calulated units". +The width in "calulated units". =cut diff --git a/lib/SVG/Timeline/Event.pm b/lib/SVG/Timeline/Event.pm index 74c59e3..7626544 100644 --- a/lib/SVG/Timeline/Event.pm +++ b/lib/SVG/Timeline/Event.pm @@ -33,13 +33,13 @@ has text => ( has start => ( is => 'ro', - isa => 'Int', + isa => 'Num', required => 1, ); has end => ( is => 'ro', - isa => 'Int', + isa => 'Num', required => 1, ); diff --git a/t/01-basic.t b/t/01-basic.t index 12a8451..864274d 100644 --- a/t/01-basic.t +++ b/t/01-basic.t @@ -13,7 +13,13 @@ $tl->add_event({ text => 'Perl', }); -is($tl->count_events, 1, 'Correct number of events'); +$tl->add_event({ + start => 2017.5726, + end => localtime->year + ( localtime->yday + 1 ) / ( localtime->is_leap_year ? 365: 366 ), + text => 'SVG::Timeline on CPAN', +}); + +is($tl->count_events, 2, 'Correct number of events'); is($tl->events->[0]->index, 1, 'Correct index for event'); isa_ok($tl->svg, 'SVG'); my $vb1 = $tl->svg->getChildren->[0]{viewBox}; From 8c4b469c9790870e330a9eb72106c0390b7c9e2c Mon Sep 17 00:00:00 2001 From: tcheukueppo Date: Sun, 23 Oct 2022 02:50:57 +0100 Subject: [PATCH 2/2] Use the 'yy-mm-dd' format to pass the 'start' and 'end' date when instanciating an event class. --- Changes.md | 4 ++++ lib/SVG/Timeline.pm | 14 ++++++-------- lib/SVG/Timeline/Event.pm | 25 +++++++++++++++++++++++-- t/01-basic.t | 10 +++++----- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/Changes.md b/Changes.md index 6e503c1..6f2da1d 100644 --- a/Changes.md +++ b/Changes.md @@ -1,5 +1,9 @@ # Change Log +### Improved + +- Use the 'yy-mm-dd' format to pass the 'start' and 'end' date when instanciating an event class + ## [0.0.10] - 2022-06-14 ### Fixed diff --git a/lib/SVG/Timeline.pm b/lib/SVG/Timeline.pm index 11033cb..cf7b304 100644 --- a/lib/SVG/Timeline.pm +++ b/lib/SVG/Timeline.pm @@ -15,8 +15,8 @@ SVG::Timeline - Create SVG timeline charts }); $tl->add_event({ - start => 1939.66575, # 1 Sep 1939 - end => 1945.34795, # 8 May 1945 + start => '1939-09-01', # 1 Sep 1939 + end => '1945-05-08', # 8 May 1945 text => 'World War II', }); @@ -272,13 +272,11 @@ to the timeline. The following details are supported: =item * text - the name of the event that is displayed on the bar. This is required. -=item * start - the start year of the event. Can be an integer for a full year, -or a floating point value where the decimal fraction is how far through the year -the date falls. For example, C<2017.5> is roughly the 2nd of July 2017, or the -middle of the year. This is required. +=item * start - the start year of the event. It is a string of format C. +For example, C<2017-07-02> is the 2nd of July 2017. C<-mm-dd> as well as C<-dd> can +be omitted. -=item * end - the end year of the event. Can be an integer or a floating point value. -This is required. +=item * end - the end year of the event, requirements are the same as that of C. =item * colour - the colour that is used to fill the timeline block. This should be defined in the RGB format used by SVG. For example, red would be 'RGB(255,0,0)'. diff --git a/lib/SVG/Timeline/Event.pm b/lib/SVG/Timeline/Event.pm index 7626544..b4743b8 100644 --- a/lib/SVG/Timeline/Event.pm +++ b/lib/SVG/Timeline/Event.pm @@ -14,11 +14,18 @@ use 5.010; use Moose; use Moose::Util::TypeConstraints; +use DateTime; coerce __PACKAGE__, from 'HashRef', via { __PACKAGE__->new($_) }; +# Choosen format: yy-mm-dd +subtype 'Date', + as 'Str', + where { m/ \d{4} (?: -\d{2} (?: -\d{2} )? )? /ax }, + message { "Date format, '$_', is not valid" }; + has index => ( is => 'ro', isa => 'Int', @@ -31,16 +38,30 @@ has text => ( required => 1, ); +# Convert date to a floating year +sub floating_year_of { + my ( $self, $date_str, $attr ) = @_; + my ( $year, $month, $day ) = split m/-/, $date_str; + + $self->{$attr} = $year; + my $date = DateTime->new( year => $year, month => $month // 1, day => $day // 1 ); + my $ndays = $date->jd - $date->set( month => 1, day => 1 )->jd; + + $self->{$attr} += $ndays / ( $date->is_leap_year ? 366 : 365 ) if $ndays > 0; +} + has start => ( is => 'ro', - isa => 'Num', + isa => 'Date', required => 1, + trigger => sub { floating_year_of( @_[0..1], 'start' ) }, ); has end => ( is => 'ro', - isa => 'Num', + isa => 'Date', required => 1, + trigger => sub { floating_year_of( @_[0..1], 'end' ) }, ); has colour => ( diff --git a/t/01-basic.t b/t/01-basic.t index 864274d..daba892 100644 --- a/t/01-basic.t +++ b/t/01-basic.t @@ -8,14 +8,14 @@ use Time::Piece; my $tl = SVG::Timeline->new; $tl->add_event({ - start => 1987, - end => localtime->year, + start => '1987', + end => '2022-10-23', text => 'Perl', }); $tl->add_event({ - start => 2017.5726, - end => localtime->year + ( localtime->yday + 1 ) / ( localtime->is_leap_year ? 365: 366 ), + start => '2017-07-29', + end => '2022', text => 'SVG::Timeline on CPAN', }); @@ -29,7 +29,7 @@ $tl->add_event({ end => localtime->year, text => 'Python', }); -is($tl->count_events, 2, 'Correct number of events'); +is($tl->count_events, 3, 'Correct number of events'); my $vb2 = $tl->svg->getChildren->[0]{viewBox}; isnt($vb1, $vb2, 'Viewbox changed');