Code Search for Developers
 
 
  

GeneView.pm from eXtensible Genome Data Broker at Krugle


Show GeneView.pm syntax highlighted

#!/usr/bin/perl -w
package GeneView;


#use strict;

use FileHandle;
use CGI;
use GD;

do 'SITEDEF.pl';
do 'xGDB_SUPPORTED_COLORS.pl';

############# Defaults #################
my $StartX=20;
my $Margin=10;
my $LabelHeight=4;
my $LabelSpace=10;
my $HeightInc=150;
my $HalfLabelHeight=$LabelHeight/2;
my $StartY=50;
my $RulerHeight=3;
my $IDHeight=15;
#########################################




############################## Constructor ################################
# new GeneView($imgWidth,$imgHeight,$begPos,$endPos);
sub new {
    my ($class,@param) = @_;
    my $self = {};
    bless $self, ref($class) || $class;
    $self->_initialize(@param);
    return $self;
}

sub _initialize{
  my $self = shift;
  my ($imgWidth,$imgHeight,$begPos,$endPos,$noRULER,$scale)=@_;
  
  $noRULER = 0 if(!defined($noRULER));

  $self->{'imgWidth'}= $imgWidth;
  $self->{'imgHeight'}=$imgHeight;
  $self->{'imgHeight'}=$imgHeight;
  $self->{'begPos'}=$begPos;
  $self->{'endPos'}=$endPos;
  
  # assign some variables for the image;
  my $unit=1000;
  my $len=$endPos-$begPos+1;
  if($len<1000){
    $unit=10;
  }elsif($len<10000){
    $unit=100;
  }

  if($noRULER == 1){
    $StartY=10;
    $HeightInc=1;
    $self->{'zeroPos'}=int($begPos);
    $self->{'seqLen'}=$endPos- $self->{'zeroPos'} + 1;
    
    my $ratio=$self->{'seqLen'}/($self->{'imgWidth'}-$StartX-2*$Margin);
    $ratio = $scale if($scale);
    $self->{'rulerLen'}=$self->{'seqLen'}/$ratio;
    $self->{'scale'}=$self->{'seqLen'}/$self->{'rulerLen'};
    $self->{'currHeight'}=10;
    $self->{'img'} = new GD::Image($imgWidth,$imgHeight);
    $self->{'isLabeled'}= ($self->{'scale'}<100)?1:0;
    $self->_defColor($self->{'img'});
  }else{
    $self->{'zeroPos'}=int($begPos);
    $self->{'tickStart'}=(int($begPos/$unit))*$unit;
    $self->{'seqLen'}=$endPos- $self->{'zeroPos'} + 1;

    my $ratio=$self->{'seqLen'}/($self->{'imgWidth'}-$StartX-2*$Margin);
    $self->{'rulerLen'}=$self->{'seqLen'}/$ratio + 0.5;
    $self->{'scale'}=$self->{'seqLen'}/$self->{'rulerLen'};
    $self->{'currHeight'}=10;
    $self->{'img'} = new GD::Image($imgWidth,$imgHeight);
    $self->{'isLabeled'}= ($self->{'scale'}<100)?1:0;
    $self->_defColor($self->{'img'});
    $self->_drawRuler();
  }
}

sub setLabelOn{
    my $self = shift;
    $self->{'isLabeled'} = shift;
}

sub _clear{
    #do nothing
}

#draw the ruler
sub _drawRuler{
  my $self= shift;
  my $nextPower=0.001;
  my $MinDist=100;
  my $ruler;
  my $im=$self->{'img'};
  
  # get the resolution of the ruler
  my $minDist=$MinDist*$self->{'scale'};
  while($nextPower<$minDist){
    $nextPower*=10;
  }
  if($minDist<$nextPower/5.0){
    $ruler=($nextPower+0.5)/5.0;
  }elsif($minDist<$nextPower/4.0){
    $ruler=($nextPower+0.5)/4.0;
  }elsif($minDist<$nextPower/2){
    $ruler=($nextPower+0.5)/2.0;
  }else{
    $ruler=$nextPower+0.5;
  }
  
  $im->filledRectangle(min($self->_pos2x($self->{'zeroPos'}),($self->_pos2x($self->{'tickStart'}))),
		       $self->{'currHeight'},$self->_pos2x($self->{'endPos'}),
		       $self->{'currHeight'}+$RulerHeight,$self->{'black'});
  
  {
    use integer;
    my($tick_len,$x_pos,$pos,$i);
    $self->{'currHeight'}+=$RulerHeight;
    
    $ruler=$ruler/10;
    for($pos=$self->{'tickStart'},$i=0;
	$pos<=$self->{'endPos'};
	$pos+=$ruler,$i++){
      $tick_len=($i%5==0)?6:3;
      $x_pos=$self->_pos2x($pos);
      if($i%5==0){
	$im->string(gdTinyFont,
		    $x_pos-(gdTinyFont->width)*length($pos)/2,
		    $self->{'currHeight'}+10,$pos,$self->{'black'});
      }
      $im->line($x_pos,$self->{'currHeight'},$x_pos,
		$self->{'currHeight'}+$tick_len,$self->{'black'});
    }
  }
}

sub _pos2x{
    my $self=shift;
    my($pos)=@_;
    return int(( $pos - $self->{'zeroPos'} )/$self->{'scale'} + $StartX);
}

sub drawPNG{
    my ($self, $outfn) = @_;
    open (IMG,"> $outfn") or die "Cannot open file $outfn!";
    binmode IMG;
    print IMG $self->{'img'}->png;
    close IMG;
}
# to find the specified region is occupied or not
sub _isEmpty{
    my $self = shift;
    my($x1,$x2,$h)=@_;
    my $c;
    my $i;

    for($i=$x1-8;$i<=$x2+8;$i+=2){
        $c= $self->{'img'}->getPixel($i,$h);
        return 0 if($c != $self->{'white'});
    }
    return 1;
}

sub _defColor{
    my $self = shift;
    my ($img) = @_;
    $self->{'white'}=$img->colorAllocate(255, 255, 255);
    $self->{'black'}=$img->colorAllocate(0, 0, 0);
    $self->{'red'}=$img->colorAllocate(255, 0, 0);
    $self->{'green'}=$img->colorAllocate(0, 255, 0);
    $self->{'blue'}=$img->colorAllocate(0, 0, 255);

}

sub _GV_addColor{
  my $self = shift;
  my ($colorname) = @_;

  if(exists($SUPPORTED_COLORS{lc($colorname)})){
#    print STDERR "Resolving color $colorname\n";
    return $self->{img}->colorResolve(@{$SUPPORTED_COLORS{lc($colorname)}});
  }else{
    print STDERR "[GeneView.pm] The color $colorname is NOT SUPPORTED!\n";
    return undef;
  }
}

sub _getHeight{
    my $self = shift;
    my($x1,$x2,$height)=@_;
    my $labelSpace=$LabelSpace+(($self->{'isLabeled'})?$IDHeight:0);
    while(!(($self->_isEmpty($x1,$x2,$height)) &&
	    ($self->_isEmpty($x1,$x2,$height + $HalfLabelHeight + 8)) &&
	    ($self->_isEmpty($x1,$x2,$height + 5)) &&
	    ($self->_isEmpty($x1,$x2,$height - 5)))){
      $height+=$labelSpace;
    }
    if($height+$LabelHeight+$labelSpace>$self->{'imgHeight'}){
        #$HeightInc = $height;
        #resize the image
        #my $newPicHeight=$self->{'imgHeight'}+$HeightInc;
	my $newPicHeight=$height+$LabelHeight+$labelSpace;
        my $tmpIm=new GD::Image($self->{'imgWidth'},$newPicHeight);
        $self->_defColor($tmpIm);
        $tmpIm->copy($self->{'img'},0,0,0,0,
            $self->{'imgWidth'},$self->{'imgHeight'});
        $self->{'img'}=$tmpIm;
        $self->{'imgHeight'}=$newPicHeight;
    }
    return $height;
}

sub _drawBar{
  my $self = shift;
  my($a,$b,$height,$c)=@_;
  my $x1=$self->_pos2x($a);
  my $x2=$self->_pos2x($b);

  return undef if((($x1 < 0)&&($x2 < 0))||(($x1 > $self->{imgWidth})&&($x2 > $self->{imgWidth})));

  $x2=$x1+2 if($x2-$x1<2);
  { 
    use integer;
    $self->{'img'}->filledRectangle($x1,$height-$HalfLabelHeight,$x2,
				    $height+$HalfLabelHeight,$c);
  }
}

sub _drawStartBar{
  my $self = shift;
  my($a,$b,$height,$c,$c_s,$isReversed)=@_;
  my $x1=$self->_pos2x($a);
  my $x2=$self->_pos2x($b);
  
  return undef if((($x1 < 0)&&($x2 < 0))||(($x1 > $self->{imgWidth})&&($x2 > $self->{imgWidth})));
  
  if($x2-$x1<2){
    $x2 = $x1+2;
    use integer;
    $self->{'img'}->filledRectangle($x1,$height-$HalfLabelHeight,$x2,
				    $height+$HalfLabelHeight,$c_s);
  }elsif($isReversed){
    use integer;
    $self->{'img'}->filledRectangle($x2-4,$height-$HalfLabelHeight,$x2,
				    $height+$HalfLabelHeight,$c_s);
    $self->{'img'}->filledRectangle($x1,$height-$HalfLabelHeight,$x2-4,
				    $height+$HalfLabelHeight,$c);
  }else{
    use integer;
    $self->{'img'}->filledRectangle($x1,$height-$HalfLabelHeight,$x1+4,
				    $height+$HalfLabelHeight,$c_s);
    $self->{'img'}->filledRectangle($x1+4,$height-$HalfLabelHeight,$x2,
				    $height+$HalfLabelHeight,$c);
  }
}

sub _drawArrow{
  my $self = shift;
  my($a,$b,$height,$c,$c_a,$dir)=@_;
  my $x1=$self->_pos2x($a);
  my $x2=$self->_pos2x($b);

  return undef if((($x1 < 0)&&($x2 < 0))||(($x1 > $self->{imgWidth})&&($x2 > $self->{imgWidth})));

  my $poly=new GD::Polygon;
 
  $x2=$x1+2 if($x2-$x1<2);
  { use integer;
    if($dir){
      $poly->addPt($x1,$height);
      $poly->addPt(&max(&min($x1+5,$x2),$x1+2),$height-5);
      $poly->addPt(&max(&min($x1+5,$x2),$x1+2),$height+5);
      $self->{'img'}->filledPolygon($poly,$c_a);
      if($x2-$x1>5){#draw a bar
	$self->{'img'}->filledRectangle($x1+5,$height-$HalfLabelHeight,$x2,$height+$HalfLabelHeight,$c);
      }
    }else{
      $poly->addPt($x2,$height);
      $poly->addPt(&min(&max($x1,$x2-5),$x2-2),$height-5);
      $poly->addPt(&min(&max($x1,$x2-5),$x2-2),$height+5);
      $self->{'img'}->filledPolygon($poly,$c_a);
      if($x2-$x1>5){#draw a bar
	$self->{'img'}->filledRectangle($x1,$height-$HalfLabelHeight,$x2-5,$height+$HalfLabelHeight,$c);
      }
    }
  }
}

sub _drawSEdot{
  my $self = shift;
  my($a,$b,$height,$c)=@_;
  my $x1=$self->_pos2x($a);
  my $x2=$self->_pos2x($b);
  
  return undef if((($x1 < 0)&&($x2 < 0))||(($x1 > $self->{imgWidth})&&($x2 > $self->{imgWidth})));
  
  my $mid=($x1+$x2)/2;
  
  if((($mid - 2) > 0)&&(($mid + 2) < $self->{'imgWidth'})){
    $self->{'img'}->filledRectangle($mid - 2,$height-$HalfLabelHeight,$mid + 2,$height+$HalfLabelHeight,$c);
  }
}

sub drawPair{
  my $self = shift;
  my($x1,$h1,$x2,$h2,$color) = @_;
  my $c=$self->_GV_addColor($color);
  $self->{'img'}->rectangle($x1-2,$h1+$HalfLabelHeight-5,$x2+2,$h2-$HalfLabelHeight+5,$c);
}

sub drawFLAG{
  my($self,$FLAG_filename,$x,$y) = @_;
  
  open(FLAGfile,"$FLAG_filename") || die "couldn't open flag file <$FLAG_filename>\n";
  my $FLAGimg = GD::Image->new(FLAGfile);
  $self->{'img'}->rectangle($x,$y,$x+22,$y+22,$self->{'grey'});
  $self->{'img'}->copy($FLAGimg,$x+2,$y+2,0,0,20,20);
  close(FLAGfile);

  return $x + 24;
}

sub descFLAG{
  my($self,$FLG_DESC,$oc_url,@coords) = @_;

  #$FLG_DESC = CGI::escape($FLG_DESC);

  my $areaTAG = "<AREA SHAPE=\"RECT\" COORDS=\"".join(',',@coords)."\" HREF=\"$oc_url\"".
    " onmouseover=\"document.guiFORM.defline.value='$FLG_DESC';\"".
      " onmouseout=\"document.guiFORM.defline.value='Mouse over for description. Click to retrieve individual record.';\">\n";

  return $areaTAG;
}

sub addFLAGS{
  my($self,$startHeight,$info,$utr5,$cov,$utr3,$props,$oc_url) = @_;
  my $strand = ($info =~ /comp/)? 1:0;
  $info =~ s/[^\d\.,]//g;
  my @pgs = split(/[\D\.,]+/,$info);
  my $initHeight=($startHeight)?$startHeight+$HalfLabelHeight:$StartY;
  my $x1=$self->_pos2x($pgs[0]);
  my $x2=$self->_pos2x($pgs[$#pgs]);
  my $height=$self->_getHeight(&min($x1,$x2),&max($x2,$x1),$initHeight);
  my ($curX,$FLAGdesc,$imap,@props);

  if(($x2 - $x1) > 74){
    ## Enough room for at least utr5/cov/utr3 flags
    $curX = $x1+2;
    if($strand){
      $curX = drawFLAG($self,$FLAG_UTR3[$utr3],$curX,$height-4);
      $imap .= descFLAG($self,$FLAGdesc_UTR3[$utr3],$oc_url,$x1,$height-6,$curX-1,$height+20);
    }else{
      $curX = drawFLAG($self,$FLAG_UTR5[$utr5],$curX,$height-4);
      $imap .= descFLAG($self,$FLAGdesc_UTR5[$utr5],$oc_url,$x1,$height-6,$curX-1,$height+20);
    }
    
    $curX = drawFLAG($self,$FLAG_COV[$cov],$curX,$height-4);
    $imap .= descFLAG($self,$FLAGdesc_COV[$cov],$oc_url,$curX-24,$height-6,$curX-1,$height+20);
    
    if($strand){
      $curX = drawFLAG($self,$FLAG_UTR5[$utr5],$curX,$height-4);
      $imap .= descFLAG($self,$FLAGdesc_UTR5[$utr5],$oc_url,$curX-24,$height-6,$curX-1,$height+20);
    }else{
      $curX = drawFLAG($self,$FLAG_UTR3[$utr3],$curX,$height-4);
      $imap .= descFLAG($self,$FLAGdesc_UTR3[$utr3],$oc_url,$curX-24,$height-6,$curX-1,$height+20);
    }

    if(($x2 - $curX) > 24){
      ## Draw props flags as space allows
      chop($props) if($props =~ /:$/);
      @props = split(':',$props);
      while((($x2 - $curX) > 50)&&(scalar @props)){
	$props = shift @props;
        if($FLAG_PROP[$props] ne ""){
  	  $curX = drawFLAG($self,$FLAG_PROP[$props],$curX,$height-4);
	  $imap .= descFLAG($self,$FLAGdesc_PROP[$props],$oc_url,$curX-24,$height-6,$curX-1,$height+20);
        }
      }
      if(scalar @props){
	## draw FLAG_GAEVAL_MORE to show that more props remain unseen
	$curX = drawFLAG($self,$FLAG_GAEVAL_MORE,$curX,$height-4);
	$imap .= descFLAG($self,$FLAGdesc_GAEVAL_MORE,$oc_url,$curX-24,$height-6,$curX-1,$height+20);
	$FLAGdesc = $FLAGdesc_GAEVAL_MORE;
      }else{
	## draw FLAG_GAEVAL to show all props are displayed
	$curX = drawFLAG($self,$FLAG_GAEVAL,$curX,$height-4);
	$imap .= descFLAG($self,$FLAGdesc_GAEVAL,$oc_url,$curX-24,$height-6,$curX-1,$height+20);
	$FLAGdesc = $FLAGdesc_GAEVAL;
      }
    }
  }else{
    ## Only enough room for cov flag
    $curX = $x1+2;
    $curX = drawFLAG($self,$FLAG_COV[$cov],$curX,$height-4);
    $imap .= descFLAG($self,$FLAGdesc_COV[$cov],$oc_url,$x1,$height-6,$curX-1,$height+20);
    if(($x2 - $curX) > 24){
      ## draw FLAG_GAEVAL_MORE to show that more props remain unseen
      $curX = drawFLAG($self,$FLAG_GAEVAL_MORE,$curX,$height-4);
      $imap .= descFLAG($self,$FLAGdesc_GAEVAL_MORE,$oc_url,$curX-24,$height-6,$curX-1,$height+20);
    }
    $FLAGdesc = $FLAGdesc_GAEVAL_MORE;
  }
  
  $x2 = $curX if ($curX > $x2);
  $self->{'img'}->rectangle($x1,$height-6,$x2,$height+20,$self->{'india red'});
  $imap .= descFLAG($self,$FLAGdesc,$oc_url,$curX,$height-6,$x2,$height+20);

  return ($x1,$height-6,$x2,$height+20,$imap);

}

sub addMarker{
  my $self = shift;
  my($argHR,@posArray)=@_;
  my ($i,$pos,@label);

  my $c=(exists($argHR->{color}))?$argHR->{color}:"grey";
  my $c_a = (exists($argHR->{arrowColor}))?$argHR->{arrowColor}:$c;
  my $c_s = (exists($argHR->{startColor}))?$argHR->{startColor}:$c;
  my $c_d = (exists($argHR->{dotColor}))?$argHR->{dotColor}:$c;
  
  my $idHalfLen=($self->{'isLabeled'})?(gdTinyFont->width)*length($argHR->{label})/2:0;
  my $initHeight=(exists($argHR->{startHeight}))?$argHR->{startHeight}+$HalfLabelHeight:$StartY;
  
  my $isReversed = ($posArray[0] > $posArray[$#posArray])?1:0;
  my $x1 = min(max($self->_pos2x($posArray[0]),0),$self->{imgWidth});
  my $x2 = min(max($self->_pos2x($posArray[$#posArray]),0),$self->{imgWidth});
  my $mid=($x1+$x2)/2;
  &swap(\$x1,\$x2) if $isReversed;
  
  my $height=$self->_getHeight(&min($x1,$mid-$idHalfLen),&max($x2,$mid+$idHalfLen),$initHeight);
  
  $self->{'img'}->line($x1+1,$height,$x2-1,$height,$self->_GV_addColor($c));

  if(($self->{'isLabeled'})&&(exists($argHR->{label}))){  #draw ID
    $self->{'img'}->string(gdTinyFont,$mid-$idHalfLen,$height+$HalfLabelHeight+5,$argHR->{label},$self->_GV_addColor('black'));
    @label = ($mid - $idHalfLen,$height + $HalfLabelHeight + 5 ,$mid + $idHalfLen,$height + $HalfLabelHeight + 15);
  }else{
    @label = (-1,-1,-1,-1);
  }

  for($pos=0;$pos<=$#posArray;$pos++){
    if($posArray[$pos] < $self->{'zeroPos'}){
      $posArray[$pos] = $self->_pos2x($self->{'zeroPos'});
    }elsif($posArray[$pos] > $self->{'endPos'}){
      $posArray[$pos] = $self->_pos2x($self->{'endPos'});
    }else{
      $posArray[$pos] = $self->_pos2x($posArray[$pos]);
    }
  }
  return ([@label],[$height-$HalfLabelHeight,$height+$HalfLabelHeight,@posArray]);
}


sub addCDS{
  my($self,$startHeight,$cstart,$cend) = @_;
  my $x1=$self->_pos2x($cstart);
  my $x2=$self->_pos2x($cend);
  my $poly=new GD::Polygon;
  my $poly2=new GD::Polygon;

  if(($cstart >= $self->{begPos})&&($cstart <= $self->{endPos})){
    #draw CDS start triangle
    $poly->addPt($x1,$startHeight);
    $poly->addPt($x1 - 2,$startHeight - 5);
    $poly->addPt($x1 + 2,$startHeight - 5);
    $self->{'img'}->filledPolygon($poly,$self->{'green'});
  }

  if(($cend >= $self->{begPos})&&($cend <= $self->{endPos})){
    #draw CDS stop triangle
    $poly2->addPt($x2,$startHeight);
    $poly2->addPt($x2 - 2,$startHeight - 5);
    $poly2->addPt($x2 + 2,$startHeight - 5);
    $self->{'img'}->filledPolygon($poly2,$self->{'red'});
  }
}

sub addGseg{
  my $self = shift;
  my($argHR,@posArray)=@_;
  my(@label);

  my $c   = (exists($argHR->{color}))?$argHR->{color}:"green";;
  my $c_l = (exists($argHR->{leftColor}))?$argHR->{leftColor}:$c;
  my $c_r = (exists($argHR->{rightColor}))?$argHR->{rightColor}:$c;

  my $idHalfLen=($self->{'isLabeled'})?(gdTinyFont->width)*length($argHR->{label})/2:0;
  my $initHeight=(exists($argHR->{startHeight}))?$argHR->{startHeight}+$HalfLabelHeight:$StartY;
  
  my $isReversed = ($posArray[0] > $posArray[$#posArray])?1:0;
  @posArray = reverse @posArray if($isReversed);
  my $x1=$self->_pos2x(&max($posArray[0],$self->{'zeroPos'}));
  my $x2=$self->_pos2x(&min($posArray[$#posArray],$self->{'endPos'}));
  my $mid=($x1+$x2)/2;

  my $height=$self->_getHeight(&min($x1,$mid-$idHalfLen),&max($x2,$mid+$idHalfLen),$initHeight);
  $height += 8; ## Adding room for IDs on top

  my $nextPower  = 0.001;
  my $MinDist    = 100;
  my $halfStroke = 1;
  my $ruler;
  my $minDist=$MinDist*$self->{'scale'};
  while($nextPower<$minDist){$nextPower*=10;}
  if($minDist<$nextPower/5.0){
    $ruler=($nextPower+0.5)/5.0;
  }elsif($minDist<$nextPower/4.0){
    $ruler=($nextPower+0.5)/4.0;
  }elsif($minDist<$nextPower/2){
    $ruler=($nextPower+0.5)/2.0;
  }else{
    $ruler=$nextPower+0.5;
  }

  if($#posArray > 1){
    if($posArray[1] > $self->{'zeroPos'}){
      $self->{'img'}->rectangle($x1,$height - $halfStroke,$self->_pos2x($posArray[1]),$height + $HalfLabelHeight,$self->_GV_addColor($c_l));
    }
    if($posArray[2] < $self->{'endPos'}){
      $self->{'img'}->rectangle($self->_pos2x($posArray[2]),$height - $halfStroke,$x2,$height + $HalfLabelHeight,$self->_GV_addColor($c_r));
    }
    $self->{'img'}->filledRectangle($self->_pos2x($posArray[1]),$height - $halfStroke,$self->_pos2x($posArray[2]),$height + $halfStroke,$self->_GV_addColor($c));
  }else{
    $self->{'img'}->filledRectangle($x1,$height - $halfStroke,$x2,$height + $halfStroke,$self->_GV_addColor($c));
  }
  {
    use integer;
    my($show_coords,$tick_len,$x_pos,$pos,$bpos,$i);
    $ruler=$ruler/10;
    ## This hides the coords if the drawing is too small unless overridden by argHR!
    $show_coords = (exists($argHR->{showCoords}))?$argHR->{showCoords}:(($posArray[0] + (2 * $ruler)) < $posArray[$#posArray]);

    for($pos=&max($posArray[0],$self->{'zeroPos'}),$i=0;
	$pos<=&min($posArray[$#posArray],$self->{'endPos'});
	$pos+=$ruler,$i++){
      $bpos = ($isReversed)?$posArray[$#posArray] - $pos + 1 : $pos - $posArray[0] + 1;
      $tick_len=($i%5==0)?$HalfLabelHeight:($HalfLabelHeight / 2);
      $x_pos=$self->_pos2x($pos);
      if($show_coords && ($i%5==0)&&(($pos + (2* $ruler))<$posArray[$#posArray])){
	$self->{'img'}->string(gdTinyFont,
		    $x_pos-(gdTinyFont->width)*length($bpos)/2,
		    $height + 5,
		    $bpos,
		    $self->_GV_addColor('black'));
      }
      $self->{'img'}->line($x_pos,$height - $tick_len,$x_pos,$height + $tick_len,$self->_GV_addColor('black'));
    }
    ## Add final tick mark for fully contained structures
    if($posArray[$#posArray] < $self->{'endPos'}){
      $bpos = ($isReversed)? 1 : $posArray[$#posArray] - $posArray[0];
      $x_pos=$self->_pos2x($posArray[$#posArray]); $tick_len=$HalfLabelHeight;
      $self->{'img'}->string(gdTinyFont,$x_pos-(gdTinyFont->width)*length($bpos)/2,$height + 5,$bpos,$self->_GV_addColor('black')) if($show_coords);
      $self->{'img'}->line($x_pos,$height - $tick_len,$x_pos,$height + $tick_len,$self->_GV_addColor('black'));
    }
  }
  if(($self->{'isLabeled'})&&(exists($argHR->{label}))){
    $self->{'img'}->string(gdTinyFont,
			   $mid - $idHalfLen,$height - 10,
			   $argHR->{label},$self->_GV_addColor('black'));
    @label = ($mid - $idHalfLen,$height - 10,$mid + $idHalfLen,$height);
  }else{
    @label = (-1,-1,-1,-1);
  }

  for($pos=0;$pos<=$#posArray;$pos++){
    if($posArray[$pos] < $self->{'zeroPos'}){
      $posArray[$pos] = $self->_pos2x($self->{'zeroPos'});
    }elsif($posArray[$pos] > $self->{'endPos'}){
      $posArray[$pos] = $self->_pos2x($self->{'endPos'});
    }else{
      $posArray[$pos] = $self->_pos2x($posArray[$pos]);
    }
  }
  @posArray = reverse @posArray if($isReversed);
  return ([@label],[$height-$HalfLabelHeight,$height+$HalfLabelHeight,@posArray]);
}

sub addGene{
  my $self = shift;
  my($argHR,@posArray)=@_;
  my ($i,$pos,@label);
  
  my $c=(exists($argHR->{color}))?$argHR->{color}:"red";
  my $c_a = (exists($argHR->{arrowColor}))?$argHR->{arrowColor}:$c;
  my $c_s = (exists($argHR->{startColor}))?$argHR->{startColor}:$c;
  my $c_d = (exists($argHR->{dotColor}))?$argHR->{dotColor}:$c;
  
  my $idHalfLen=($self->{'isLabeled'})?(gdTinyFont->width)*length($argHR->{label})/2:0;
  my $initHeight=(exists($argHR->{startHeight}))?$argHR->{startHeight}+$HalfLabelHeight:$StartY;
  
  my $isReversed = ($posArray[0] > $posArray[$#posArray])?1:0;
  my $x1 = min(max($self->_pos2x($posArray[0]),0),$self->{imgWidth});
  my $x2 = min(max($self->_pos2x($posArray[$#posArray]),0),$self->{imgWidth});
  my $mid=($x1+$x2)/2;
  &swap(\$x1,\$x2) if $isReversed;
  
  my $height=$self->_getHeight(&min($x1,$mid-$idHalfLen),&max($x2,$mid+$idHalfLen),$initHeight);
  
  $self->{'img'}->line($x1+1,$height,$x2-1,$height,$self->_GV_addColor($c));
  if($isReversed){
    if(($#posArray > 1)||(exists($argHR->{drawArrowhead}))){
      if(($#posArray == 1)&&(exists($argHR->{drawArrowhead}))){
	$self->_drawArrow($posArray[$#posArray],$posArray[$#posArray-1],$height,$self->_GV_addColor($c),$self->_GV_addColor($c_a),$isReversed);
      }else{
	$self->_drawStartBar($posArray[1],$posArray[0],$height,$self->_GV_addColor($c),$self->_GV_addColor($c_s),$isReversed);
	for($i=2;$i<@posArray-2;$i+=2){
	  $self->_drawBar($posArray[$i+1],$posArray[$i],$height,$self->_GV_addColor($c));
	}
	$self->_drawArrow($posArray[$#posArray],$posArray[$#posArray-1],$height,$self->_GV_addColor($c),$self->_GV_addColor($c_a),$isReversed);
      }
    }else{
      $self->_drawStartBar($posArray[1],$posArray[0],$height,$self->_GV_addColor($c),$self->_GV_addColor($c),$isReversed);
      $self->_drawSEdot($posArray[1],$posArray[0],$height,$self->_GV_addColor($c_d));
    }
  }else{
    if(($#posArray > 1)||(exists($argHR->{drawArrowhead}))){
      if(($#posArray == 1)&&(exists($argHR->{drawArrowhead}))){
	$self->_drawArrow($posArray[$#posArray-1],$posArray[$#posArray],$height,$self->_GV_addColor($c),$self->_GV_addColor($c_a),$isReversed);
      }else{
	$self->_drawStartBar($posArray[0],$posArray[1],$height,$self->_GV_addColor($c),$self->_GV_addColor($c_s),$isReversed);
	for($i=2;$i<@posArray-2;$i+=2){
	  $self->_drawBar($posArray[$i],$posArray[$i+1],$height,$self->_GV_addColor($c));
	}
	$self->_drawArrow($posArray[$#posArray-1],$posArray[$#posArray],$height,$self->_GV_addColor($c),$self->_GV_addColor($c_a),$isReversed);
      }
    }else{
      $self->_drawStartBar($posArray[0],$posArray[1],$height,$self->_GV_addColor($c),$self->_GV_addColor($c),$isReversed);
      $self->_drawSEdot($posArray[0],$posArray[1],$height,$self->_GV_addColor($c_d));
    }
  }
  
  #draw ID
  if(($self->{'isLabeled'})&&(exists($argHR->{label}))){
    $self->{'img'}->string(gdTinyFont,$mid-$idHalfLen,$height+$HalfLabelHeight+5,
			   $argHR->{label},$self->_GV_addColor('black'));
    @label = ($mid - $idHalfLen,$height + $HalfLabelHeight + 5 ,$mid + $idHalfLen,$height + $HalfLabelHeight + 15);
  }else{
    @label = (-1,-1,-1,-1);
  }

  for($pos=0;$pos<=$#posArray;$pos++){
    if($posArray[$pos] < $self->{'zeroPos'}){
      $posArray[$pos] = $self->_pos2x($self->{'zeroPos'});
    }elsif($posArray[$pos] > $self->{'endPos'}){
      $posArray[$pos] = $self->_pos2x($self->{'endPos'});
    }else{
      $posArray[$pos] = $self->_pos2x($posArray[$pos]);
    }
  }
  return ([@label],[$height-$HalfLabelHeight,$height+$HalfLabelHeight,@posArray]);
}

sub showSplicePattern{
  my $self = shift;
  my($argHR,@cds)=@_;
  my ($a,$x,$c,$diff);
  
  $c=(exists($argHR->{color}))?$argHR->{color}:'red';

  if($cds[0] > $cds[$#cds]){
    ## reverse strand PGS
    $a = $cds[0];
    $x = $cds[$#cds];
    for(my $y=0;$y<=$#cds;$y++){
      $cds[$y] = ($a + $x) - $cds[$y];
    }
  }
  
  $diff=0;
  for($x=1;$x<$#cds;$x+=2){
    $diff += ($cds[$x+1] - $cds[$x]);
  }   
   
  $self->_drawArrow($cds[0],($cds[$#cds] - $diff),$StartY,$self->_GV_addColor($c),$self->_GV_addColor($c),0);
  $a=0; $diff=0;
  for($x=1;$x<$#cds;$x+=2){
    $a = $self->_pos2x($cds[$x] - $diff);
    $self->{'img'}->filledRectangle($a,$StartY-$LabelHeight,$a+2,$StartY+$LabelHeight,$self->_GV_addColor('green'));
    $diff += ($cds[$x+1] - $cds[$x]);
  }
}

sub swap{
    my($x,$y)=@_;
    if($$x>$$y){
        my $temp=$$x;
        $$x=$$y;
        $$y=$temp;
    }
}

sub min{return ($_[0] < $_[1])?$_[0]:$_[1];}

sub max{return ($_[0] > $_[1])?$_[0]:$_[1];}

sub DESTROY {
    my $self=shift;
    $self->_clear();
}

##################### End of Package #########################
1;




See more files for this project here

eXtensible Genome Data Broker

The xGDB project provides scientists with an online portal for the integration of diverse sources of genomic data. Portals allow researchers to effectively target a specific scientific question by customizing their interactions with available data.

Project homepage: http://sourceforge.net/projects/xgdb
Programming language(s): JavaScript,Perl,PHP
License: other

  DSO/
    AnnotationTrack.pm
    BAC.pm
    CDNApgs.pm
    ESTpgs.pm
    GBKann.pm
    GSEG.pm
    GeneSeqerSequence.pm
    GenomeSegmentTrack.pm
    Locus.pm
    Marker.pm
    PROBE.pm
    SequenceTrack.pm
    TIGRtu.pm
    UCAann.pm
  fct/
    GenomeData.pm
  GDBgui.pm
  GSQDB.pm
  GeneView.pm
  GenomeView.pm
  SeqUtils.pm
  checkLOGIN.pl
  getPARAM.pl
  index.html
  xGDB_SUPPORTED_COLORS.pl