File Coverage

blib/lib/Bio/Phylo/Forest/DrawTreeRole.pm
Criterion Covered Total %
statement 51 88 57.9
branch 12 24 50.0
condition n/a
subroutine 10 12 83.3
pod 2 2 100.0
total 75 126 59.5


line stmt bran cond sub pod time code
1             package Bio::Phylo::Forest::DrawTreeRole;
2 31     31   47937 use strict;
  31         72  
  31         797  
3 31     31   141 use Carp;
  31         55  
  31         1906  
4 31     31   17775 use Bio::Phylo::Forest::TreeRole;
  31         94  
  31         256  
5 31     31   273 use base 'Bio::Phylo::Forest::TreeRole';
  31         72  
  31         3807  
6 31     31   207 use Bio::Phylo::Forest::DrawNodeRole;
  31         102  
  31         504  
7 31     31   175 use Bio::Phylo::Util::CONSTANT 'looks_like_hash';
  31         60  
  31         27057  
8             {
9              
10             our $AUTOLOAD;
11             my @properties = qw(width height node_radius tip_radius node_color node_shape
12             node_image branch_color branch_shape branch_width branch_style collapsed_clade_width
13             font_face font_size font_style margin margin_top margin_bottom margin_left
14             margin_right padding padding_top padding_bottom padding_left padding_right
15             mode shape text_horiz_offset text_vert_offset);
16              
17             =head1 NAME
18              
19             Bio::Phylo::Forest::DrawTreeRole - Tree with extra methods for tree drawing
20              
21             =head1 SYNOPSIS
22              
23             # see Bio::Phylo::Forest::Tree
24              
25             =head1 DESCRIPTION
26              
27             The object models a phylogenetic tree, a container of Bio::Phylo::For-
28             est::Node objects. The tree object inherits from Bio::Phylo::Listable,
29             so look there for more methods.
30              
31             In addition, this subclass of the default tree object L
32             has getters and setters for drawing trees, e.g. font and text attributes, etc.
33              
34             =head1 METHODS
35              
36             =head2 CONSTRUCTORS
37              
38             =over
39              
40             =item new()
41              
42             Tree constructor.
43              
44             Type : Constructor
45             Title : new
46             Usage : my $tree = Bio::Phylo::Forest::DrawTree->new;
47             Function: Instantiates a Bio::Phylo::Forest::DrawTree object.
48             Returns : A Bio::Phylo::Forest::DrawTree object.
49             Args : No required arguments.
50              
51             =cut
52              
53             sub new {
54 178     178 1 732 my $class = shift;
55 178         779 my %args = looks_like_hash @_;
56 178 50       581 if ( not $args{'-tree'} ) {
57 178         1043 return $class->SUPER::new(@_);
58             }
59             else {
60 0         0 my $tree = $args{'-tree'};
61 0         0 my $self = $tree->clone;
62 0         0 bless $self, $class;
63 0         0 for my $node ( @{ $self->get_entities } ) {
  0         0  
64 0         0 bless $node, 'Bio::Phylo::Forest::DrawNode';
65             }
66            
67 0         0 delete $args{'-tree'};
68 0         0 for my $key ( keys %args ) {
69 0         0 my $method = $key;
70 0         0 $method =~ s/^-/set_/;
71 0         0 $self->$method( $args{$key} );
72             }
73 0         0 return $self;
74             }
75             }
76              
77             =back
78              
79             =head2 MUTATORS
80              
81             =over
82              
83             =item set_width()
84              
85             Type : Mutator
86             Title : set_width
87             Usage : $tree->set_width($width);
88             Function: Sets width
89             Returns : $self
90             Args : width
91              
92             =item set_height()
93              
94             Type : Mutator
95             Title : set_height
96             Usage : $tree->set_height($height);
97             Function: Sets height
98             Returns : $self
99             Args : height
100              
101             =item set_node_radius()
102              
103             Type : Mutator
104             Title : set_node_radius
105             Usage : $tree->set_node_radius($node_radius);
106             Function: Sets node_radius
107             Returns : $self
108             Args : node_radius
109              
110             =item set_tip_radius()
111              
112             Type : Mutator
113             Title : set_tip_node_radius
114             Usage : $tree->set_tip_radius($node_radius);
115             Function: Sets tip radius
116             Returns : $self
117             Args : tip radius
118              
119             =item set_node_colour()
120              
121             Type : Mutator
122             Title : set_node_colour
123             Usage : $tree->set_node_colour($node_colour);
124             Function: Sets node_colour
125             Returns : $self
126             Args : node_colour
127              
128             =item set_node_shape()
129              
130             Type : Mutator
131             Title : set_node_shape
132             Usage : $tree->set_node_shape($node_shape);
133             Function: Sets node_shape
134             Returns : $self
135             Args : node_shape
136              
137             =item set_node_image()
138              
139             Type : Mutator
140             Title : set_node_image
141             Usage : $tree->set_node_image($node_image);
142             Function: Sets node_image
143             Returns : $self
144             Args : node_image
145              
146             =item set_collapsed_clade_width()
147              
148             Sets collapsed clade width.
149              
150             Type : Mutator
151             Title : set_collapsed_clade_width
152             Usage : $tree->set_collapsed_clade_width(6);
153             Function: sets the width of collapsed clade triangles relative to uncollapsed tips
154             Returns :
155             Args : Positive number
156              
157             =item set_branch_color()
158              
159             Type : Mutator
160             Title : set_branch_color
161             Usage : $tree->set_branch_color($branch_color);
162             Function: Sets branch_color
163             Returns : $self
164             Args : branch_color
165              
166             =item set_branch_shape()
167              
168             Type : Mutator
169             Title : set_branch_shape
170             Usage : $tree->set_branch_shape($branch_shape);
171             Function: Sets branch_shape
172             Returns : $self
173             Args : branch_shape
174              
175             =item set_branch_width()
176              
177             Type : Mutator
178             Title : set_branch_width
179             Usage : $tree->set_branch_width($branch_width);
180             Function: Sets branch width
181             Returns : $self
182             Args : branch_width
183              
184             =item set_branch_style()
185              
186             Type : Mutator
187             Title : set_branch_style
188             Usage : $tree->set_branch_style($branch_style);
189             Function: Sets branch style
190             Returns : $self
191             Args : branch_style
192              
193             =item set_font_face()
194              
195             Type : Mutator
196             Title : set_font_face
197             Usage : $tree->set_font_face($font_face);
198             Function: Sets font_face
199             Returns : $self
200             Args : font face, Verdana, Arial, Serif
201              
202             =item set_font_size()
203              
204             Type : Mutator
205             Title : set_font_size
206             Usage : $tree->set_font_size($font_size);
207             Function: Sets font_size
208             Returns : $self
209             Args : Font size in pixels
210              
211             =item set_font_style()
212              
213             Type : Mutator
214             Title : set_font_style
215             Usage : $tree->set_font_style($font_style);
216             Function: Sets font_style
217             Returns : $self
218             Args : Font style, e.g. Italic
219              
220             =item set_margin()
221              
222             Type : Mutator
223             Title : set_margin
224             Usage : $tree->set_margin($margin);
225             Function: Sets margin
226             Returns : $self
227             Args : margin
228              
229             =item set_margin_top()
230              
231             Type : Mutator
232             Title : set_margin_top
233             Usage : $tree->set_margin_top($margin_top);
234             Function: Sets margin_top
235             Returns : $self
236             Args : margin_top
237              
238             =item set_margin_bottom()
239              
240             Type : Mutator
241             Title : set_margin_bottom
242             Usage : $tree->set_margin_bottom($margin_bottom);
243             Function: Sets margin_bottom
244             Returns : $self
245             Args : margin_bottom
246              
247             =item set_margin_left()
248              
249             Type : Mutator
250             Title : set_margin_left
251             Usage : $tree->set_margin_left($margin_left);
252             Function: Sets margin_left
253             Returns : $self
254             Args : margin_left
255              
256             =item set_margin_right()
257              
258             Type : Mutator
259             Title : set_margin_right
260             Usage : $tree->set_margin_right($margin_right);
261             Function: Sets margin_right
262             Returns : $self
263             Args : margin_right
264              
265             =item set_padding()
266              
267             Type : Mutator
268             Title : set_padding
269             Usage : $tree->set_padding($padding);
270             Function: Sets padding
271             Returns : $self
272             Args : padding
273              
274             =item set_padding_top()
275              
276             Type : Mutator
277             Title : set_padding_top
278             Usage : $tree->set_padding_top($padding_top);
279             Function: Sets padding_top
280             Returns : $self
281             Args : padding_top
282              
283             =item set_padding_bottom()
284              
285             Type : Mutator
286             Title : set_padding_bottom
287             Usage : $tree->set_padding_bottom($padding_bottom);
288             Function: Sets padding_bottom
289             Returns : $self
290             Args : padding_bottom
291              
292             =item set_padding_left()
293              
294             Type : Mutator
295             Title : set_padding_left
296             Usage : $tree->set_padding_left($padding_left);
297             Function: Sets padding_left
298             Returns : $self
299             Args : padding_left
300              
301             =item set_padding_right()
302              
303             Type : Mutator
304             Title : set_padding_right
305             Usage : $tree->set_padding_right($padding_right);
306             Function: Sets padding_right
307             Returns : $self
308             Args : padding_right
309              
310             =item set_mode()
311              
312             Type : Mutator
313             Title : set_mode
314             Usage : $tree->set_mode($mode);
315             Function: Sets mode
316             Returns : $self
317             Args : mode, e.g. 'CLADO' or 'PHYLO'
318              
319             =item set_shape()
320              
321             Type : Mutator
322             Title : set_shape
323             Usage : $tree->set_shape($shape);
324             Function: Sets shape
325             Returns : $self
326             Args : shape, e.g. 'RECT', 'CURVY', 'DIAG'
327              
328             =item set_text_horiz_offset()
329              
330             Type : Mutator
331             Title : set_text_horiz_offset
332             Usage : $tree->set_text_horiz_offset($text_horiz_offset);
333             Function: Sets text_horiz_offset
334             Returns : $self
335             Args : text_horiz_offset
336              
337             =item set_text_vert_offset()
338              
339             Type : Mutator
340             Title : set_text_vert_offset
341             Usage : $tree->set_text_vert_offset($text_vert_offset);
342             Function: Sets text_vert_offset
343             Returns : $self
344             Args : text_vert_offset
345              
346             =back
347              
348             =head2 ACCESSORS
349              
350             =over
351              
352             =item get_width()
353              
354             Type : Accessor
355             Title : get_width
356             Usage : my $width = $tree->get_width();
357             Function: Gets width
358             Returns : width
359             Args : NONE
360              
361             =item get_height()
362              
363             Type : Accessor
364             Title : get_height
365             Usage : my $height = $tree->get_height();
366             Function: Gets height
367             Returns : height
368             Args : NONE
369              
370             =item get_node_radius()
371              
372             Type : Accessor
373             Title : get_node_radius
374             Usage : my $node_radius = $tree->get_node_radius();
375             Function: Gets node_radius
376             Returns : node_radius
377             Args : NONE
378              
379             =item get_node_colour()
380              
381             Type : Accessor
382             Title : get_node_colour
383             Usage : my $node_colour = $tree->get_node_colour();
384             Function: Gets node_colour
385             Returns : node_colour
386             Args : NONE
387              
388             =item get_node_shape()
389              
390             Type : Accessor
391             Title : get_node_shape
392             Usage : my $node_shape = $tree->get_node_shape();
393             Function: Gets node_shape
394             Returns : node_shape
395             Args : NONE
396              
397             =item get_node_image()
398              
399             Type : Accessor
400             Title : get_node_image
401             Usage : my $node_image = $tree->get_node_image();
402             Function: Gets node_image
403             Returns : node_image
404             Args : NONE
405              
406             =item get_collapsed_clade_width()
407              
408             Gets collapsed clade width.
409              
410             Type : Mutator
411             Title : get_collapsed_clade_width
412             Usage : $w = $tree->get_collapsed_clade_width();
413             Function: gets the width of collapsed clade triangles relative to uncollapsed tips
414             Returns : Positive number
415             Args : None
416              
417             =item get_branch_color()
418              
419             Type : Accessor
420             Title : get_branch_color
421             Usage : my $branch_color = $tree->get_branch_color();
422             Function: Gets branch_color
423             Returns : branch_color
424             Args : NONE
425              
426             =item get_branch_shape()
427              
428             Type : Accessor
429             Title : get_branch_shape
430             Usage : my $branch_shape = $tree->get_branch_shape();
431             Function: Gets branch_shape
432             Returns : branch_shape
433             Args : NONE
434              
435             =item get_branch_width()
436              
437             Type : Accessor
438             Title : get_branch_width
439             Usage : my $branch_width = $tree->get_branch_width();
440             Function: Gets branch_width
441             Returns : branch_width
442             Args : NONE
443              
444             =item get_branch_style()
445              
446             Type : Accessor
447             Title : get_branch_style
448             Usage : my $branch_style = $tree->get_branch_style();
449             Function: Gets branch_style
450             Returns : branch_style
451             Args : NONE
452              
453             =item get_font_face()
454              
455             Type : Accessor
456             Title : get_font_face
457             Usage : my $font_face = $tree->get_font_face();
458             Function: Gets font_face
459             Returns : font_face
460             Args : NONE
461              
462             =item get_font_size()
463              
464             Type : Accessor
465             Title : get_font_size
466             Usage : my $font_size = $tree->get_font_size();
467             Function: Gets font_size
468             Returns : font_size
469             Args : NONE
470              
471             =item get_font_style()
472              
473             Type : Accessor
474             Title : get_font_style
475             Usage : my $font_style = $tree->get_font_style();
476             Function: Gets font_style
477             Returns : font_style
478             Args : NONE
479              
480             =item get_margin()
481              
482             Type : Accessor
483             Title : get_margin
484             Usage : my $margin = $tree->get_margin();
485             Function: Gets margin
486             Returns : margin
487             Args : NONE
488              
489             =item get_margin_top()
490              
491             Type : Accessor
492             Title : get_margin_top
493             Usage : my $margin_top = $tree->get_margin_top();
494             Function: Gets margin_top
495             Returns : margin_top
496             Args : NONE
497              
498             =item get_margin_bottom()
499              
500             Type : Accessor
501             Title : get_margin_bottom
502             Usage : my $margin_bottom = $tree->get_margin_bottom();
503             Function: Gets margin_bottom
504             Returns : margin_bottom
505             Args : NONE
506              
507             =item get_margin_left()
508              
509             Type : Accessor
510             Title : get_margin_left
511             Usage : my $margin_left = $tree->get_margin_left();
512             Function: Gets margin_left
513             Returns : margin_left
514             Args : NONE
515              
516             =item get_margin_right()
517              
518             Type : Accessor
519             Title : get_margin_right
520             Usage : my $margin_right = $tree->get_margin_right();
521             Function: Gets margin_right
522             Returns : margin_right
523             Args : NONE
524              
525             =item get_padding()
526              
527             Type : Accessor
528             Title : get_padding
529             Usage : my $padding = $tree->get_padding();
530             Function: Gets padding
531             Returns : padding
532             Args : NONE
533              
534             =item get_padding_top()
535              
536             Type : Accessor
537             Title : get_padding_top
538             Usage : my $padding_top = $tree->get_padding_top();
539             Function: Gets padding_top
540             Returns : padding_top
541             Args : NONE
542              
543             =item get_padding_bottom()
544              
545             Type : Accessor
546             Title : get_padding_bottom
547             Usage : my $padding_bottom = $tree->get_padding_bottom();
548             Function: Gets padding_bottom
549             Returns : padding_bottom
550             Args : NONE
551              
552             =item get_padding_left()
553              
554             Type : Accessor
555             Title : get_padding_left
556             Usage : my $padding_left = $tree->get_padding_left();
557             Function: Gets padding_left
558             Returns : padding_left
559             Args : NONE
560              
561             =item get_padding_right()
562              
563             Type : Accessor
564             Title : get_padding_right
565             Usage : my $padding_right = $tree->get_padding_right();
566             Function: Gets padding_right
567             Returns : padding_right
568             Args : NONE
569              
570             =item get_mode()
571              
572             Type : Accessor
573             Title : get_mode
574             Usage : my $mode = $tree->get_mode();
575             Function: Gets mode
576             Returns : mode
577             Args : NONE
578              
579             =cut
580              
581             sub get_mode {
582 1     1 1 4 my $self = shift;
583 1 50       8 if ( $self->is_cladogram ) {
584 1         4 return 'CLADO';
585             }
586 0         0 return $self->get_meta_object( 'map:mode' );
587             }
588              
589             =item get_shape()
590              
591             Type : Accessor
592             Title : get_shape
593             Usage : my $shape = $tree->get_shape();
594             Function: Gets shape
595             Returns : shape
596             Args : NONE
597              
598             =item get_text_horiz_offset()
599              
600             Type : Accessor
601             Title : get_text_horiz_offset
602             Usage : my $text_horiz_offset = $tree->get_text_horiz_offset();
603             Function: Gets text_horiz_offset
604             Returns : text_horiz_offset
605             Args : NONE
606              
607             =item get_text_vert_offset()
608              
609             Type : Accessor
610             Title : get_text_vert_offset
611             Usage : my $text_vert_offset = $tree->get_text_vert_offset();
612             Function: Gets text_vert_offset
613             Returns : text_vert_offset
614             Args : NONE
615              
616             =begin comment
617              
618             This method re-computes the node coordinates
619              
620             =end comment
621              
622             =cut
623              
624             sub _redraw {
625 29     29   37 my $self = shift;
626 29         120 my ( $width, $height ) = ( $self->get_width, $self->get_height );
627 29         56 my $tips_seen = 0;
628 29         82 my $total_tips = $self->calc_number_of_terminals();
629 29 50       60 if ( my $root = $self->get_root ) {
630 0         0 my $tallest = $root->calc_max_path_to_tips;
631 0         0 my $maxnodes = $root->calc_max_nodes_to_tips;
632 0         0 my $is_clado = $self->get_mode =~ m/^c/i;
633             $self->visit_depth_first(
634             '-post' => sub {
635 0     0   0 my $node = shift;
636 0         0 my ( $x, $y );
637 0 0       0 if ( $node->is_terminal ) {
638 0         0 $tips_seen++;
639 0         0 $y = ( $height / $total_tips ) * $tips_seen;
640 0 0       0 $x =
641             $is_clado
642             ? $width
643             : ( $width / $tallest ) * $node->calc_path_to_root;
644             }
645             else {
646 0         0 my @children = @{ $node->get_children };
  0         0  
647 0         0 $y += $_->get_y for @children;
648 0         0 $y /= scalar @children;
649 0 0       0 $x =
650             $is_clado
651             ? $width -
652             ( ( $width / $maxnodes ) * $node->calc_max_nodes_to_tips )
653             : ( $width / $tallest ) * $node->calc_path_to_root;
654             }
655 0         0 $node->set_y($y);
656 0         0 $node->set_x($x);
657             }
658 0         0 );
659             }
660             }
661              
662              
663             =back
664              
665             =cut
666              
667             sub AUTOLOAD {
668 116     116   11603 my $self = shift;
669 116         174 my $method = $AUTOLOAD;
670 116         540 $method =~ s/.+://; # strip package names
671 116         212 $method =~ s/colour/color/; # map Canadian/British to American :)
672            
673             # if the user calls some non-existant method, try to do the
674             # usual way, with this message, from perspective of caller
675 116         159 my $template = 'Can\'t locate object method "%s" via package "%s"';
676            
677             # handler set_* method calls
678 116 100       434 if ( $method =~ /^set_(.+)$/ ) {
    100          
679 29         64 my $prop = $1;
680              
681             # test if this is actually settable
682 29 50       102 if ( grep { /^\Q$prop\E$/ } @properties ) {
  841         2070  
683 29         50 my $value = shift;
684            
685             # these are properties that must be applied to all nodes
686 29 100       89 if ( $prop =~ /_(?:node|tip|branch|clade|font|text)_/ ) {
687             $self->visit(sub{
688 0     0   0 my $node = shift;
689 0         0 $node->$method($value);
690 1         7 });
691             }
692            
693             # these are properties that must be expanded to left/right/top/bottom
694 29 50       65 if ( $prop =~ /_(?:margin|padding)$/ ) {
695 0         0 for my $pos ( qw(left right top bottom) ) {
696 0         0 my $expanded = $method . '_' . $pos;
697 0         0 $self->$expanded($value);
698             }
699             }
700            
701             # also apply the property to the tree itself
702 29         117 $self->set_meta_object( "map:$prop" => $value );
703 29         87 $self->_redraw;
704 29         131 return $self;
705             }
706             else {
707 0         0 croak sprintf $template, $method, __PACKAGE__;
708             }
709             }
710             elsif ( $method =~ /^get_(.+)$/ ) {
711 86         172 my $prop = $1;
712            
713             # test if this is actually gettable
714 86 50       143 if ( grep { /^\Q$prop\E$/ } @properties ) {
  2494         5909  
715            
716             # return the annotation
717 86         272 return $self->get_meta_object( "map:$prop" );
718             }
719             else {
720 0         0 croak sprintf $template, $method, __PACKAGE__;
721             }
722             }
723             else {
724 1         191 croak sprintf $template, $method, __PACKAGE__;
725             }
726             }
727              
728             # podinherit_insert_token
729              
730             =head1 SEE ALSO
731              
732             There is a mailing list at L
733             for any user or developer questions and discussions.
734              
735             =over
736              
737             =item L
738              
739             This object inherits from L, so methods
740             defined there are also applicable here.
741              
742             =item L
743              
744             Also see the manual: L and L.
745              
746             =back
747              
748             =head1 CITATION
749              
750             If you use Bio::Phylo in published research, please cite it:
751              
752             B, B, B, B
753             and B, 2011. Bio::Phylo - phyloinformatic analysis using Perl.
754             I B<12>:63.
755             L
756              
757             =cut
758              
759             }
760             1;