Chemistry-Artificial-Graphics

 view release on metacpan or  search on metacpan

lib/Chemistry/Artificial/Graphics.pm  view on Meta::CPAN

=head2 Graphic plot

These functions are used in the plot process.

=cut

=head3 Common functions (not depending of the graphic type)

These functions are used to write SVG files, and they are:

=cut

=over 4

=item $graph->write_style()

Here we define the style of the objects in the graph, for example: path (the 
lines), circle(the components), text (text properties)...

Here we defined the arrows directions too.

This function should be called from the inside of the module, not being 
recomended to call it from an external applicattion.

=cut

sub write_style
{	
my $self = shift;
open (svgfile,">>$self->{file}") or die("Couldn't open File\n");
my $function2 = '
<defs>
<radialGradient id="mygradient1" cx="10%" cy="10%" r="100%" fx="25%" fy="25%" 
gradientUnits="objectBoundingBox">
 <stop id="2stop1" offset="0%" style="stop-color:blue;"/>
 <stop id="2stop2" offset="100%" style="stop-color:black;"/>
</radialGradient>
<marker id="Triangle_down" viewBox="0 0 10 10" refX="10" refY="5"
 markerUnits="strokeWidth" markerWidth="16" markerHeight="12" stroke="green"
 orient="90">
 <path d="M0,0 L10,5 L0,10 z"/>
</marker>
<marker id="Triangle_up" viewBox="0 0 10 10" refX="10" refY="5"
 markerUnits="strokeWidth" markerWidth="16" markerHeight="12" stroke="green"
 orient="270">
 <path d="M0,0 L10,5 L0,10 z"/>
</marker>

<marker id="Triangle_up_down" viewBox="0 0 10 10" refX="10" refY="5"
 markerUnits="strokeWidth" markerWidth="16" markerHeight="12" stroke="green"
 orient="270">
 <path d="M0,0 L10,5 L0,10 z"/>
</marker>


</defs>'."\n";
print svgfile $function2;
close (svgfile);
}

=item $graph->write_circle(x, y, id, color, smilestring, child, formula,
reaction, reaction_type, atommap, elembefore)

This function writes a component in the graph.

	The properties:
	* id: This is an unique id for one component in the graph.
	* cx: X position.

This function should be called from the inside of the module, not being 
recomended to call it from an external applicattion.

=cut

sub write_circle
{	
my $self = shift;
my ($x,$y,$id,$color,$smilestring,$child,$formula,$reaction,$reaction_type,
$atommap,$elembefore)=@_;
open (svgfile,">>$self->{file}") or die("Couldn't open File\n");
print svgfile '<circle id="c'. $id .'" onclick="showContentAndRelatives(evt)" 
cx="'. $x. '" cy="' .$y. '" r="20" stroke="'.$color.'" 
smilestring="'. $smilestring .'" child="'. $child.'" formula="'. $formula.'" 
reaction="'. $reaction.'" reactiontype="'. 
$reaction_type.'" atommap="'. $atommap.'" elembefore="'. $elembefore.'"  
style="fill:url(#mygradient1)" stroke-with="1"/>' ."\n";
close (svgfile);
}

=item $graph->write_text(text, x, y, id)

Function used to write a text line in the SVG.

	The properties:
	* x: X position to start the text.
	* y: Y positicion to start the text.

This function should be called from the inside of the module, not being 
recomended to call it from an external applicattion.

=cut

sub write_text 
{
my $self = shift;
my ($text,$x,$y,$id)=@_;
open (svgfile,">>$self->{file}") or die("Couldn't open File\n");
open (rsvgfile,"<$self->{file}");
my $test = join ("",<rsvgfile>);
close rsvgfile;
my $testtext = $text;
$testtext=~ s/(\(|\)|\[|\]|\+)/\\$1/g;
my $count=( $test=~ s/smilestring="$testtext"//g );
if ( $test !~ /reaction="$testtext"/g )
{print svgfile '<text id="t'.$id.'" x="'.$x .'" y="'.$y .'" font-family="
'.$self->{def_font}.'" font-size="'.$self->{def_font_size}.'" fill=" '.
$self->{def_font_color}.'"   stroke-width="1"  > '.$text."[Listed:$count]".
' </text>'."\n";}
else
{print svgfile '<text id="t'.$id.'" x="'.$x .'" y="'.$y .'" font-family="
'.$self->{def_font}.'" font-size="'.$self->{def_font_size}.'" fill=" '.
$self->{def_font_color}.'"   stroke-width="1"  > '.$text.' </text>'."\n";
}
}	

=item $graph->write_line(id,inix,iniy,xend,yend,direction)

Function used to write a line in the SVG file. This is a path component of the
SVG.

This function should be called from the inside of the module, not being 
recomended to call it from an external applicattion.

=cut	

sub write_line
{	
my $self = shift;
my ($id,$inix,$iniy,$xend,$yend,$direction)=@_;
open (svgfile,">>$self->{file}") or die("Couldn't open File\n");
my $midx=($inix+$xend)/2;
my $midy=($iniy+$yend)/2;
if ($direction==0)

lib/Chemistry/Artificial/Graphics.pm  view on Meta::CPAN

    var splitlevel = currentId.split("c");
    var currentLevel = splitlevel;
    var level = parseInt(currentLevel[1],10);
    level = level+1;
    var groupElement = document.getElementById("g"+level);
    if (groupElement.getAttribute("display")=="none")
    { groupElement.setAttribute("display","inline"); }
    else 
    {groupElement.setAttribute("display","none"); 
    }
   }  
  }
 else
 {var SVGDoc  = evt.target.ownerDocument;
  var SVGRoot = SVGDoc.documentElement;
  var svgNS = "http://www.w3.org/2000/svg";
  var circle = evt.target;
  var currentId=circle.getAttribute("id");
  var splitlevel = currentId.split("c");
  var x = parseInt(circle.getAttribute("cx"));
  var y = parseInt(circle.getAttribute("cy"));
  var currentLevel = splitlevel;
  var level = parseInt(currentLevel[1],10);
  var group = document.createElementNS(svgNS,"g");
  if (document.getElementById("p"+level)!=null) 
  {alert("This element already exists");}
  else 
  {group.setAttribute("id","p"+level);
   SVGRoot.appendChild(group);
   var rect=document.createElementNS(svgNS,"rect");
   rect.setAttribute("x",x);
   rect.setAttribute("id","rect"+level);
   rect.setAttribute("x",x);
   rect.setAttribute("y",y);
   rect.setAttribute("rx",5);
   rect.setAttribute("ry",5);
   rect.setAttribute("width",500);
   rect.setAttribute("height",100);
   rect.setAttribute("style","fill:white;stroke:blue;stroke-width:2;fill-opacity:0.8;stroke-opacity:0.9");
   rect.setAttribute(\'onclick\',\'close(evt)\');
   group.appendChild(rect);
   //Create a text smiles
   x = x+10;
   y = y+10;
   var textsmiles=document.createElementNS(svgNS,"text");
   textsmiles.setAttribute("x",x);   textsmiles.setAttribute("y",y);
   textsmiles.setAttribute("id","s"+level);
   textsmiles.setAttribute("style","text-anchor:right;font-size:12;font-family:Arial;fill:blue");
   smilestring = circle.getAttribute("smilestring");	
   textsmiles.appendChild(document.createTextNode("SmilesString: "+smilestring));
   group.appendChild(textsmiles)
   //Create a text child
   y = y+10;
   var childtext=document.createElementNS(svgNS,"text");
   childtext.setAttribute("x",x);	childtext.setAttribute("y",y);
   childtext.setAttribute("id","ch"+level);
   childtext.setAttribute("style","text-anchor:right;font-size:12;font-family:Arial;fill:blue");
   childstring = circle.getAttribute("child");	
   childtext.appendChild(document.createTextNode("Child Number: "+childstring));
   group.appendChild(childtext);
   //Create a text formula
   y = y+10;
   var ftext=document.createElementNS(svgNS,"text");
   ftext.setAttribute("x",x);ftext.setAttribute("y",y);
   ftext.setAttribute("id","f"+level);
   ftext.setAttribute("style","text-anchor:right;font-size:12;font-family:Arial;fill:blue");
   formulastring = circle.getAttribute("formula");	
   ftext.appendChild(document.createTextNode("Formula: "+formulastring));
   group.appendChild(ftext);
   //Create a text reaction
   y = y+10;
   var rtext=document.createElementNS(svgNS,"text");
   rtext.setAttribute("x",x);rtext.setAttribute("y",y);
   rtext.setAttribute("id","r"+level);
   rtext.setAttribute("style","text-anchor:right;font-size:12;font-family:Arial;fill:blue");
   reactionstring = circle.getAttribute("reaction");
   rtypestring = circle.getAttribute("reactiontype");	
   rtext.appendChild(document.createTextNode("Reaction: "+reactionstring +"("+rtypestring+")"));	
   group.appendChild(rtext);
   //Create a text atommap
   y = y+10;
   var amtext=document.createElementNS(svgNS,"text");
   amtext.setAttribute("x",x);amtext.setAttribute("y",y);
   amtext.setAttribute("id","am"+level);
   amtext.setAttribute("style","text-anchor:right;font-size:12;font-family:Arial;fill:blue");
   amstring = circle.getAttribute("atommap");	
   amtext.appendChild(document.createTextNode("Atommap: "+amstring));
   group.appendChild(amtext);
   //Create a text elembefore
   y = y+10;
   var ebtext=document.createElementNS(svgNS,"text");
   ebtext.setAttribute("x",x);ebtext.setAttribute("y",y);
   ebtext.setAttribute("id","eb"+level);
   ebtext.setAttribute("style","text-anchor:right;font-size:12;font-family:Arial;fill:blue");
   ebstring = circle.getAttribute("elembefore");	
   ebtext.appendChild(document.createTextNode("Element Before: "+ebstring));
   group.appendChild(ebtext);
  }
 }
}
'."\n";
print svgfile '<script type="text/ecmascript"> <![CDATA[ '."\n" ;
print svgfile $function ;
print svgfile ' ]]> </script> '."\n";
print svgfile '<script type="text/ecmascript"> <![CDATA[ 
function changeState(evt)
{var rect = evt.target;
 if (rect.getAttribute("mode")=="E")
 {rect.setAttribute("mode","P");
 var text = document.getElementById(\'properties\')	
 text.setAttribute("display","inline");
 var text = document.getElementById(\'expandtext\')	
 text.setAttribute("display","none");	
 }
 else
 {rect.setAttribute("mode","E");
 var text = document.getElementById(\'properties\')	
 text.setAttribute("display","none");
 var text = document.getElementById(\'expandtext\')	
 text.setAttribute("display","inline");			
 }
}
]]> </script>'."\n";
print svgfile '<script type="text/ecmascript"> <![CDATA[ 
function close(evt)
{	
var obj = evt.target;
obj.setAttribute("display","none");

lib/Chemistry/Artificial/Graphics.pm  view on Meta::CPAN

 my $rootel = pop (@$root);
 my $child = $self->{db}->rec_child($rootel);
 my $color;
 if (scalar(@$child)!=0) {$color = $self->{def_fathercolor};}
 else {$color = $self->{def_childcolor};}
 my $info = $self->{db}->graphic_information($rootid,$rootel);
 $self->write_circle($posx,$$posy,$self->{id},$color,@$info[0],
 scalar(@$child)/2,@$info[1],@$info[5],@$info[3],@$info[4],@$info[2]);
 $self->write_text(@$info[0],$posx+$self->{radius}*1.5,$$posy,$self->{id});
 if ($posx != $self->{radius})
 {$self->write_line($self->{id},$posx-$self->{distanceh},$$posy,$posx,$$posy,
 @$info[3]);
  $self->write_text(@$info[5],$posx-$self->{distanceh},$$posy+$self->{radius},
  $self->{id});
 }
 $self->{id}= $self->{id}+1;
 if (scalar(@$child)!=0)
 {$group=$self->{id};
  $self->open_group($group);
  $posx = $posx+$self->{distanceh};
  $$posy=$$posy+(2*$self->{radius});
  $self->recursive_ch($group,$posx,$posy,$child);
  $self->close_group();
  $posx = $posx-$self->{distanceh};
 }
 else
 { $$posy=$$posy+(2*$self->{radius});
 }
 $$posy=$$posy+(2*$self->{radius});
 $self->recursive_ch($group,$posx,$posy,$root);
}
}

=back

=head3 Functions that depends of the graphic type (static)

Static graphics needs some diferent functions in the SVG file

=cut

=over 4

=item $graph->write_bottom_static()

Writes the bottom (last lines) in the SVG static file.

This function should be called from the inside of the module, not being 
recomended to call it from an external applicattion.

=cut

sub write_bottom_static
{	
my $self=shift;
open (svgfile,">>$self->{file}") or die("Couldn't open File\n");
print svgfile "</svg>\n";
close (svgfile);
}

=item $graph->write_circle_static(x, y, id, color, smilestring, child, formula,
reaction, reaction_type, atommap, elembefore)

This function writes a component in the graph.

	The properties:
	* id: This is an unique id for one component in the graph.
	* cx: X position.

This function should be called from the inside of the module, not being 
recomended to call it from an external applicattion.

=cut

sub write_circle_static
{	
my $self = shift;
my ($x,$y,$id,$color,$smilestring,$child,$formula,$reaction,$reaction_type,
$atommap,$elembefore)=@_;
open (svgfile,">>$self->{file}") or die("Couldn't open File\n");
print svgfile '<circle id="c'. $id .'" cx="'. $x. '" cy="' .$y. '" r="20" 
stroke="'.$color.'" smilestring="'. $smilestring .'" child="'. $child.'"
 formula="'. $formula.'" reaction="'. $reaction.'" reactiontype="'. 
$reaction_type.'" atommap="'. $atommap.'" elembefore="'. $elembefore.'"  
style="fill:url(#mygradient1)" stroke-with="1"/>' ."\n";
close (svgfile);
}

=item $graph->recursive_ch_static(x, y, root)

Represents a SVG static file with the solution in the solution graphic table.

How does it works:

Get all the root elements and then, get the childs for each one.

This function should be called from the inside of the module, not being 
recomended to call it from an external applicattion.

=cut

sub recursive_ch_static	
{
my $self = shift;
my ($posx,$posy,$root)=@_;
if (scalar(@$root)!=0)
{my $rootid= pop (@$root);
 my $rootel = pop (@$root);
 my $child = $self->{db}->rec_child($rootel);
 my $color;
 if (scalar(@$child)!=0) {$color = $self->{def_fathercolor};}
 else {$color = $self->{def_childcolor};}
 my $info = $self->{db}->graphic_information($rootid,$rootel);
 $self->write_circle_static($posx,$$posy,$self->{id},$color,@$info[0],
 scalar(@$child)/2,@$info[1],@$info[5],@$info[3],@$info[4],@$info[2]);
 $self->write_text(@$info[0],$posx+$self->{radius}*1.5,$$posy,$self->{id});
 if ($posx != $self->{radius})
 {$self->write_line($self->{id},$posx-$self->{distanceh},$$posy,$posx,$$posy,
 @$info[3]);
  $self->write_text(@$info[5],$posx-$self->{distanceh},$$posy+$self->{radius},
  $self->{id});
 }
 $self->{id}= $self->{id}+1;
 if (scalar(@$child)!=0)
 {
  $posx = $posx+$self->{distanceh};
  $$posy=$$posy+(2*$self->{radius});
  $self->recursive_ch_static($posx,$posy,$child);
  $posx = $posx-$self->{distanceh};
 }
 else
 { $$posy=$$posy+(2*$self->{radius});
 }
 $$posy=$$posy+(2*$self->{radius});
 $self->recursive_ch_static($posx,$posy,$root);
}
}

=back

=head3 Functions in text mode 

Text mode graphics needs diferent functions to write the file.



( run in 2.403 seconds using v1.01-cache-2.11-cpan-5735350b133 )