From b4a75987b58663bc56169d189771641cbfbbd146 Mon Sep 17 00:00:00 2001 From: martinahansen Date: Fri, 19 Mar 2010 16:15:25 +0000 Subject: [PATCH] added PDF/SVG export to BGB git-svn-id: http://biopieces.googlecode.com/svn/trunk@935 74ccb610-7750-0410-82ae-013aeee3265d --- code_perl/Maasha/BGB/Draw.pm | 94 +++++++++++++++++++ code_perl/Maasha/BGB/Track.pm | 13 ++- code_perl/Maasha/KISS.pm | 7 +- www/index.cgi | 171 ++++++++++++++++++++++++++++++---- 4 files changed, 260 insertions(+), 25 deletions(-) diff --git a/code_perl/Maasha/BGB/Draw.pm b/code_perl/Maasha/BGB/Draw.pm index 1a76cd5..2f0577a 100644 --- a/code_perl/Maasha/BGB/Draw.pm +++ b/code_perl/Maasha/BGB/Draw.pm @@ -253,6 +253,100 @@ sub palette } +sub render_png +{ + # Martin A. Hansen, March 2010. + + # Given a list of BGB tracks, render the + # PNG surface stream and return the base64 + # encoded PNG data. + + my ( $width, # image width + $height, # image height + $tracks, # list of BGB tracks to render + ) = @_; + + # Returns a string. + + my ( $surface, $cr, $track, $png_data ); + + $surface = Cairo::ImageSurface->create( 'argb32', $width, $height ); + $cr = Cairo::Context->create( $surface ); + + $cr->rectangle( 0, 0, $width, $height ); + $cr->set_source_rgb( 1, 1, 1 ); + $cr->fill; + + foreach $track ( @{ $tracks } ) { + draw_feature( $cr, $track ) if $track; + } + + $png_data = base64_png( $surface ); + + return $png_data; +} + + +sub render_pdf_file +{ + # Martin A. Hansen, March 2010. + + # Given a list of BGB tracks, render these and save + # to a PDF file. + + my ( $file, # path to PDF file + $width, # image width + $height, # image height + $tracks, # list of BGB tracks to render + ) = @_; + + # Returns nothing. + + my ( $surface, $cr, $track ); + + $surface = Cairo::PdfSurface->create ( $file, $width, $height ); + $cr = Cairo::Context->create( $surface ); + + $cr->rectangle( 0, 0, $width, $height ); + $cr->set_source_rgb( 1, 1, 1 ); + $cr->fill; + + foreach $track ( @{ $tracks } ) { + draw_feature( $cr, $track ) if $track; + } +} + + +sub render_svg_file +{ + # Martin A. Hansen, March 2010. + + # Given a list of BGB tracks, render these and save + # to a SVG file. + + my ( $file, # path to PDF file + $width, # image width + $height, # image height + $tracks, # list of BGB tracks to render + ) = @_; + + # Returns nothing. + + my ( $surface, $cr, $track ); + + $surface = Cairo::SvgSurface->create ( $file, $width, $height ); + $cr = Cairo::Context->create( $surface ); + + $cr->rectangle( 0, 0, $width, $height ); + $cr->set_source_rgb( 1, 1, 1 ); + $cr->fill; + + foreach $track ( @{ $tracks } ) { + draw_feature( $cr, $track ) if $track; + } +} + + sub file_png { # Martin A. Hansen, October 2009. diff --git a/code_perl/Maasha/BGB/Track.pm b/code_perl/Maasha/BGB/Track.pm index 75ba552..ef99f42 100644 --- a/code_perl/Maasha/BGB/Track.pm +++ b/code_perl/Maasha/BGB/Track.pm @@ -78,8 +78,8 @@ sub track_grid { push @grid, { type => 'grid', - line_width => 0.1, - color => [ 0, 0, 0 ], + line_width => 1, + color => [ 0.82, 0.89, 1 ], x1 => $i, y1 => 0, x2 => $i, @@ -368,12 +368,17 @@ sub track_linear if ( $w >= 1 ) { $x1 = sprintf( "%.0f", ( $entry->[ S_BEG ] - $beg ) * $factor ); + $x2 = $x1 + $w; + + $x1 = 0 if $x1 < 0; + $x2 = $cookie->{ 'IMG_WIDTH' } if $x2 > $cookie->{ 'IMG_WIDTH' }; for ( $y_step = 0; $y_step < @ladder; $y_step++ ) { last if $x1 >= $ladder[ $y_step ] + 1; } $y1 = $cookie->{ 'TRACK_OFFSET' } + ( ( 1.1 + $cookie->{ 'FEAT_WIDTH' } ) * $y_step ); + $y2 = $y1 + $cookie->{ 'FEAT_WIDTH' }; $feature = { line_width => $cookie->{ 'FEAT_WIDTH' }, @@ -385,8 +390,8 @@ sub track_linear strand => $entry->[ STRAND ], x1 => $x1, y1 => $y1, - x2 => $x1 + $w, - y2 => $y1 + $cookie->{ 'FEAT_WIDTH' }, + x2 => $x2, + y2 => $y2, }; if ( $entry->[ STRAND ] eq '+' or $entry->[ STRAND ] eq '-' ) { diff --git a/code_perl/Maasha/KISS.pm b/code_perl/Maasha/KISS.pm index be84108..b304b02 100644 --- a/code_perl/Maasha/KISS.pm +++ b/code_perl/Maasha/KISS.pm @@ -108,8 +108,8 @@ sub kiss_retrieve # within an optional interval. my ( $file, # path to KISS file - $beg, # interval begin - OPTIONAL - $end, # interval end - OPTIONAL + $beg, # interval begin - OPTIONAL + $end, # interval end - OPTIONAL ) = @_; # Returns a list. @@ -123,9 +123,8 @@ sub kiss_retrieve while ( $entry = kiss_entry_get( $fh ) ) { - push @entries, $entry if $entry->[ S_END ] > $beg; - last if $entry->[ S_BEG ] > $end; + push @entries, $entry if $entry->[ S_END ] > $beg; } close $fh; diff --git a/www/index.cgi b/www/index.cgi index 38b1988..1dfeb53 100755 --- a/www/index.cgi +++ b/www/index.cgi @@ -247,7 +247,7 @@ sub session_store $new_session->{ 'TIME' } = Maasha::Common::time_stamp(); $new_session->{ 'PAGE' } = $cookie->{ 'PAGE' }; - if ( $cookie->{ 'PAGE' } eq 'browse' ) + if ( $cookie->{ 'PAGE' } =~ /browse|export_pdf|export_svg/ ) { $new_session->{ 'CLADE' } = $cookie->{ 'CLADE' }; $new_session->{ 'GENOME' } = $cookie->{ 'GENOME' }; @@ -586,6 +586,10 @@ sub page push @html, page_dna( $cookie ); } elsif ( $cookie->{ 'PAGE' } eq 'export' ) { push @html, page_export( $cookie ); + } elsif ( $cookie->{ 'PAGE' } eq 'export_pdf' ) { + push @html, page_export_pdf( $cookie ); + } elsif ( $cookie->{ 'PAGE' } eq 'export_svg' ) { + push @html, page_export_svg( $cookie ); } elsif ( $cookie->{ 'PAGE' } eq 'clade' ) { push @html, page_clade( $cookie ); } elsif ( $cookie->{ 'PAGE' } eq 'genome' ) { @@ -701,6 +705,46 @@ sub page_export } +sub page_export_pdf +{ + # Martin A. Hansen, March 2010. + + # Renders the export PDF page. + + my ( $cookie, + ) = @_; + + # Returns a list. + + my ( @html ); + + push @html, section_taxonomy_table( $cookie ); + push @html, section_export_pdf( $cookie ); + + return wantarray ? @html : \@html; +} + + +sub page_export_svg +{ + # Martin A. Hansen, March 2010. + + # Renders the export SVG page. + + my ( $cookie, + ) = @_; + + # Returns a list. + + my ( @html ); + + push @html, section_taxonomy_table( $cookie ); + push @html, section_export_svg( $cookie ); + + return wantarray ? @html : \@html; +} + + sub page_clade { # Martin A. Hansen, March 2010. @@ -1081,9 +1125,9 @@ sub section_linkout # Returns a list. - my ( $link, @html ); + my ( $link_out, $link_pdf, $link_svg, @html ); - $link = Maasha::XHTML::ln( + $link_out = Maasha::XHTML::ln( txt => 'link', href => join( "&", "$cookie->{ 'SCRIPT' }?page=browse", "clade=$cookie->{ 'CLADE' }", @@ -1096,7 +1140,37 @@ sub section_linkout title => "Static link to this view", ); - push @html, Maasha::XHTML::p( txt => $link, class => 'center' ); + $link_pdf = Maasha::XHTML::ln( + txt => 'PDF', + href => join( "&", "$cookie->{ 'SCRIPT' }?page=export_pdf", + "session_id=$cookie->{ 'SESSION_ID' }", + "user=$cookie->{ 'USER' }", + "clade=$cookie->{ 'CLADE' }", + "genome=$cookie->{ 'GENOME' }", + "assembly=$cookie->{ 'ASSEMBLY' }", + "contig=$cookie->{ 'CONTIG' }", + "nav_start=$cookie->{ 'NAV_START' }", + "nav_end=$cookie->{ 'NAV_END' }", + ), + title => "Export view in PDF", + ); + + $link_svg = Maasha::XHTML::ln( + txt => 'SVG', + href => join( "&", "$cookie->{ 'SCRIPT' }?page=export_svg", + "session_id=$cookie->{ 'SESSION_ID' }", + "user=$cookie->{ 'USER' }", + "clade=$cookie->{ 'CLADE' }", + "genome=$cookie->{ 'GENOME' }", + "assembly=$cookie->{ 'ASSEMBLY' }", + "contig=$cookie->{ 'CONTIG' }", + "nav_start=$cookie->{ 'NAV_START' }", + "nav_end=$cookie->{ 'NAV_END' }", + ), + title => "Export view in SVG", + ); + + push @html, Maasha::XHTML::p( txt => "$link_out $link_pdf $link_svg", class => 'center' ); return wantarray ? @html : \@html; } @@ -1109,7 +1183,7 @@ sub section_browse # Returns a list. - my ( @track_list, $i, @tracks, $track, $elem, $surface, $cr, $png_data, @html, @img, $x1, $y1, $x2, $y2, $factor, $center ); + my ( @track_list, $i, @tracks, $track, $elem, $png_data, @html, @img, $x1, $y1, $x2, $y2, $factor, $center ); push @tracks, [ Maasha::BGB::Track::track_ruler( $cookie ) ]; push @tracks, [ Maasha::BGB::Track::track_seq( $cookie ) ]; @@ -1125,18 +1199,7 @@ sub section_browse unshift @tracks, [ Maasha::BGB::Track::track_grid( $cookie ) ]; - $surface = Cairo::ImageSurface->create( 'argb32', $cookie->{ 'IMG_WIDTH' }, $cookie->{ 'TRACK_OFFSET' } ); - $cr = Cairo::Context->create( $surface ); - - $cr->rectangle( 0, 0, $cookie->{ 'IMG_WIDTH' }, $cookie->{ 'TRACK_OFFSET' } ); - $cr->set_source_rgb( 1, 1, 1 ); - $cr->fill; - - foreach $track ( @tracks ) { - Maasha::BGB::Draw::draw_feature( $cr, $track ) if $track; - } - - $png_data = Maasha::BGB::Draw::base64_png( $surface ); + $png_data = Maasha::BGB::Draw::render_png( $cookie->{ 'IMG_WIDTH' }, $cookie->{ 'TRACK_OFFSET' }, \@tracks ); push @img, Maasha::XHTML::img( src => "data:image/png;base64,$png_data", @@ -1299,6 +1362,80 @@ sub section_export } +sub section_export_pdf +{ + # Martin A. Hansen, March 2010. + + # Returns a HTML section with export table. + + my ( $cookie, # cookie hash + ) = @_; + + # Returns a list. + + my ( @tracks, @track_list, $i, $file, @html ); + + push @tracks, [ Maasha::BGB::Track::track_ruler( $cookie ) ]; + push @tracks, [ Maasha::BGB::Track::track_seq( $cookie ) ]; + + @track_list = Maasha::BGB::Track::list_track_dir( $cookie->{ 'USER' }, $cookie->{ 'CLADE' }, $cookie->{ 'GENOME' }, $cookie->{ 'ASSEMBLY' }, $cookie->{ 'CONTIG' } ); + + for ( $i = 0; $i < @track_list; $i++ ) + { + $cookie->{ 'FEAT_COLOR' } = Maasha::BGB::Draw::palette( $i ); + + push @tracks, [ Maasha::BGB::Track::track_feature( $track_list[ $i ], $cookie ) ]; + } + + unshift @tracks, [ Maasha::BGB::Track::track_grid( $cookie ) ]; + + $file = "$cookie->{ 'SESSION_DIR' }/$cookie->{ 'USER' }/BGB_export.pdf"; + + Maasha::BGB::Draw::render_pdf_file( $file, $cookie->{ 'IMG_WIDTH' }, $cookie->{ 'TRACK_OFFSET' }, \@tracks ); + + push @html, Maasha::XHTML::p( txt => Maasha::XHTML::ln( txt => "BGB_export.pdf", href => $file ), class => 'center' ); + + return wantarray ? @html : \@html; +} + + +sub section_export_svg +{ + # Martin A. Hansen, March 2010. + + # Export view in SVG format. + + my ( $cookie, # cookie hash + ) = @_; + + # Returns a list. + + my ( @tracks, @track_list, $i, $file, @html ); + + push @tracks, [ Maasha::BGB::Track::track_ruler( $cookie ) ]; + push @tracks, [ Maasha::BGB::Track::track_seq( $cookie ) ]; + + @track_list = Maasha::BGB::Track::list_track_dir( $cookie->{ 'USER' }, $cookie->{ 'CLADE' }, $cookie->{ 'GENOME' }, $cookie->{ 'ASSEMBLY' }, $cookie->{ 'CONTIG' } ); + + for ( $i = 0; $i < @track_list; $i++ ) + { + $cookie->{ 'FEAT_COLOR' } = Maasha::BGB::Draw::palette( $i ); + + push @tracks, [ Maasha::BGB::Track::track_feature( $track_list[ $i ], $cookie ) ]; + } + + unshift @tracks, [ Maasha::BGB::Track::track_grid( $cookie ) ]; + + $file = "$cookie->{ 'SESSION_DIR' }/$cookie->{ 'USER' }/BGB_export.svg"; + + Maasha::BGB::Draw::render_svg_file( $file, $cookie->{ 'IMG_WIDTH' }, $cookie->{ 'TRACK_OFFSET' }, \@tracks ); + + push @html, Maasha::XHTML::p( txt => Maasha::XHTML::ln( txt => "BGB_export.svg", href => $file ), class => 'center' ); + + return wantarray ? @html : \@html; +} + + sub section_search { # Martin A. Hansen, November 2009. -- 2.39.2