R/plot.utilities.R

link.to.sbgn.start = '<a xlink:href="https://cdn.rawgit.com/sbgn/process-descriptions/b2904462d11bd8d65e9c7a1318d95d468048cb50/templates/PD_L1V1.3.svg">'
link.to.sbgn.end = '</a>'

svg.header = '<?xml version="1.0" encoding="UTF-8"?>
<svg width="%f" height="%f"
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<metadata id="metadata7">image/svg+xml</metadata>
'
svg.end = '
</svg>'
###############################################
template.text = '
<text
x="%f"
y="%f"
id="%s"
style="font-size:%fpx;text-anchor:%s;font-family:Arial,Helvetica;alignment-baseline:%s;stroke.opacity:%s;dominant-baseline:%s"
fill="%s"
>
%s</text>
'


###############################################
template.path = '
<path
d="%s"
id="%s"
style="fill:%s;fill-opacity:%f;stroke-width:%f;stroke:%s;stroke-opacity:%f"
transform = "rotate(%f %f %f)"
/>
'
plot.path = function(d
                     ,id
                     ,fill.color
                     ,stroke.width
                     ,stroke.color
                     ,angle=0
                     ,rotate.x=0
                     ,rotate.y=0
                     ,fill.opacity=0.6
                     ,stroke.opacity=1
                     ,object){
        
    if("shape" %in% slotNames(object) ){ # if we are ploting a glyph(glyph has slot "shape")
        if(length(object@shape$fill.color)>0){
            fill.color = object@shape$fill.color
        }
        if(length(object@shape$fill.opacity)>0){
            fill.opacity = object@shape$fill.opacity
        }
        if(length(object@shape$stroke.width)>0){
            stroke.width  = object@shape$stroke.width
        }
        if(length(object@shape$stroke.opacity)>0){
            stroke.opacity  = object@shape$stroke.opacity
        }
        if(length(object@shape$stroke.color)>0){
            stroke.color  = object@shape$stroke.color
        }
    # }else{
    }else if("edge" %in% slotNames(object) ){ # if we are ploting an arc
        fill.color = object@edge$tip.fill.color
        fill.opacity = object@edge$tip.fill.opacity
        stroke.width  = object@edge$tip.stroke.width
        stroke.opacity  = object@edge$tip.stroke.opacity
        stroke.color  = object@edge$tip.stroke.color
    }else {
        message("Plot.path function is not implemented for this object!!! \n Please make sure the object has a slot named 'shape' or 'edge'.")
        print(object)
        stop()
    }
    svg = sprintf(template.path,d,id,fill.color,fill.opacity,stroke.width,stroke.color,stroke.opacity,angle,rotate.x,rotate.y)
    return(svg)
}

###############################################
template.rectangle = '
<rect
width="%f"
height="%f"
rx="%f"
ry="%f"
x="%f"
y="%f"
id="%s"
style="fill:%s;fill-opacity:%f;stroke:%s;stroke-width:%f;stroke-opacity:%f" />
'
#
plot.rectangle = function(x,y,h,w,id,rx=0,ry=0,fill.color="white",stroke.color="black",stroke.width=1,fill.opacity=0.6,stroke.opacity=1,glyph=new("glyph")){
    if(length(glyph@shape$fill.color)>0){
        fill.color = glyph@shape$fill.color
    }
    if(length(glyph@shape$fill.opacity)>0){
        fill.opacity = glyph@shape$fill.opacity
    }
    if(length(glyph@shape$stroke.width)>0){
        stroke.width  = glyph@shape$stroke.width
    }
    if(length(glyph@shape$stroke.opacity)>0){
        stroke.opacity  = glyph@shape$stroke.opacity
    }
    if(length(glyph@shape$stroke.color)>0){
        stroke.color  = glyph@shape$stroke.color
    }
    svg = sprintf(template.rectangle,w,h,rx,ry,x,y,id,fill.color,fill.opacity,stroke.color,stroke.width,stroke.opacity)
    return(svg)
}

###########################################################
# use path to plot a rectangle that has 1,2,3 or 4 rounded corner. Returns the content for "d" command in "path"
#the r of the rounded corners can be different(can be set using r1,r2,r3,r4: from top left corner, clockwise)
generate.d.for.partly.rounded.corner.rect = function(x,y,w,h,r1,r2,r3,r4){
    start.and.upperLeft = paste("M",x,r1+y, "Q",x,y, x+r1,y,sep=" ")
    top.and.upperRight = paste("L",x+w-r2,y, "Q",x+w,y, x+w,y+r2,sep=" ")
    right.and.lowerRight = paste("L",x+w,y+h-r3, "Q",x+w,y+h, x+w-r3,y+h,sep=" ")
    bottom.and.lowerLeft = paste("L",x+r4,y+h, "Q",x,y+h, x,y+h-r4, "Z",sep=" ")
    d.content = paste(start.and.upperLeft,top.and.upperRight,right.and.lowerRight,bottom.and.lowerLeft,sep=" ")
    return(d.content)
}
###############################################

template.polygon = '
<polygon
points = "%s"
id="line"
style="fill:%s; stroke:%s; stroke-opacity:%s; stroke-width:%f"
transform = "rotate(%f %f %f)"
/>
'
plot.polygon = function(object,points,fill.color,rotate.a,rotate.x,rotate.y){
    if(fill.color == "black"){
        fill.color = object@edge$tip.fill.color  # if the edge has a filled tip(e.g. production), we can change it to user defined color. If the edge type has an empty tip, we can't change it.
    }
    sprintf(template.polygon,points
            ,fill.color
            ,object@edge$tip.stroke.color
            ,object@edge$tip.stroke.opacity
            ,object@edge$tip.stroke.width
            ,rotate.a,rotate.x,rotate.y)
}


###############################################
template.ellipse = '
<ellipse
rx="%f"
ry="%f"
cx="%f"
cy="%f"
id="%s"
style="fill:%s;fill-opacity:%f;stroke:%s;stroke-width:%f;stroke-opacity:%f" />
'
plot.ellipse = function(x,y,h,w,id,rx=0,ry=0,fill.color="white",fill.opacity=1,stroke.color="black",stroke.width=1,stroke.opacity=1,glyph=new("glyph")){
    if(length(glyph@shape$fill.color)>0){
        fill.color = glyph@shape$fill.color
    }
    if(length(glyph@shape$fill.opacity)>0){
        fill.opacity = glyph@shape$fill.opacity
    }
    if(length(glyph@shape$stroke.width)>0){
        stroke.width  = glyph@shape$stroke.width
    }
    if(length(glyph@shape$stroke.opacity)>0){
        stroke.opacity  = glyph@shape$stroke.opacity
    }
    if(length(glyph@shape$stroke.color)>0){
        stroke.color  = glyph@shape$stroke.color
    }
    svg = sprintf(template.ellipse,w/2,h/2,x,y,id,fill.color,fill.opacity,stroke.color,stroke.width,stroke.opacity)
    return(svg)
}

plot.ellipse.edge.tip = function(x,y,h,w,id,rx=0,ry=0,fill.color="white",fill.opacity=1,stroke.color="black",stroke.width=1,stroke.opacity=1,object){
    if(fill.color == "black"){
        fill.color = object@edge$tip.fill.color  # if the edge has a filled tip(e.g. production), we can change it to user defined color. If the edge type has empty tip fill color, we can't change it.
    }
    svg = sprintf(template.ellipse,w/2,h/2,x,y,id
                  ,fill.color
                  ,object@edge$tip.fill.opacity
                  ,object@edge$tip.stroke.color
                  ,object@edge$tip.stroke.width
                  ,object@edge$tip.stroke.opacity
                  )
    return(svg)
}

###############################################
template.line = '
<line
%s
id="%s"
style="stroke:%s;stroke-width:%f;stroke-opacity:%f" />
'

 plot.line = function(LineCoordinates,id,stroke.color="black",stroke.opacity=1,stroke.width=1,object=NULL){
     if(! is.null(object)){
         stroke.color = object@edge$line.stroke.color
         stroke.width = object@edge$line.width
     }
    # stroke.width = 2*stroke.width
    svg = template.line
    svg = sprintf(template.line,LineCoordinates,id,stroke.color,stroke.width,stroke.opacity)
    return(svg)
}

plot.LineWings = function(x,y,w,h,orientation,id){
    leftLineCoordinates = paste("x1=",x-w," y1=",y," x2=",x-w/2," y2=",y,"",sep='"')
    rightLineCoordinates = paste("x1=",x+w/2," y1=",y," x2=",x+w," y2=",y,"",sep='"')
    if (orientation == "vertical"){
        leftLineCoordinates = paste("x1=",x," y1=",y-h," x2=",x," y2=",y-h/2,"",sep='"')
        rightLineCoordinates = paste("x1=",x," y1=",y+h/2," x2=",x," y2=",y+h,"",sep='"')
    }
    svg.line.l = plot.line(leftLineCoordinates,id)
    svg.line.r = plot.line(rightLineCoordinates,id)
    svg = paste(svg.line.l,svg.line.r,sep="\n")
    return(svg)
}

##########################################################
#' An object to store glyph information
#' @slot compartment 
#' 
#' A character string. The compartment this glyph belongs to.
#' 
#' @slot x,y,h,w
#' 
#' Numeric. The x,y location and hight, width of the glyph
#' 
#' @slot id
#' 
#' A character string. The ID of the glyph (determined by the "id" attribute in element "glyph")
#' 
#' @slot label
#' 
#' A character string. label of the glyph. Extracted from the element "label"
#' 
#' @slot glyph.class 
#' 
#' A character string. Class of the glyph
#' 
#' @slot user.data 
#' 
#' A numeric vector. The omics data mapped to this glyph.
#' 
#' @slot stroke.width,stroke.opacity,fill.opacity 
#' 
#' Numeric. Controls glyph border width or opacity of node fill and border.
#' 
#' @slot fill.color,stroke.color 
#' 
#' A character string. The fill color and stroke color of glyph.
#' 
#' @slot label_location 
#' 
#' A character string. One of "center" or "top". If set to "center", the glyph label text will be displayed at the center of the glyph. If set to "top", the label will be displayed at the top of the glyph. 
#' 
#' @slot orientation 
#' 
#' A character string. One of "left","right","up","down". This is specific to glyphs of classes "terminal" and "tag". It will change the orientation of the node. 
#' 
#' @slot global.parameters.list 
#' 
#' A list. This is a copy of parameters in '...' of function \code{\link{SBGNview}}. 
#'              
#' @slot shape 
#' 
#' A list. Parameters controlling how the node is rendered. Available elements can be accessed as follow:
#' 
#' 
#'              glyph@@shape$stroke.color\cr
#'                      -Character (e.g. "red"). The color of glyph border. \cr
#'              
#'              glyph@@shape$stroke.opacity\cr
#'                      -Numeric (e.g. 0.8). The opacity of glyph border. Must be between 0 and 1.\cr
#'              
#'              glyph@@shape$stroke.width\cr
#'                      -Numeric. The width of glyph border\cr
#'              
#'              glyph@@shape$fill.opacity\cr
#'                      -Numeric. The opacity of glyph fill. Must be between 0 and 1.\cr
#'              
#'              glyph@@shape$fill.color\cr
#'                      -Numeric. The glyph fill color. Note that this will overwrite colors generated from omics data!\cr
#'              
#' @slot text
#' 
#' A list. Parameters controlling how node label is rendered. Available elements can be accessed as follow:
#' 
#'              glyph@@text$y.shift\cr
#'                      -Numeric. Move glyph label vertically by this value.\cr
#'              
#'              glyph@@text$x.shift\cr
#'                      -Numeric. Move glyph label horizontally by this value.\cr
#'              
#'              glyph@@text$color\cr
#'                      -A character string. The color of glyph label.\cr
#'              
#'              glyph@@text$font.size\cr
#'                      -A character string. The font size of glyph label.\cr
#'                      
#' @details User can modify glyph objects to change the way how it is rendered. 
#' 
#' Some of the slots/parameters in a glyph object control similar graph features (e.g. text font, line width/color etc). The priority is determined in the following sequence: 
#' 
#' 
#' 1. glyph@@text, glyph@@shape.
#' 
#' 2. Fill color derived from omics data 
#' 
#' 3. Parameters in slot "glyph@@global.parameters.list"
#' 
#' 4. Slots in glyph object: stroke.opacity, fill.color etc.
#' 
#' For example, if both of the following parameters are set: 
#' 
#' 1). glyph@@text$font.size = 5
#' 
#' 2). lobal.parameters.list$font.size = 10
#'
#' Then the font size is set by "glyph@@text$font.size = 5".
#'              



setClass(
    "glyph"
    ,representation  (compartment = "character", x="numeric",y="numeric",h="numeric",w="numeric",id = "character",label="character",label.margin = "numeric"  ,label_location="character",svg.port = "character" ,orientation="character",user.data = "vector",clone = "list", fill.color = "character", stroke.width = "numeric",stroke.color="character",stroke.opacity="numeric",fill.opacity="numeric",global.parameters.list="list",glyph.class="character",text="list",shape="list")
)
setClass(
    "port"
    ,contains="glyph"
    # ,representation  (x="numeric",y="numeric",id = "character")
)


##########################################################
#' An object to store arc information.
#' @slot target,source,id,arc.class 
#' A character string. Information extracted from element "arc"
#' @slot start.x,start.y,end.x,end.y 
#' Numeric. Information extracted from elements "start", "end" or "next"
#' @slot stroke.opacity 
#' Numeric. Controls the line of an arc (not tip of arc).
#' @slot global.parameters.list 
#' A list. This is a copy of parameters in '...' of SBGNview. It can affect glyph behavior if the element has a corresponding feature of the arc. For example "edge.tip.size" affects the arc but "compartment.opacity" doesn't. See details for more information. This will be improved in future versions to remove unrelated parameters.
#'              
#' @slot edge 
#' 
#' A list. An arc in SBGN map normally consists of a line and a tip shape at the end of the line. This list holds variables that controls arc properties. Available elements can be accessed as follow:
#'  
#'           The following three paremeters control the line.\cr
#'              arc@@edge$line.stroke.color\cr
#'              arc@@edge$line.stroke.opacity\cr
#'              arc@@edge$line.width\cr
#'                      
#'                      
#'           The following five paremeters control the tip.\cr
#'              arc@@edge$tip.stroke.opacity\cr
#'              arc@@edge$tip.stroke.color\cr
#'              arc@@edge$tip.stroke.width\cr
#'              arc@@edge$tip.fill.color\cr
#'              arc@@edge$tip.fill.opacity\cr
#'              
#' @details Arc information comes from two sources:1. SBGN-ML file's "arc" element ("source", "target", coordinates etc.). 2. Parameters specified when running \code{\link{SBGNview}}.  User can modify arc objects to change the way how it is rendered. Some of the slots/parameters in arc object controls similar graph features such as text font, line width/color etc. 
#' 
#' The priority is determined in the following sequence: 
#' 
#' 1. arc@@edge
#' 
#' 2. Parameters in slot "arc@@global.parameters.list" 
#' 
#' 3. Slots in arc object: stroke.opacity, fill.color etc.  
#' 
#' 

setClass(
    "arc"
    ,representation  (target="character",source="character",id="character",arc.class="character",start.y="numeric",start.x="numeric",end.y="numeric",end.x="numeric",stroke.opacity = "numeric",global.parameters.list="list",edge = "list")
)
setClass(
    "spline"
    ,representation  (id="character",spline.coords = "vector",edge="list",global.parameters.list="list")
)

##########################################################
#' An object to store information for spline formated arcs.
#' @slot target,source,id,arc.class 
#' A character string. Information extracted from element "arc.spline"
#' @slot start.x,start.y,end.x,end.y 
#' Numeric. Information extracted from elements "start", "end" or "next"
#' @slot stroke.opacity 
#' Numeric. Controls the line of an arc (not tip of arc).
#' @slot components A list of "arc" and "spline" objects. A spline arc is represented by several components: 1. The two ends of the arc are represented by straight line "arc" objects. 2. splines connecting the ends are represented by "spline" objects.
#' @slot global.parameters.list 
#' A list. This is a copy of parameters in '...' of SBGNview. It can affect glyph behavior if the element has a corresponding feature of the arc. For example "edge.tip.size" affects the arc but "compartment.opacity" doesn't. See details for more information. This will be improved in future versions to remove unrelated parameters.
#'              
#' @slot edge 
#' 
#' A list. An arc in SBGN map normally consists of a line and a tip shape at the end of the line. This list holds variables that controls arc properties. Available elements can be accessed as follow:
#'  
#'           The following three paremeters control the line.\cr
#'              arc@@edge$line.stroke.color\cr
#'              arc@@edge$line.stroke.opacity\cr
#'              arc@@edge$line.width\cr
#'                      
#'                      
#'           The following five paremeters control the tip.\cr
#'              arc@@edge$tip.stroke.opacity\cr
#'              arc@@edge$tip.stroke.color\cr
#'              arc@@edge$tip.stroke.width\cr
#'              arc@@edge$tip.fill.color\cr
#'              arc@@edge$tip.fill.opacity\cr
#'              
#' @details Arc information comes from two sources:1. SBGN-ML file's "arc" element ("source", "target", coordinates etc.). 2. Parameters specified when running \code{\link{SBGNview}}.  User can modify arc objects to change the way how it is rendered. Some of the slots/parameters in arc object controls similar graph features such as text font, line width/color etc. 
#' 
#' The priority is determined in the following sequence: 
#' 
#' 1. arc@@edge
#' 
#' 2. Parameters in slot "arc@@global.parameters.list" 
#' 
#' 3. Slots in arc object: stroke.opacity, fill.color etc.  
#' 
#' 
setClass(
    "spline.arc"
    ,representation  (id="character", source = "character",target="character",arc.class="character",edge="list",components="list",global.parameters.list="list")
)

setGeneric(
    "plot.glyph"
    , function(object){
        standardGeneric("plot.glyph")
    }
)
setGeneric(
    "plot.arc"
    , function(object){
        standardGeneric("plot.arc")
    }
)

###############################################
setClass("macromolecule.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("macromolecule.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        fill.color = "white"
        if(length(object@fill.color)>0){
            fill.color = object@fill.color
        }
        # label = object@label
        label.location = "center"
        rx = min(h,w)/10
        ry = min(h,w)/10
        stroke.width=1
        if(length(object@shape$stroke.width)>0){
            stroke.width = object@shape$stroke.width
        }
        stroke.color=1
        if(length(object@stroke.color)>0){
            stroke.color = object@stroke.color
        }
        stroke.opacity=1
        if(length(object@stroke.opacity)>0){
            stroke.opacity = object@stroke.opacity
        }
        fill.opacity=1
        if(length(object@fill.opacity)>0){
            fill.opacity = object@fill.opacity
        }
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        # svg = paste(svg.rect,sep="\n")
        svg=""
        
        
        if(is.na(user.data[1])){
            
        }
        # if(user.data[1] != "no.user.data"){
        if(!identical(user.data[1],"no.user.data")){
            for(i in seq_len(length.out =  length(user.data))){
                fill.color = color.from.01.value(user.data[i],global.parameters.list=global.parameters.list,gene.or.cpd="gene")
                glyph.data.i = object
                glyph.data.i@fill.color = fill.color
                glyph.data.i@fill.opacity = 1
                glyph.data.i@user.data = c("no.user.data")
                glyph.data.i@w = w/length(user.data)
                glyph.data.i@x = x -w/2  + (i-1/2) * glyph.data.i@w
                glyph.data.i@label = " "
                glyph.data.i@shape$stroke.width = 0.1
                glyph.data.i@stroke.opacity = 0.5
                glyph.data.i@stroke.color = "black"
                glyph.data.i@shape$stroke.opacity = 0.5 # if we are plotting data shape, don't plot the border
                glyph.data.i@shape$stroke.width = 0.1 # if we are plotting data shape, don't plot the border
                svg = paste(svg,plot.glyph(glyph.data.i),sep="\n")
            }
            fill.opacity = 0
            stroke.opacity = 1
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,rx=rx,ry=ry,stroke.width = stroke.width,fill.color = fill.color,stroke.opacity = stroke.opacity,fill.opacity = fill.opacity)
        svg = paste(svg,svg.rect,svg.text,sep="\n")
        return(svg)
    }
)


###############################################
setClass("entity.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("entity.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        fill.color = "white"
        if(length(object@fill.color)>0){
            fill.color = object@fill.color
        }
        # label = object@label
        label.location = "center"
        stroke.width=1
        stroke.opacity=1
        if(length(object@shape$stroke.width)>0){
            stroke.width = object@shape$stroke.width
        }
        if(length(object@stroke.opacity)>0){
            stroke.opacity = object@stroke.opacity
        }
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        rx = min(h,w)/10
        ry = min(h,w)/10
        # svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,rx=rx,ry=ry,stroke.width = stroke.width,stroke.opacity = stroke.opacity)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        # svg = paste(svg.rect,sep="\n")
        svg=""
        
        
        # if(user.data[1] != "no.user.data"){
        if(!identical(user.data[1],"no.user.data")){
            for(i in seq_len(length.out = length(user.data))){
                fill.color = color.from.01.value(user.data[i],global.parameters.list=global.parameters.list,gene.or.cpd="gene")
                glyph.data.i = object
                glyph.data.i@fill.color = fill.color
                glyph.data.i@user.data = c("no.user.data")
                glyph.data.i@w = w/length(user.data)
                glyph.data.i@x = x -w/2  + (i-1/2) * glyph.data.i@w
                glyph.data.i@label = " "
                glyph.data.i@shape$stroke.width = 0.5
                glyph.data.i@stroke.opacity = 0
                svg = paste(svg,plot.glyph(glyph.data.i),sep="\n")
            }
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,rx=rx,ry=ry,stroke.width = stroke.width,stroke.opacity = stroke.opacity)
        svg = paste(svg,svg.rect,svg.text,sep="\n")
        
        return(svg)
    }
)

############################################
setClass("compartment.sbgn",contains="glyph",representation(max.x="numeric"))
setMethod(
    "plot.glyph"
    ,signature("compartment.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location = "top"
        # ry = rx
        max.x = object@max.x
        rx = ry = 20
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,id=id,h=h,w=w,rx=rx,ry=ry,stroke.width = object@shape$stroke.width,fill.opacity = global.parameters.list$compartment.opacity)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location,max.x=max.x)
        svg = paste(svg.rect,svg.text,sep="\n")
        # svg = ""
        return(svg)
    }
)
############################################
setClass("complex.sbgn",contains="glyph",representation(if.complex.empty="logical"))
setMethod(
    "plot.glyph"
    ,signature("complex.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x-w/2
        y = object@y -h/2
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        if ( length(nchar(object@label_location))==0 ){
            label.location = "top"
        }else if( object@label_location != "center" ){
            label.location = "top"
        }else{
            label.location = object@label_location
        }
        if.complex.empty= FALSE
        if(length(object@if.complex.empty) !=0){
            if.complex.empty = object@if.complex.empty
        }
        if(if.complex.empty){
            label.location = "center"
        }
        rx = ry = 8
        corner.r = rx
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        d1 = (paste("M",x,y+corner.r, x,y+h-corner.r, x+corner.r,y+h,  x+w-corner.r,y+h,  x+w,y+h-corner.r,  x+w,y+corner.r, x+w-corner.r,y, x+corner.r,y ,"Z",sep=" "))
        svg.path1 = plot.path(object=object,d=d1,id=id,fill.color="white",stroke.width=stroke.width,stroke.color = "black")
        
        # label="complex" # try not to show complex name
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x+w/2,y=y+h/2,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.path1,svg.text,sep="\n")
        return(svg)
    }
)

############################################
setClass("complex_multimer.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("complex_multimer.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x-w/2
        y = object@y -h/2
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location = "center"
        rx = min(h,w)/10
        ry = min(h,w)/10
        corner.r = global.parameters.list$edge.tip.size*3
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        d1 = (paste("M",x,y+corner.r, x,y+h-corner.r, x+corner.r,y+h,  x+w-corner.r,y+h,  x+w,y+h-corner.r,  x+w,y+corner.r, x+w-corner.r,y, x+corner.r,y ,"Z",sep=" "))
        svg.path1 = plot.path(object=object,d=d1,id=id,fill.color="white",stroke.width=stroke.width,stroke.color = "black",fill.opacity = 1)
        
        x = x+global.parameters.list$edge.tip.size*3/2; y = y+global.parameters.list$edge.tip.size*3/2
        d2 = (paste("M",x,y+corner.r, x,y+h-corner.r, x+corner.r,y+h,  x+w-corner.r,y+h,  x+w,y+h-corner.r,  x+w,y+corner.r, x+w-corner.r,y, x+corner.r,y ,"Z",sep=" "))
        svg.path2 = plot.path(object=object,d=d2,id=id,fill.color="white",stroke.width=stroke.width,stroke.color = "black")
        
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x+w/2,y=y+h/2,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.path2,svg.path1,svg.text,sep="\n")
        return(svg)
    }
)
##########################################################
setClass("state_variable.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("state_variable.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        object@label = gsub(" ","",object@label)
        label.location = "center"
        rx = min(h,w)/10
        ry = min(h,w)/10
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width,fill.opacity = global.parameters.list$auxiliary.opacity)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.ellipse,svg.text,sep="\n")
        return(svg)
    }
)

##########################################################
setClass("unspecified_entity.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("unspecified_entity.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        fill.color = "white"
        if(length(object@fill.color)>0){
            fill.color = object@fill.color
        }
        fill.opacity = 1
        # if(length(object@fill.opacity)>0){
        #     fill.opacity = object@fill.opacity
        # }
        label.location = "center"
        rx = min(h,w)/10
        ry = min(h,w)/10
        stroke.width=1
        if(length(object@shape$stroke.width)>0){
            stroke.width = object@shape$stroke.width
        }
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        # svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        # svg = paste(svg.ellipse,sep="\n")
        svg=""
        
        # if(user.data[1] != "no.user.data"){
        if(!identical(user.data[1],"no.user.data")){
            fill.color = color.from.01.value(user.data[1],global.parameters.list=global.parameters.list,gene.or.cpd="gene")
            svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width,fill.color = fill.color,stroke.opacity = 0)
            svg = paste(svg,svg.ellipse,sep="\n")
            if(length(user.data)>1){
                for(i in 2: length(user.data)){
                    fill.color = color.from.01.value(user.data[i],global.parameters.list=global.parameters.list,gene.or.cpd="gene")
                    glyph.data.i = object
                    glyph.data.i@fill.color = fill.color
                    glyph.data.i@user.data = c("no.user.data")
                    glyph.data.i@x = x -w/2  + (i-1) * w/length(user.data)
                    glyph.data.i@label = " "
                    glyph.data.i@shape$stroke.width = 0.5
                    start.x=x -w/2  + (i-1) * w/length(user.data)
                    start.y.1 = y+(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    start.y.2 = y-(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    if(start.x>x){
                        large.flag = 0
                    }else{
                        large.flag = 1
                    }
                    d.1 = (paste("M",start.x,start.y.1,"A",w/2,h/2 ,1, large.flag,0 ,start.x,start.y.2,sep=" "))
                    svg.path.1 = plot.path(object=object,d=d.1,id=id,fill.color=fill.color,stroke.width= 1,stroke.color = "black",stroke.opacity = 0)
                    
                    start.x=x -w/2  + (i) * w/length(user.data)
                    start.y.1 = y+(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    start.y.2 = y-(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    if(start.x>x){
                        large.flag = 0
                    }else{
                        large.flag = 1
                    }
                    d.2 = (paste("M",start.x,start.y.1,"A",w/2,h/2 ,1, large.flag,0,start.x,start.y.2,sep=" "))
                    svg.path.2 = plot.path(object=object,d=d.2,id=id,fill.color="white",stroke.width= 1,stroke.color = "black",stroke.opacity = 0)
                    svg = paste(svg,svg.path.1,svg.path.2,sep="\n")
                }
            }
            fill.opacity = 0
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width,fill.opacity = fill.opacity)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg,svg.ellipse,svg.text,sep="\n")
        return(svg)
    }
)

##########################################################
setClass("unit_of_information.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("unit_of_information.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        object@label = gsub(" ","",object@label)
        label.location = "center"
        rx = min(h,w)/10
        ry = min(h,w)/10
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,stroke.width = stroke.width,fill.opacity = global.parameters.list$auxiliary.opacity)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.rect,svg.text,sep="\n")
        return(svg)
    }
)

##########################################################
setClass("stoichiometry.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("stoichiometry.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        label.location = "center"
        rx = min(h,w)/10
        ry = min(h,w)/10
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,stroke.width = stroke.width)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.rect,svg.text,sep="\n")
        return(svg)
    }
)




##########################################################
setClass("cardinality.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("cardinality.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        label.location = "center"
        rx = min(h,w)/10
        ry = min(h,w)/10
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,stroke.width = stroke.width)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.rect,svg.text,sep="\n")
        return(svg)
    }
)



##########################################################
setClass("biological_activity.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("biological_activity.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        label.location = "center"
        rx = min(h,w)/10
        ry = min(h,w)/10
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,stroke.width = stroke.width)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.rect,svg.text,sep="\n")
        return(svg)
    }
)

############################################
setClass("submap.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("submap.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        label.location = "top"
        rx = 0
        ry = 0
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,stroke.width = stroke.width)
        svg = svg.rect
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        # svg = paste(svg.rect,svg.wings,sep="\n")
        svg = paste(svg.rect,svg.wings,svg.text,sep="\n")
        return(svg)
    }
)

############################################
setClass("process.sbgn",contains="glyph",representation(if.show.label="logical"))
setMethod(
    "plot.glyph"
    ,signature("process.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        if(!object@if.show.label){
            object@label = ""
        }else{
        }
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        label.location = "center"
        rx = 0
        ry = 0
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,stroke.width = stroke.width)
        svg = svg.rect
        svg.wings = ""
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.rect,svg.wings,svg.text,sep="\n")
        return(svg)
    }
)
############################################
setClass("uncertain_process.sbgn",contains="glyph",representation(if.show.label="logical"))
setMethod(
    "plot.glyph"
    ,signature("uncertain_process.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        if(!object@if.show.label){
            object@label = "?"
        }else{
        }
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        label.location = "center"
        rx = 0
        ry = 0
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,stroke.width = stroke.width)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.rect,svg.wings,svg.text,sep="\n")
        return(svg)
    }
)
##########################################################
setClass("and.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("and.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        object@label = "AND"
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        label.location = "center"
        rx = 0
        ry = 0
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.ellipse,svg.wings,svg.text,sep="\n")
        return(svg)
    }
)

##########################################################
setClass("or.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("or.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        object@label = "OR"
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        label.location = "center"
        rx = 0
        ry = 0
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.ellipse,svg.wings,svg.text,sep="\n")
        return(svg)
    }
)
##########################################################
setClass("not.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("not.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        object@label = "NOT"
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        label.location = "center"
        rx = 0
        ry = 0
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.ellipse,svg.wings,svg.text,sep="\n")
        return(svg)
    }
)

##########################################################
setClass("tau.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("tau.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        object@label = "t"
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        label.location = "center"
        rx = 0
        ry = 0
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.ellipse,svg.wings,svg.text,sep="\n")
        return(svg)
    }
)

############################################

setClass("macromolecule_multimer.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("macromolecule_multimer.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        fill.color = "white"
        if(length(object@fill.color)>0){
            fill.color = object@fill.color
        }
        fill.opacity=1
        if(length(object@fill.opacity)>0){
            fill.opacity = object@fill.opacity
        }
        object@label = object@label
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        stroke.opacity=1
        if(length(object@stroke.opacity)>0){
            stroke.opacity = object@stroke.opacity
        }
        label.location = "center"
        rx = min(h,w)/10
        ry = min(h,w)/10
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        # svg.rect.up = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,id=id,h=h,w=w,rx=rx,ry=ry,stroke.width = stroke.width,fill.opacity = 1)
        svg.rect.down = plot.rectangle(glyph=object,x=x-w/2+global.parameters.list$multimer.margin,y=y-h/2+global.parameters.list$multimer.margin,id=id,h=h,w=w,rx=rx,ry=ry,stroke.width = stroke.width)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        # svg = paste(svg.rect.down,svg.rect.up,sep="\n")
        svg = paste(svg.rect.down,sep="\n")
        # svg=""
        
        # if(user.data[1] != "no.user.data"){
        if(!identical(user.data[1],"no.user.data")){
            for(i in seq_len(length.out = length(user.data))){
                fill.color = color.from.01.value(user.data[i],global.parameters.list=global.parameters.list,gene.or.cpd="gene")
                glyph.data.i = new("macromolecule.sbgn")
                glyph.data.i@fill.color = fill.color
                glyph.data.i@user.data = c("no.user.data")
                glyph.data.i@compartment = object@compartment
                glyph.data.i@y=y
                glyph.data.i@h=h
                glyph.data.i@w = w/length(user.data)
                glyph.data.i@x = x -w/2  + (i-1/2) * glyph.data.i@w
                glyph.data.i@label = " "
                glyph.data.i@id=paste(id,"user.data",i,sep="_")
                glyph.data.i@shape$stroke.width = 0.5
                glyph.data.i@stroke.opacity = 0
                glyph.data.i@fill.opacity = 1
                svg = paste(svg,plot.glyph(glyph.data.i),sep="\n")
            }
            fill.opacity=0
        }
        svg.rect.up = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,id=id,h=h,w=w,rx=rx,ry=ry,stroke.width = stroke.width,fill.opacity = fill.opacity)
        svg = paste(svg,svg.rect.up,svg.text,sep="\n")
        
        return(svg)
    }
)

##########################################################
setClass("outcome.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("outcome.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        if (length(object@orientation)>0){
            orientation = object@orientation
            print (orientation)
        }else{
            orientation = "horizontal"
        }
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,fill.color="black",stroke.width = stroke.width)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg = svg.ellipse
        return(svg)
    }
)
###########################################################
setClass("simple_chemical_multimer.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("simple_chemical_multimer.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        w=h
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        label = object@label
        label.location = "center"
        fill.color = "white"
        if(length(object@fill.color)>0){
            fill.color = object@fill.color
        }
        fill.opacity = 1
        # if(length(object@fill.opacity)>0){
        #     fill.opacity = object@fill.opacity
        # }
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        # svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width,fill.opacity = 1)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg.ellipse2 = plot.ellipse(glyph=object,x+5,y+5,h,w,id)
        svg = paste(svg.ellipse2,sep="\n")
        
        if(!identical(user.data[1],"no.user.data")){
        # if(user.data[1] != "no.user.data"){
            fill.color = color.from.01.value(user.data[1],global.parameters.list=global.parameters.list,gene.or.cpd="compond")
            svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width,fill.color = fill.color,fill.opacity = 1)
            svg = paste(svg,svg.ellipse,sep="\n")
            if(length(user.data)>1){
                for(i in 2: length(user.data)){
                    fill.color = color.from.01.value(user.data[i],global.parameters.list=global.parameters.list,gene.or.cpd="compond")
                    glyph.data.i = object
                    glyph.data.i@fill.color = fill.color
                    glyph.data.i@user.data = c("no.user.data")
                    glyph.data.i@fill.opacity=1
                    # glyph.data.i@w = w/length(user.data)
                    glyph.data.i@x = x -w/2  + (i-1) * w/length(user.data)
                    glyph.data.i@label = " "
                    glyph.data.i@shape$stroke.width = 0.5
                    start.x=x -w/2  + (i-1) * w/length(user.data)
                    start.y.1 = y+(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    start.y.2 = y-(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    if(start.x>x){
                        large.flag = 0
                    }else{
                        large.flag = 1
                    }
                    d.1 = (paste("M",start.x,start.y.1,"A",w/2,h/2 ,1, large.flag,0 ,start.x,start.y.2,sep=" "))
                    svg.path.1 = plot.path(object=object,d=d.1,id=id,fill.color=fill.color,stroke.width= 1,stroke.color = "black",fill.opacity = 1,stroke.opacity = 0)
                    
                    start.x=x -w/2  + (i) * w/length(user.data)
                    start.y.1 = y+(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    start.y.2 = y-(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    if(start.x>x){
                        large.flag = 0
                    }else{
                        large.flag = 1
                    }
                    d.2 = (paste("M",start.x,start.y.1,"A",w/2,h/2 ,1, large.flag,0,start.x,start.y.2,sep=" "))
                    svg.path.2 = plot.path(object=object,d=d.2,id=id,fill.color="white",stroke.width= 1,stroke.color = "black",stroke.opacity = 0)
                    svg = paste(svg,svg.path.1,svg.path.2,sep="\n")
                }
                
            }
            fill.opacity=0
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width,fill.opacity = fill.opacity)
        svg = paste(svg,svg.ellipse,svg.text,sep="\n")
        
        return(svg)
    }
)

############################################
setClass("omitted_process.sbgn",contains="glyph",representation(if.show.label="logical"))
setMethod(
    "plot.glyph"
    ,signature("omitted_process.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        if(!object@if.show.label){
            object@label = '\\\\'
        }else{
            object@label = object@label
        }
        
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        label.location = "center"
        rx = 0
        ry = 0
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.rect = plot.rectangle(glyph=object,x=x-w/2,y=y-h/2,h=h,w=w,id=id,stroke.width = stroke.width)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.rect,svg.wings,svg.text,sep="\n")
        return(svg)
    }
)



###########################################################
setClass("simple_chemical.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("simple_chemical.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        w=h
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        fill.color = "white"
        if(length(object@fill.color)>0){
            fill.color = object@fill.color
        }
        # label = object@label
        label.location = "center"
        stroke.color=1
        if(length(object@stroke.color)>0){
            stroke.color = object@stroke.color
        }
        stroke.width=1
        if(length(object@shape$stroke.width)>0){
            stroke.width = object@shape$stroke.width
        }
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        # svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width,fill.color = fill.color)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        # svg = paste(svg.ellipse,sep="\n")
        svg=""
        
        
        
        # if(user.data[1] != "no.user.data"){
        if(!identical(user.data[1],"no.user.data")){
            fill.color = color.from.01.value(user.data[1],global.parameters.list=global.parameters.list,gene.or.cpd="compond")
            svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width,fill.color = fill.color,stroke.opacity=0.5)
            svg = paste(svg,svg.ellipse,sep="\n")
            if(length(user.data)>1){
                svg.sep.data.line = ""
                for(i in 2: length(user.data)){
                    fill.color = color.from.01.value(user.data[i],global.parameters.list=global.parameters.list,gene.or.cpd="compond")
                    glyph.data.i = object
                    glyph.data.i@fill.color = fill.color
                    glyph.data.i@user.data = c("no.user.data")
                    # glyph.data.i@w = w/length(user.data)
                    glyph.data.i@x = x -w/2  + (i-1) * w/length(user.data)
                    glyph.data.i@label = " "
                    glyph.data.i@shape$stroke.width = 0.5
                    start.x=x -w/2  + (i-1) * w/length(user.data)
                    start.y.1 = y+(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    start.y.2 = y-(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    
                    Coordinates = paste("x1=",start.x," y1=",start.y.1," x2=",start.x," y2=",start.y.2,"",sep='"')
                    svg.sep.data.line = paste(svg.sep.data.line
                                              ,plot.line(LineCoordinates = Coordinates,id = id,stroke.width = 0.1,stroke.opacity = 0.5),sep="\n")
                    
                    if(start.x>x){
                        large.flag = 0
                    }else{
                        large.flag = 1
                    }
                    d.1 = (paste("M",start.x,start.y.1,"A",w/2,h/2 ,1, large.flag,0 ,start.x,start.y.2,sep=" "))
                    object.data = object # if we are ploting shape for data, don't plot border
                    object.data@shape$stroke.opacity = 0
                    svg.path.1 = plot.path(object=object.data,d=d.1,id=id,fill.color=fill.color,stroke.width= 0.1,stroke.color = "black",stroke.opacity = 0)
                    
                    start.x=x -w/2  + (i) * w/length(user.data)
                    start.y.1 = y+(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    start.y.2 = y-(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
                    if(start.x>x){
                        large.flag = 0
                    }else{
                        large.flag = 1
                    }
                    d.2 = (paste("M",start.x,start.y.1,"A",w/2,h/2 ,1, large.flag,0,start.x,start.y.2,sep=" "))
                    svg.path.2 = plot.path(object=object.data,d=d.2,id=id,fill.color="white",stroke.width= 0.1,stroke.color = "black",stroke.opacity = 0)
                    svg = paste(svg,svg.path.1,svg.path.2,sep="\n")
                }
                svg = paste(svg,svg.sep.data.line,sep="\n")
            }
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width,fill.opacity = 0)
        svg = paste(svg,svg.ellipse,svg.text,sep="\n")
        return(svg)
    }
)

###########################################################
setClass("dissociation.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("dissociation.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse.o = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        svg.ellipse.i = plot.ellipse(glyph=object,x,y,h/2,w/2,id)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg = paste(svg.ellipse.o,svg.ellipse.i,svg.wings,sep="\n")
        return(svg)
    }
)

######################################################

setClass("nucleic_acid_feature_multimer.sbgn",contains="glyph",representation(r4="numeric",r3="numeric"))
setMethod(
    "plot.glyph"
    ,signature("nucleic_acid_feature_multimer.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location="center"
        fill.color = "white"
        if(length(object@fill.color)>0){
            fill.color = object@fill.color
        }
        fill.opacity = 1
        if(length(object@fill.opacity)>0){
            fill.opacity = object@fill.opacity
        }
        r1 = 0;r2=0;r3=max(h,w)/10;r4=max(h,w)/10
        if(length(object@r4)>0){
            r4 = object@r4
        }
        if(length(object@r3)>0){
            r3 = object@r3
        }
        
        stroke.width=1
        if(length(object@shape$stroke.width)>0){
            stroke.width = object@shape$stroke.width
        }
        stroke.opacity=1
        if(length(object@stroke.opacity)>0){
            stroke.opacity = object@stroke.opacity
        }
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        # svg.path = plot.path(object=object,d=d,id=id,fill.color="white",stroke.width=stroke.width,stroke.color = "black",fill.opacity = 1)
        
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        
        d2 = generate.d.for.partly.rounded.corner.rect(x=x-w/2+global.parameters.list$multimer.margin,y=y-h/2+global.parameters.list$multimer.margin,w=w,h=h,r1=r1,r2=r2,r3=r3,r4=r4)
        svg.path2 = plot.path(object=object,d=d2,id=id,fill.color="white",stroke.width=stroke.width,stroke.color = "black",stroke.opacity = 1)
        
        # svg = paste(svg.path2,svg.path,sep="\n")
        svg = paste(svg.path2,sep="\n")
        
        # if(user.data[1] != "no.user.data"){
        if(!identical(user.data[1],"no.user.data")){
            for(i in seq_len(length.out = length(user.data))){
                fill.color = color.from.01.value(user.data[i],global.parameters.list=global.parameters.list,gene.or.cpd="gene")
                glyph.data.i = new("nucleic_acid_feature.sbgn")
                glyph.data.i@fill.color = fill.color
                glyph.data.i@user.data = c("no.user.data")
                glyph.data.i@y = y
                glyph.data.i@h = h
                glyph.data.i@w = w/length(user.data)
                glyph.data.i@x = x -w/2  + (i-1/2) * glyph.data.i@w
                glyph.data.i@label = " "
                glyph.data.i@compartment = object@compartment
                glyph.data.i@id=paste(id,"user.data",i,sep="_")
                glyph.data.i@shape$stroke.width = 0.5
                glyph.data.i@stroke.opacity = 0
                glyph.data.i@fill.opacity = 1
                if(i == 1){
                    glyph.data.i@r3 = 0
                }else if(i==length(user.data)){
                    glyph.data.i@r4 = 0
                }else{
                    glyph.data.i@r4=0
                    glyph.data.i@r3=0
                }
                svg = paste(svg,plot.glyph(glyph.data.i),sep="\n")
            }
            fill.opacity=0
        }
        d = generate.d.for.partly.rounded.corner.rect(x=x-w/2,y=y-h/2,w=w,h=h,r1=r1,r2=r2,r3=r3,r4=r4)
        svg.path = plot.path(object=object,d=d,id=id,fill.color="white",stroke.width=1,stroke.color = "black",fill.opacity = fill.opacity,stroke.opacity = 1)
        svg = paste(svg,svg.path,svg.text,sep="\n")
        return(svg)
    }
)


######################################################

setClass("nucleic_acid_feature.sbgn",contains="glyph",representation(r4="numeric",r3="numeric"))
setMethod(
    "plot.glyph"
    ,signature("nucleic_acid_feature.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        fill.color = "white"
        if(length(object@fill.color)>0){
            fill.color = object@fill.color
        }
        fill.opacity = 1
        if(length(object@fill.opacity)>0){
            fill.opacity = object@fill.opacity
        }
        # label = object@label
        label.location="center"
        r1 = 0;r2=0;r3=max(h,w)/10;r4=max(h,w)/10
        if(length(object@r4)>0){
            r4 = object@r4
        }
        if(length(object@r3)>0){
            r3 = object@r3
        }
        stroke.width=1
        if(length(object@shape$stroke.width)>0){
            stroke.width = object@shape$stroke.width
        }
        stroke.opacity=1
        if(length(object@stroke.opacity)>0){
            stroke.opacity = object@stroke.opacity
        }
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        
        svg=""
        # if(user.data[1] != "no.user.data"){
        if(!identical(user.data[1],"no.user.data")){
            for(i in seq_len(length.out = length(user.data))){
                fill.color = color.from.01.value(user.data[i],global.parameters.list=global.parameters.list,gene.or.cpd="gene")
                glyph.data.i = object
                glyph.data.i@fill.color = fill.color
                glyph.data.i@fill.opacity = 1
                glyph.data.i@user.data = c("no.user.data")
                glyph.data.i@w = w/length(user.data)
                glyph.data.i@x = x -w/2  + (i-1/2) * glyph.data.i@w
                glyph.data.i@label = " "
                glyph.data.i@shape$stroke.width = 0.5
                glyph.data.i@stroke.opacity = 0
                if(i == 1){
                    glyph.data.i@r3 = 0
                }else if(i==length(user.data)){
                    glyph.data.i@r4 = 0
                }else{
                    glyph.data.i@r4=0
                    glyph.data.i@r3=0
                }
                svg = paste(svg,plot.glyph(glyph.data.i),sep="\n")
            }
            fill.opacity=0
        }
        d = generate.d.for.partly.rounded.corner.rect(x=x-w/2,y=y-h/2,w=w,h=h,r1=r1,r2=r2,r3=r3,r4=r4)
        svg.path = plot.path(object=object,d=d,id=id,fill.color=fill.color,stroke.width=stroke.width,stroke.color = "black",stroke.opacity=stroke.opacity,fill.opacity = fill.opacity )
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg,svg.path,svg.text,sep="\n")
        return(svg)
    }
)
######################################################

setClass("perturbation.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("perturbation.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x-w/2
        y = object@y-h/2
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location="center"
        d = (paste("M",x,y,x+h/3,y+h/2 ,x,y+h  ,x+w,y+h  ,x+w-h/3,y+h/2, x+w,y,"Z",sep=" "))
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.path = plot.path(object=object,d=d,id=id,fill.color="white",stroke.width=stroke.width,stroke.color = "black")
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x+w/2,y=y+h/2,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.path,svg.text,sep="\n")
        return(svg)
    }
)
######################################################

setClass("perturbing_agent.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("perturbing_agent.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x-w/2
        y = object@y-h/2
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location="center"
        d = (paste("M",x,y,x+h/3,y+h/2 ,x,y+h  ,x+w,y+h  ,x+w-h/3,y+h/2, x+w,y,"Z",sep=" "))
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.path = plot.path(object=object,d=d,id=id,fill.color="white",stroke.width=stroke.width,stroke.color = "black")
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x+w/2,y=y+h/2,h=h,w=w,id=id,label.location=label.location)
        # svg.ellipse = plot.ellipse(glyph=object,180,210,5,5,id,fill.color = "red")
        svg = paste(svg.path,svg.text,sep="\n")
        # svg = paste(svg.path,svg.text,svg.ellipse,sep="\n")
        return(svg)
    }
)
######################################################

setClass("annotation.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("annotation.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x-w
        y = object@y-h
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        # stroke.opacity = object@stroke.opacity
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        label.location="center"
        d1 = (paste("M",x,y, x,y+h, x+w/4,y+h,  x+min(h,w)/10,y+3*h/2,  x+w/2,y+h,  x+w,y+h, x+w,y+h/5, x+w-h/5,y ,"Z",sep=" "))
        
        svg.path1 = plot.path(object=object,d=d1,id=id,fill.color="white",stroke.width=1,stroke.color = "black",stroke.opacity = stroke.opacity)
        
        d2 = (paste("M",x+w-h/5,y+h/5, x+w,y+h/5, x+w-h/5,y ,"Z",sep=" "))
        svg.path2 = plot.path(object=object,d=d2,id=id,fill.color="black",stroke.width=1,stroke.color = "black",stroke.opacity = stroke.opacity)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x+w/2,y=y+h/2,h=h,w=w,id=id,label.location=label.location,stroke.opacity = stroke.opacity)
        svg = paste(svg.path1,svg.path2,svg.text,sep="\n")
        return(svg)
    }
)


######################################################
setClass("existence.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("existence.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location="center"
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,fill.color = "white",stroke.width = stroke.width)
        d = (paste("M",x,y-h/2,"a",h/2,h/2 ,0, 0,1 ,0,h,sep=" "))
        svg.path = plot.path(object=object,d=d,id=id,fill.color="black",stroke.width=1,stroke.color = "black")
        svg = paste(svg.ellipse,svg.path,sep="\n")
        return(svg)
    }
)

######################################################
setClass("clone_simple_chemical.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("clone_simple_chemical.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = "clone"
        # label = object@label
        label.location="center"
        start.x=x-w/2+w/20
        start.y = y+(h/2/(w/2)*((w/2)**2-(start.x-x)**2)**0.5)
        d = (paste("M",start.x,start.y,"A",w/2,h/2 ,1, 0,0 ,x+w/2-w/20,start.y,sep=" "))
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.path = plot.path(object=object,d=d,id=id,fill.color="black",stroke.width= stroke.width,stroke.color = "black")
        svg = svg.path
        return(svg)
    }
)
######################################################


setClass("clone.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("clone.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = "clone"
        # label = object@label
        label.location="center"
        r1 = 0;r2=0;r3=max(h,w)/10;r4=max(h,w)/10
        d1 = generate.d.for.partly.rounded.corner.rect(x=x-w/2,y=y+h/2-h/5,w=w,h=h/5,r1=r1,r2=r2,r3=r3,r4=r4)
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.path.bigbox = plot.path(object=object,d=d1,id=id,fill.color="black",stroke.width=stroke.width,stroke.color = "black")
        
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y+h/2-h/10,h=h,w=w,id=id,label.location=label.location,color="white")
        svg = paste(svg.path.bigbox,svg.text,sep="\n")
        return(svg)
    }
)

######################################################

setClass("clone_marker.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("clone_marker.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location="center"
        r1 = 0;r2=0;r3=min(h,w)/10;r4=min(h,w)/10
        d1 = generate.d.for.partly.rounded.corner.rect(x=x-w/2,y=y-h/2,w=w,h=h,r1=r1,r2=r2,r3=r3,r4=r4)
        svg.path.bigbox = plot.path(object=object,d=d1,id=id,fill.color="white",stroke.width=1,stroke.color = "black")
        d2 = generate.d.for.partly.rounded.corner.rect(x=x-w/2,y=y-h/2+3/5*h,w=w,h=2/5*h,r1=r1,r2=r2,r3=r3,r4=r4)
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.path.innerbox = plot.path(object=object,d=d2,id=id,fill.color="gray",stroke.width=stroke.width,stroke.color = "black")
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y-1/5*h,h=h,w=w,id=id,label.location=label.location)
        white.top.line.to.cover = paste("M",x-w/2,y-h/2,x+w/2,y-h/2,sep=" ")
        svg.path.topWhiteLine = plot.path(object=object,d=white.top.line.to.cover,id=id,fill.color="gray",stroke.width=5,stroke.color = "white")
        svg = paste(svg.path.bigbox,svg.path.innerbox,svg.path.topWhiteLine,svg.text,sep="\n")
        return(svg)
    }
)

######################################################

setClass("terminal.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("terminal.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x-w/2
        y = object@y-h/2
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        orientation = object@orientation
        label.location="center"
        d = (paste("M",x+h/3,y,x,y+h/2 ,x+h/3,y+h  ,x+w-h/3,y+h  ,x+w,y+h/2, x+w-h/3,y,"Z",sep=" "))
        if (orientation == "right"){
            d = (paste("M",x,y ,x,y+h  ,x+w-w/3,y+h  ,x+w,y+h/2, x+w-w/3,y,"Z",sep=" "))
        }else if (orientation == "left"){
            d = (paste("M",x+w/3,y,x,y+h/2 ,x+w/3,y+h  ,x+w,y+h  ,x+w,y,"Z",sep=" "))
        }else if (orientation == "up"){
            d = (paste("M",x+w/2,y,x,y+h/3 ,x,y+h  ,x+w,y+h  ,x+w,y+h/3,"Z",sep=" "))
        }else if (orientation == "down"){
            d = (paste("M",x,y ,x,y+h-h/3, x+w/2,y+h  ,x+w,y+h-h/3  ,x+w,y,"Z",sep=" "))
        }
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.path = plot.path(object=object,d=d,id=id,fill.color="white",stroke.width=stroke.width,stroke.color = "black")
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x+w/2,y=y+h/2,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.path,svg.text,sep="\n")
        return(svg)
    }
)

######################################################

setClass("tag.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("tag.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x-w/2
        y = object@y-h/2
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        orientation = object@orientation
        label.location="center"
        d = (paste("M",x+h/3,y,x,y+h/2 ,x+h/3,y+h  ,x+w-h/3,y+h  ,x+w,y+h/2, x+w-h/3,y,"Z",sep=" "))
        if (orientation == "right"){
            d = (paste("M",x,y ,x,y+h  ,x+w-w/3,y+h  ,x+w,y+h/2, x+w-w/3,y,"Z",sep=" "))
        }else if (orientation == "left"){
            d = (paste("M",x+w/3,y,x,y+h/2 ,x+w/3,y+h  ,x+w,y+h  ,x+w,y,"Z",sep=" "))
        }else if (orientation == "up"){
            d = (paste("M",x+w/2,y,x,y+h/3 ,x,y+h  ,x+w,y+h  ,x+w,y+h/3,"Z",sep=" "))
        }else if (orientation == "down"){
            d = (paste("M",x,y ,x,y+h-h/3, x+w/2,y+h  ,x+w,y+h-h/3  ,x+w,y,"Z",sep=" "))
        }
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.path = plot.path(object=object,d=d,id=id,fill.color="white",stroke.width=stroke.width,stroke.color = "black")
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x+w/2,y=y+h/2,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.path,svg.text,sep="\n")
        return(svg)
    }
)

######################################################

setClass("phenotype.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("phenotype.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x-w/2
        y = object@y-h/2
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location="center"
        d = (paste("M",x+h/3,y,x+5,y+h/2 ,x+h/3,y+h  ,x+w-h/3,y+h  ,x+w-5,y+h/2, x+w-h/3,y,"Z",sep=" "))
        svg.path = plot.path(object=object,d=d,id=id,fill.color="white",stroke.width=1,stroke.color = "black")
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x+w/2,y=y+h/2,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.path,svg.text,sep="\n")
        return(svg)
    }
)


##########################################################
setClass("association.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("association.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,fill.color="black",stroke.width = stroke.width)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg = paste(svg.ellipse,svg.wings,sep="\n")
        return(svg)
    }
)
######################################################
setClass("interaction.sbgn.arc",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("interaction.sbgn.arc")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        Coordinates = paste("x1=",x-w/2," y1=",y+h/2," x2=",x+w/2," y2=",y-h/2,"",sep='"')
        svg = svg.ellipse
        return(svg)
    }
)


######################################################
setClass("interaction.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("interaction.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        Coordinates = paste("x1=",x-w/2," y1=",y+h/2," x2=",x+w/2," y2=",y-h/2,"",sep='"')
        svg.line = plot.line(Coordinates,id)
        svg = svg.ellipse
        return(svg)
    }
)


##########################################################
setClass("delay.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("delay.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        object@label = "t"
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        label.location = "center"
        rx = 0
        ry = 0
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        svg.wings = plot.LineWings(x,y,w,h,orientation,id)
        svg.wings = ""
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.ellipse,svg.wings,svg.text,sep="\n")
        return(svg)
    }
)



######################################################
setClass("source_and_sink.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("source_and_sink.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        if (length(object@orientation)>0){
            orientation = object@orientation
        }else{
            orientation = "horizontal"
        }
        stroke.width=1
        if(object@compartment == "free.node.within.compartment"){
            stroke.width = 3
        }
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id,stroke.width = stroke.width)
        Coordinates = paste("x1=",x-w/2," y1=",y+h/2," x2=",x+w/2," y2=",y-h/2,"",sep='"')
        svg.line = plot.line(Coordinates,id)
        svg = paste(svg.ellipse,svg.line,sep="\n")
        return(svg)
    }
)

######################################################
setClass("location.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("location.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        h = w
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        svg.ellipse = plot.ellipse(glyph=object,x,y,h,w,id)
        angle = pi/6
        Coordinates1 = paste("x1=",x-w/2*cos(angle)," y1=",y+h/2*sin(angle)," x2=",x+w/2*sin(angle)," y2=",y-h/2*cos(angle),"",sep='"')
        svg.line1 = plot.line(Coordinates1,id)
        Coordinates2 = paste("x1=",x-w/2*(cos(angle)-sin(angle))/2," y1=",y+h/2*(sin(angle)-cos(angle))/2," x2=",x+w/2*sin(pi/4)," y2=",y+h/2*cos(pi/4),"",sep='"')
        svg.line2 = plot.line(Coordinates2,id)
        svg = paste(svg.ellipse,svg.line1,svg.line2,sep="\n")
        return(svg)
    }
)
######################################################

setClass("state_variable.ER.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("state_variable.ER.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location="center"
        r1 = h/2 ;r2=r1;r3=r1;r4=r1
        d = generate.d.for.partly.rounded.corner.rect(x=x-w/2,y=y-h/2,w=w,h=h,r1=r1,r2=r2,r3=r3,r4=r4)
        svg.path = plot.path(object=object,d=d,id=id,fill.color="white",stroke.width=1,stroke.color = "black",fill.opacity = 1)
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.path,svg.text,sep="\n")
        return(svg)
    }
)
######################################################
setClass("variable_value.sbgn",contains="glyph")
setMethod(
    "plot.glyph"
    ,signature("variable_value.sbgn")
    , function(object){
        w = object@w
        h = object@h ; 
        x = object@x
        y = object@y
        global.parameters.list = object@global.parameters.list
        id = object@id ; user.data = object@user.data
        # label = object@label
        label.location="center"
        r1 = h/2 ;r2=r1;r3=r1;r4=r1
        d = generate.d.for.partly.rounded.corner.rect(x=x-w/2,y=y-h/2,w=w,h=h,r1=r1,r2=r2,r3=r3,r4=r4)
        svg.path = plot.path(object=object,d=d,id=id,fill.color="white",stroke.width=1,stroke.color = "black")
        svg.text = plot.text(glyph=object,glyph.class=object@glyph.class,global.parameters.list=global.parameters.list,x=x,y=y,h=h,w=w,id=id,label.location=label.location)
        svg = paste(svg.path,svg.text,sep="\n")
        return(svg)
    }
)



















######################################################

setMethod(
    "plot.arc"
    ,signature("spline.arc")
    , function(object){
        components = object@components
        svg = ""
        for (i in seq_len(length.out = length(components))){
            component = components[[i]]
            component@edge = object@edge
            component@global.parameters.list = object@global.parameters.list
            if(!is(component, "spline")){
                component@edge$line.stroke.opacity = 0
            }
            svg = paste(svg,plot.arc(component),sep="\n")
        }
        return(svg)
    }
)


######################################################

spline.svg.template = '<path d="M%s %s C %s %s, %s %s,%s %s" stroke="%s" stroke-opacity="%s" stroke-width="%s" fill-opacity="0" fill="transparent"/>'
setMethod(
    "plot.arc"
    ,signature("spline")
    , function(object){
        svg =  do.call(sprintf,c(list(spline.svg.template)
                                 ,c(object@spline.coords
                                    ,object@edge$line.stroke.color
                                    ,object@edge$line.stroke.opacity
                                    ,object@edge$line.width
                                   )
                                )
                        )
        return(svg)
    }
)

######################################################

setClass("absolute_stimulation.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("absolute_stimulation.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id 
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        points = paste(end.x,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y-global.parameters.list$edge.tip.size," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y+global.parameters.list$edge.tip.size,sep="")
        points2 = paste(end.x-global.parameters.list$edge.tip.size*3,",",end.y," ",end.x-global.parameters.list$edge.tip.size*6,",",end.y-global.parameters.list$edge.tip.size," ",end.x-global.parameters.list$edge.tip.size*6,",",end.y+global.parameters.list$edge.tip.size,sep="")
        if (start.x<end.x){
            svg.triangle = plot.polygon(object=object,points,fill.color = "white",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
            svg.triangle2 = plot.polygon(object=object,points2,fill.color = "white",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            svg.triangle = plot.polygon(object=object,points,fill.color = "white",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
            svg.triangle2= plot.polygon(object=object,points2,fill.color = "white",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
        }
        svg = paste(svg.line,svg.triangle,svg.triangle2,sep="\n")
        return(svg)
    }
)
######################################################

setClass("absolute_inhibition.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("absolute_inhibition.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        global.parameters.list = object@global.parameters.list
        id = object@id ;
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        d = (paste("M",end.x-1,end.y-global.parameters.list$edge.tip.size*3/2,end.x-1,end.y+global.parameters.list$edge.tip.size*3/2,sep=" "))
        svg.endLine = plot.path(object=object,d=d,id=id,fill.color="black",stroke.width=1,stroke.color = "black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        if (start.x<end.x){
            d1 = (paste("M",end.x-global.parameters.list$edge.tip.size*3/4,end.y-global.parameters.list$edge.tip.size*3/2,end.x-global.parameters.list$edge.tip.size*3/4,end.y+global.parameters.list$edge.tip.size*3/2,sep=" "))
            svg.endLine1 = plot.path(object=object,d=d1,id=id,fill.color="black",stroke.width=1,stroke.color = "black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            d1 = (paste("M",end.x+global.parameters.list$edge.tip.size*3/4,end.y-global.parameters.list$edge.tip.size*3/2,end.x+global.parameters.list$edge.tip.size*3/4,end.y+global.parameters.list$edge.tip.size*3/2,sep=" "))
            svg.endLine1 = plot.path(object=object,d=d1,id=id,fill.color="black",stroke.width=1,stroke.color = "black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }
        svg = paste(svg.line,svg.endLine,svg.endLine1,sep="\n")
        return(svg)
    }
)
######################################################

setClass("necessary_stimulation.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("necessary_stimulation.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        global.parameters.list = object@global.parameters.list
        end.line.length = global.parameters.list$edge.tip.size*3/2
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        points = paste(end.x,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y-end.line.length," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y+end.line.length,sep="")
        if (start.x<end.x){
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
            d = (paste("M",end.x-global.parameters.list$edge.tip.size*4,end.y-end.line.length-global.parameters.list$edge.tip.size*3/4,end.x-global.parameters.list$edge.tip.size*4,end.y+end.line.length+global.parameters.list$edge.tip.size*3/4,sep=" "))
            svg.endLine = plot.path(object=object,d=d,id=id,fill.color="black",stroke.width=1,stroke.color = "black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
            d = (paste("M",end.x+global.parameters.list$edge.tip.size*4,end.y-end.line.length-global.parameters.list$edge.tip.size*3/4,end.x+global.parameters.list$edge.tip.size*4,end.y+end.line.length+global.parameters.list$edge.tip.size*3/4,sep=" "))
            svg.endLine = plot.path(object=object,d=d,id=id,fill.color="black",stroke.width=1,stroke.color = "black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }
        svg = paste(svg.line,svg.triangle,svg.endLine,sep="\n")
        return(svg)
    }
)

######################################################
setClass("equivalence_arc.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("equivalence_arc.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        svg = svg.line
        return(svg)
    }
)


######################################################
setClass("consumption.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("consumption.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        svg = svg.line
        return(svg)
    }
)
######################################################
setClass("next.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("next.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        svg = svg.line
        return(svg)
    }
)

###############################################

setClass("production.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("production.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        #############################
        # if(grepl("arc_292_output_257",id)){
        #     cat("printing object")
        # }
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        end.size = global.parameters.list$edge.tip.size*2
        points = paste(end.x,",",end.y," ",end.x-end.size,",",end.y-end.size/2," ",end.x-end.size,",",end.y+end.size/2,sep="")
        if (start.x<end.x){
            svg.triangle = plot.polygon(object=object,points,"black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            svg.triangle = plot.polygon(object=object,points,"black",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
        }
        svg = paste(svg.line,svg.triangle,sep="\n")
        return(svg)
    }
)
######################################################

setClass("interaction.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("interaction.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        
        points.end = paste(end.x,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y-global.parameters.list$edge.tip.size," ",end.x-global.parameters.list$edge.tip.size*2,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y+global.parameters.list$edge.tip.size,sep="")
        points.start = paste(start.x,",",start.y," ",start.x+global.parameters.list$edge.tip.size*3,",",start.y-global.parameters.list$edge.tip.size," ",start.x+global.parameters.list$edge.tip.size*2,",",start.y," ",start.x+global.parameters.list$edge.tip.size*3,",",start.y+global.parameters.list$edge.tip.size,sep="")
        if (start.x<end.x){
            svg.triangle.end = plot.polygon(object=object,points.end,"black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
            svg.triangle.start = plot.polygon(object=object,points.start,"black",atan((start.y-end.y)/(start.x-end.x))/pi*180,start.x,start.y)
        }else{
            svg.triangle.end = plot.polygon(object=object,points.end,"black",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
            svg.triangle.start = plot.polygon(object=object,points.start,"black",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,start.x,start.y)
        }
        svg = paste(svg.line,svg.triangle.end,svg.triangle.start,sep="\n")
        return(svg)
    }
)
######################################################

setClass("assignment.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("assignment.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        points = paste(end.x,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y-global.parameters.list$edge.tip.size," ",end.x-global.parameters.list$edge.tip.size*2,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y+global.parameters.list$edge.tip.size,sep="")
        if (start.x<end.x){
            svg.triangle = plot.polygon(object=object,points,"black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            svg.triangle = plot.polygon(object=object,points,"black",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
        }
        svg = paste(svg.line,svg.triangle,sep="\n")
        return(svg)
    }
)
######################################################

setClass("catalysis.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("catalysis.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        global.parameters.list = object@global.parameters.list
        id = object@id ;
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        angle = atan((start.y-end.y)/(start.x-end.x))
        circle.r = global.parameters.list$edge.tip.size
        if (start.x<end.x){
            circle.center.x = end.x - circle.r * cos(angle)
            circle.center.y = end.y - circle.r * sin(angle)
        }else {
            circle.center.x = end.x + circle.r * cos(angle)
            circle.center.y = end.y + circle.r * sin(angle)
        }
        svg.ellipse = plot.ellipse.edge.tip(circle.center.x,circle.center.y,circle.r*2,circle.r*2,id,fill.opacity = 0.8,object=object)
        svg = paste(svg.line,svg.ellipse,sep="\n")
        return(svg)
    }
)
######################################################
setClass("positive_influence.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("positive_influence.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        points = paste(end.x,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y-global.parameters.list$edge.tip.size," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y+global.parameters.list$edge.tip.size,sep="")
        if (start.x<end.x){
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
        }
        svg = paste(svg.line,svg.triangle,sep="\n")
        return(svg)
    }
)
######################################################


setClass("stimulation.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("stimulation.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        points = paste(end.x,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y-global.parameters.list$edge.tip.size," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y+global.parameters.list$edge.tip.size,sep="")
        if (start.x<end.x){
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
        }
        svg = paste(svg.line,svg.triangle,sep="\n")
        return(svg)
    }
)
######################################################

setClass("negative_influence.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("negative_influence.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        if (start.x<end.x){
            d = (paste("M",end.x-global.parameters.list$inhibition.edge.end.shift,end.y-global.parameters.list$edge.tip.size*3/2,end.x-global.parameters.list$inhibition.edge.end.shift,end.y+global.parameters.list$edge.tip.size*3/2,sep=" "))
            svg.endLine = plot.path(object=object,d=d,id=id,fill.color="black",stroke.width=1,stroke.color = "black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            d = (paste("M",end.x+global.parameters.list$inhibition.edge.end.shift,end.y-global.parameters.list$edge.tip.size*3/2,end.x+global.parameters.list$inhibition.edge.end.shift,end.y+global.parameters.list$edge.tip.size*3/2,sep=" "))
            svg.endLine = plot.path(object=object,d=d,id=id,fill.color="black",stroke.width=1,stroke.color = "black",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }
        svg = paste(svg.line,svg.endLine,sep="\n")
        return(svg)
    }
)
######################################################

setClass("inhibition.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("inhibition.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        
        
        inhibition.edge.end.shift = global.parameters.list$inhibition.edge.end.shift
        line.length = ((start.x-end.x)**2 + (start.y-end.y)**2) ** 0.5
        if (start.x<end.x){
                      # if(grepl("arc_165_inhibitor_28",object@id)){
                      #     print("start x smaller than end x")
                      #     print(start.x)
                      #     print(end.x)
                      #     print("printed two x es")
                      # }
            d1 = (paste("M"
                       # ,start.x
                       ,end.x - line.length
                       ,end.y
                       ,end.x-inhibition.edge.end.shift
                       ,end.y
                       ,sep=" "))
            svg.line = plot.path(object=object
                                 ,d=d1
                                 ,id=id
                                 ,fill.color="white"
                                 ,stroke.color = "white"
                                 ,stroke.width=1
                                 ,angle = atan((start.y-end.y)/(start.x-end.x))/pi*180
                                 ,rotate.x = end.x
                                 ,rotate.y = end.y
                                 )
                
            d = (paste("M"
                       ,end.x-inhibition.edge.end.shift
                       # ,end.x - line.length
                       ,end.y-global.parameters.list$edge.tip.size*3/2
                       ,end.x-inhibition.edge.end.shift
                       ,end.y+global.parameters.list$edge.tip.size*3/2
                       ,sep=" "))
            svg.endLine = plot.path(object=object,d=d,id=id,fill.color="black",stroke.width=1,stroke.color = "black"
                                    ,atan((start.y-end.y)/(start.x-end.x))/pi*180
                                    ,end.x
                                    ,end.y)
        }else{
            d1 = (paste("M"
                       ,end.x + line.length
                       ,end.y
                       ,end.x+inhibition.edge.end.shift
                       ,end.y
                       ,sep=" "))
            svg.line = plot.path(object=object
                                 ,d=d1
                                 ,id=id
                                 ,fill.color="white"
                                 ,stroke.color = "white"
                                 ,stroke.width=1
                                ,atan((start.y-end.y)/(start.x-end.x))/pi*180
                                ,end.x
                                ,end.y)
            
            d = (paste("M"
                       ,end.x+inhibition.edge.end.shift
                       ,end.y-global.parameters.list$edge.tip.size*3/2
                       ,end.x+inhibition.edge.end.shift
                       ,end.y+global.parameters.list$edge.tip.size*3/2
                       ,sep=" "))
            # object@edge$tip.stroke.color = "purple"
            svg.endLine = plot.path(object=object,d=d,id=id,fill.color="black",stroke.width=1,stroke.color = "black"
                                    ,atan((start.y-end.y)/(start.x-end.x))/pi*180
                                    ,end.x
                                    ,end.y)
        }
        svg = paste(svg.line,svg.endLine,sep="\n")
        return(svg)
    }
)
######################################################

setClass("unknown_influence.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("unknown_influence.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        points = paste(end.x,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3/2,",",end.y-global.parameters.list$edge.tip.size*3/2," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3/2,",",end.y+global.parameters.list$edge.tip.size*3/2,sep="")
        if (start.x<end.x){
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
        }
        svg = paste(svg.line,svg.triangle,sep="\n")
        return(svg)
    }
)
######################################################

setClass("modulation.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("modulation.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        global.parameters.list = object@global.parameters.list
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        points = paste(end.x,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3/2,",",end.y-global.parameters.list$edge.tip.size*3/2," ",end.x-global.parameters.list$edge.tip.size*3,",",end.y," ",end.x-global.parameters.list$edge.tip.size*3/2,",",end.y+global.parameters.list$edge.tip.size*3/2,sep="")
        if (start.x<end.x){
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180,end.x,end.y)
        }else{
            svg.triangle = plot.polygon(object=object,points,"white",atan((start.y-end.y)/(start.x-end.x))/pi*180+180,end.x,end.y)
        }
        svg = paste(svg.line,svg.triangle,sep="\n")
        return(svg)
    }
)
######################################################

setClass("logic_arc.sbgn.arc",contains="arc")
setMethod(
    "plot.arc"
    ,signature("logic_arc.sbgn.arc")
    , function(object){
        start.x = object@start.x
        start.y = object@start.y
        end.x = object@end.x
        end.y = object@end.y
        id = object@id ;
        if(length(object@stroke.opacity) !=0) stroke.opacity = object@stroke.opacity  else stroke.opacity = 1
        LineCoordinates = paste("x1=",start.x," y1=",start.y," x2=",end.x," y2=",end.y,"",sep='"')
        svg.line = plot.line(object=object,LineCoordinates,id,stroke.opacity=stroke.opacity)
        svg = svg.line
        return(svg)
    }
)

plot.text = function(x,y,h,w,id,label.location,color="black",glyph.class="",stroke.opacity=1,max.x=0,if.generate.text.box= FALSE,global.parameters.list,glyph){
    label = glyph@label
    if(length(glyph@text$color)>0){
        color = glyph@text$color
    }
    if(length(glyph@text$x.shift)>0){
        x = x + glyph@text$x.shift
    }
    if(length(glyph@text$y.shift)>0){
        y = y + glyph@text$y.shift
    }
    label = gsub("&","-",label)
    label = gsub("<[^><]+>","",label)  # when using paxtools::toSBGN to convert biopax files to SBGN files, some text in the SBGN files contain special characters :label text="<i>p</i>-chloromercuribenzoate" . the "<" and ">" will create problem in the svg file. So we need remove them.
    if (length(nchar(label))==0){ # when the label is empty, don't plot it
        print("no label")
        return ("")
    } 
    result.list = break.text.into.segments(w,glyph.class,global.parameters.list = global.parameters.list,max.x=max.x,glyph=glyph)
    label = result.list$words.segments
    font.size = result.list$font.size
    global.parameters.list$complex.compartment.label.margin.use = global.parameters.list$complex.compartment.label.margin
    if(glyph.class == "compartment"){
        if(max.x>0){ # if the graph is large, make label larger
            global.parameters.list$complex.compartment.label.margin.use = global.parameters.list$complex.compartment.label.margin.use * max(1,max.x/2000)
        }
    }
    
    label.segments = strsplit(label,'\n') # the label text in some of the input sbgn files are labeled with "&#xA;" in order to be seperated to different lines
    label.segments = label.segments[[1]]
    align.shift = font.size/3
    
    text.anchor = "middle"
    alignment.baseline = "middle"
    x.label.box = x
    if (length(label.segments)>1){ # if the text is labeled to be seperated into different lines
        svg = ""
        n.lines = length(label.segments)
        h.label.box = n.lines * font.size
        for (i in seq_len(length.out = n.lines)){
            label.segment = label.segments[i]
            w.label.box = nchar(label.segment)*font.size
            if(label.location == "center"){
                alignment.baseline = "baseline"
                first.segment.shift = (n.lines-1)/2*font.size
                start.y = y- first.segment.shift
                y.segment = start.y + (i-1)*font.size
                y.segment = y.segment+align.shift
                if(i == 1){
                    y.label.box = y.segment+align.shift
                }
            }else if(label.location == "top"){
                y.segment = y-h/2+2 + (i-1)*font.size
                if(glyph.class %in% c("complex","compartment")){
                    y.segment = y-h/2-n.lines*font.size + (i-1)*font.size
                }
                text.anchor = "middle"
                alignment.baseline = "baseline"
                y.segment = y.segment+align.shift*2
                if(i == 1){
                    y.label.box = y.segment+align.shift
                }
            }
            svg.segment = sprintf(template.text,x,y.segment,id,font.size,text.anchor,alignment.baseline,stroke.opacity,alignment.baseline,color,label.segment)
            svg = paste(svg,svg.segment,sep="\n")
        }
    } else{
        w.label.box = nchar(label)*font.size *0.5
        h.label.box = font.size
        if(glyph.class %in% c("compartment","complex")){
            align.shift = 0
        }
        svg = template.text
        if(label.location == "center"){
            alignment.baseline = "baseline"
            svg = sprintf(template.text,x,y+align.shift,id,font.size,text.anchor,alignment.baseline,stroke.opacity,alignment.baseline,color,label)
            y.label.box = y+align.shift
        }else if(label.location == "top"){
            text.anchor = "middle"
            # alignment.baseline = "hanging"
            if(glyph.class %in% c("complex","compartment")){
                alignment.baseline = "baseline"
                svg = sprintf(template.text,x,y+align.shift-h/2-global.parameters.list$complex.compartment.label.margin.use,id,font.size,text.anchor,alignment.baseline,stroke.opacity,alignment.baseline,color,label)
            }else{
                svg = sprintf(template.text,x,y+align.shift-h/2+4,id,font.size,text.anchor,alignment.baseline,stroke.opacity,alignment.baseline,color,label)
            }
            y.label.box = y -h/2 -global.parameters.list$complex.compartment.label.margin.use - h.label.box/3
        }
    }
    return(svg)
}
chemokine/OmicsSBGN documentation built on June 27, 2019, 7:52 p.m.