Simplify some code
[bioperl-live.git] / Bio / TreeIO / svggraph.pm
blob8b02ef75fc64530a8f2f654c3aa51454c6178186
2 # BioPerl module for Bio::TreeIO::svg-graph
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Allen Day <allenday@ucla.edu>
8 # Copyright Brian O'Connor
10 # You may distribute this module under the same terms as perl itself
12 # POD documentation - main docs before the code
14 =head1 NAME
16 Bio::TreeIO::svggraph - A simple output format that converts a Tree object to an SVG output
18 =head1 SYNOPSIS
20 use Bio::TreeIO;
21 my $in = Bio::TreeIO->new(-file => 'input', -format => 'newick');
22 my $out = Bio::TreeIO->new(-file => '>output', -format => 'svggraph');
24 while( my $tree = $in->next_tree ) {
25 my $svg_xml = $out->write_tree($tree);
28 =head1 DESCRIPTION
30 This outputs a tree as an SVG graphic using the SVG::Graph API
32 =head1 FEEDBACK
34 =head2 Mailing Lists
36 User feedback is an integral part of the evolution of this and other
37 Bioperl modules. Send your comments and suggestions preferably to
38 the Bioperl mailing list. Your participation is much appreciated.
40 bioperl-l@bioperl.org - General discussion
41 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
43 =head2 Support
45 Please direct usage questions or support issues to the mailing list:
47 I<bioperl-l@bioperl.org>
49 rather than to the module maintainer directly. Many experienced and
50 reponsive experts will be able look at the problem and quickly
51 address it. Please include a thorough description of the problem
52 with code and data examples if at all possible.
54 =head2 Reporting Bugs
56 Report bugs to the Bioperl bug tracking system to help us keep track
57 of the bugs and their resolution. Bug reports can be submitted via the
58 web:
60 https://github.com/bioperl/bioperl-live/issues
62 =head1 AUTHOR - Brian OConnor
64 Email brian.oconnor-at-excite.com
66 =head1 CONTRIBUTORS
68 Allen Day
69 Guillaume Rousse, Guillaume-dot-Rousse-at-inria-dot-fr
71 =head1 APPENDIX
73 The rest of the documentation details each of the object methods.
74 Internal methods are usually preceded with a _
76 =cut
79 # Let the code begin...
82 package Bio::TreeIO::svggraph;
83 use strict;
85 # Object preamble - inherits from Bio::Root::Root
87 use SVG::Graph;
88 use SVG::Graph::Data;
89 use SVG::Graph::Data::Tree;
90 use SVG::Graph::Data::Node;
91 use Bio::Tree::TreeI;
92 use Bio::Tree::Node;
93 use Tree::DAG_Node;
96 use base qw(Bio::TreeIO);
98 =head2 new
100 Title : new
101 Usage : my $obj = Bio::TreeIO::svggraph->new();
102 Function: Builds a new Bio::TreeIO::svggraph object
103 Returns : Bio::TreeIO::svggraph
104 Args :-width => image width (default 1600)
105 -height => image height (default 1000)
106 -margin => margin (default 30)
107 -stroke => stroke color (default 'black')
108 -stroke_width=> stroke width (default 2)
109 -font_size=> font size (default '10px')
110 -nomalize => undef or 'log' (default is undef)
112 =cut
114 sub _initialize {
115 my $self = shift;
116 my ($width,$height,$margin,$stroke,
117 $stroke_width,$font_size,
118 $normalize) = $self->_rearrange([qw
119 (WIDTH
120 HEIGHT
121 MARGIN
122 STROKE
123 STROKE_WIDTH
124 FONT_SIZE
125 NORMALIZE)],
126 @_);
127 $self->{_width} = $width || 1600;
128 $self->{_height} = $height || 1000;
129 $self->{_margin} = defined $margin ? $margin : 30;
130 $self->{_stroke} = $stroke || 'black';
131 $self->{_stroke_width} = $stroke_width || 2;
132 $self->{_font_size} = $font_size || '10px';
133 $self->{_normalize} = $normalize || '';
134 $self->SUPER::_initialize(@_);
137 =head2 write_tree
139 Title : write_tree
140 Usage : $treeio->write_tree($tree);
141 Function: Write a tree out to data stream in newick/phylip format
142 Returns : none
143 Args : Bio::Tree::TreeI object
145 =cut
147 sub write_tree{
148 my ($self,$tree) = @_;
149 my $line = $self->_write_tree_Helper($tree->get_root_node);
150 $self->_print($line. "\n");
151 $self->flush if $self->_flush_on_write && defined $self->_fh;
152 return;
155 sub _write_tree_Helper {
156 my ($self,$node) = @_;
158 my $graph = SVG::Graph->new
159 ('width' => $self->{'_width'},
160 'height' => $self->{'_height'},
161 'margin' => $self->{'_margin'});
163 my $group0 = $graph->add_frame;
164 my $tree = SVG::Graph::Data::Tree->new;
165 my $root = SVG::Graph::Data::Node->new;
166 $root->name($node->id);
167 $self->_decorateRoot($root, $node->each_Descendent());
168 $tree->root($root);
169 $group0->add_data($tree);
171 $group0->add_glyph('tree',
172 'stroke' =>$self->{'_stroke'},
173 'stroke-width'=>$self->{'_stroke_width'},
174 'font-size' =>$self->{'_font_size'});
176 return($graph->draw);
180 =head2 decorateRoot
182 Title : _decorateRoot
183 Usage : internal methods
184 Function:
185 Example :
186 Returns :
187 Args :
190 =cut
192 sub _decorateRoot {
193 my ($self,$previousNode,@children) = @_;
194 for my $child (@children) {
195 my $currNode = SVG::Graph::Data::Node->new;
197 # if no ID is set, the branch label is intentionally set blank (bug in SVG::Graph)
198 my $id = $child->id || '';
199 $currNode->branch_label($id);
200 my $length = $child->branch_length;
201 if ($self->{_normalize} eq 'log') {
202 $length = log($length + 1);
205 $currNode->branch_length($length);
206 $previousNode->add_daughter($currNode);
207 $self->_decorateRoot($currNode, $child->each_Descendent());
212 =head2 next_tree
214 Title : next_tree
215 Usage :
216 Function: Sorry not possible with this format
217 Returns : none
218 Args : none
221 =cut
223 sub next_tree{
224 $_[0]->throw("Sorry the format 'svggraph' can only be used as an output format");