aboutsummaryrefslogtreecommitdiff
path: root/wqflask/utility/svg.py
diff options
context:
space:
mode:
Diffstat (limited to 'wqflask/utility/svg.py')
-rw-r--r--wqflask/utility/svg.py1179
1 files changed, 0 insertions, 1179 deletions
diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py
deleted file mode 100644
index 912cd04c..00000000
--- a/wqflask/utility/svg.py
+++ /dev/null
@@ -1,1179 +0,0 @@
-# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License
-# as published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the GNU Affero General Public License for more details.
-#
-# This program is available from Source Forge: at GeneNetwork Project
-# (sourceforge.net/projects/genenetwork/).
-#
-# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
-# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
-#
-#
-#
-# This module is used by GeneNetwork project (www.genenetwork.org)
-#
-# Created by GeneNetwork Core Team 2010/08/10
-#
-# Last updated by GeneNetwork Core Team 2010/10/20
-
-#!/usr/bin/env python
-# Copyright (c) 2002, Fedor Baart & Hans de Wit (Stichting Farmaceutische Kengetallen)
-# All rights reserved.
-##
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-##
-# Redistributions of source code must retain the above copyright notice, this
-# list of conditions and the following disclaimer.
-##
-# Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation and/or
-# other materials provided with the distribution.
-##
-# Neither the name of the Stichting Farmaceutische Kengetallen nor the names of
-# its contributors may be used to endorse or promote products derived from this
-# software without specific prior written permission.
-##
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# Thanks to Gerald Rosennfellner for his help and useful comments.
-
-import sys
-import exceptions
-__doc__ = """Use SVGdraw to generate your SVGdrawings.
-
-SVGdraw uses an object model drawing and a method toXML to create SVG graphics
-by using easy to use classes and methods usualy you start by creating a drawing eg
-
- d=drawing()
- # then you create a SVG root element
- s=svg()
- # then you add some elements eg a circle and add it to the svg root element
- c=circle()
- # you can supply attributes by using named arguments.
- c=circle(fill='red',stroke='blue')
- # or by updating the attributes attribute:
- c.attributes['stroke-width']=1
- s.addElement(c)
- # then you add the svg root element to the drawing
- d.setSVG(s)
- # and finaly you xmlify the drawing
- d.toXml()
-
-
-this results in the svg source of the drawing, which consists of a circle
-on a white background. Its as easy as that;)
-This module was created using the SVG specification of www.w3c.org and the
-O'Reilly (www.oreilly.com) python books as information sources. A svg viewer
-is available from www.adobe.com"""
-
-__version__ = "1.0"
-
-# there are two possibilities to generate svg:
-# via a dom implementation and directly using <element>text</element> strings
-# the latter is way faster (and shorter in coding)
-# the former is only used in debugging svg programs
-# maybe it will be removed alltogether after a while
-# with the following variable you indicate whether to use the dom implementation
-# Note that PyXML is required for using the dom implementation.
-# It is also possible to use the standard minidom. But I didn't try that one.
-# Anyway the text based approach is about 60 times faster than using the full dom implementation.
-use_dom_implementation = 0
-
-
-if use_dom_implementation != 0:
- try:
- from xml.dom import implementation
- from xml.dom.ext import PrettyPrint
- except:
- raise exceptions.ImportError(
- "PyXML is required for using the dom implementation")
-# The implementation is used for the creating the XML document.
-# The prettyprint module is used for converting the xml document object to a xml file
-
-sys.setrecursionlimit = 50
-# The recursion limit is set conservative so mistakes like s=svg() s.addElement(s)
-# won't eat up too much processor time.
-
-# the following code is pasted form xml.sax.saxutils
-# it makes it possible to run the code without the xml sax package installed
-# To make it possible to have <rubbish> in your text elements, it is necessary to escape the texts
-
-
-def _escape(data, entities={}):
- """Escape &, <, and > in a string of data.
-
- You can escape other strings of data by passing a dictionary as
- the optional entities parameter. The keys and values must all be
- strings; each key will be replaced with its corresponding value.
- """
- # data = data.replace("&", "&amp;")
- data = data.replace("<", "&lt;")
- data = data.replace(">", "&gt;")
- for chars, entity in list(entities.items()):
- data = data.replace(chars, entity)
- return data
-
-
-def _quoteattr(data, entities={}):
- """Escape and quote an attribute value.
-
- Escape &, <, and > in a string of data, then quote it for use as
- an attribute value. The \" character will be escaped as well, if
- necessary.
-
- You can escape other strings of data by passing a dictionary as
- the optional entities parameter. The keys and values must all be
- strings; each key will be replaced with its corresponding value.
- """
- data = _escape(data, entities)
- if '"' in data:
- if "'" in data:
- data = '"%s"' % data.replace('"', "&quot;")
- else:
- data = "'%s'" % data
- else:
- data = '"%s"' % data
- return data
-
-
-def _xypointlist(a):
- """formats a list of xy pairs"""
- s = ''
- for e in a: # this could be done more elegant
- s += str(e)[1:-1] + ' '
- return s
-
-
-def _viewboxlist(a):
- """formats a tuple"""
- s = ''
- for e in a:
- s += str(e) + ' '
- return s
-
-
-def _pointlist(a):
- """formats a list of numbers"""
- return str(a)[1:-1]
-
-
-class pathdata:
- """class used to create a pathdata object which can be used for a path.
- although most methods are pretty straightforward it might be useful to look at the SVG specification."""
- # I didn't test the methods below.
-
- def __init__(self, x=None, y=None):
- self.path = []
- if x is not None and y is not None:
- self.path.append('M ' + str(x) + ' ' + str(y))
-
- def closepath(self):
- """ends the path"""
- self.path.append('z')
-
- def move(self, x, y):
- """move to absolute"""
- self.path.append('M ' + str(x) + ' ' + str(y))
-
- def relmove(self, x, y):
- """move to relative"""
- self.path.append('m ' + str(x) + ' ' + str(y))
-
- def line(self, x, y):
- """line to absolute"""
- self.path.append('L ' + str(x) + ' ' + str(y))
-
- def relline(self, x, y):
- """line to relative"""
- self.path.append('l ' + str(x) + ' ' + str(y))
-
- def hline(self, x):
- """horizontal line to absolute"""
- self.path.append('H' + str(x))
-
- def relhline(self, x):
- """horizontal line to relative"""
- self.path.append('h' + str(x))
-
- def vline(self, y):
- """verical line to absolute"""
- self.path.append('V' + str(y))
-
- def relvline(self, y):
- """vertical line to relative"""
- self.path.append('v' + str(y))
-
- def bezier(self, x1, y1, x2, y2, x, y):
- """bezier with xy1 and xy2 to xy absolut"""
- self.path.append('C' + str(x1) + ',' + str(y1) + ' ' + str(x2)
- + ',' + str(y2) + ' ' + str(x) + ',' + str(y))
-
- def relbezier(self, x1, y1, x2, y2, x, y):
- """bezier with xy1 and xy2 to xy relative"""
- self.path.append('c' + str(x1) + ',' + str(y1) + ' ' + str(x2)
- + ',' + str(y2) + ' ' + str(x) + ',' + str(y))
-
- def smbezier(self, x2, y2, x, y):
- """smooth bezier with xy2 to xy absolut"""
- self.path.append('S' + str(x2) + ',' + str(y2) + \
- ' ' + str(x) + ',' + str(y))
-
- def relsmbezier(self, x2, y2, x, y):
- """smooth bezier with xy2 to xy relative"""
- self.path.append('s' + str(x2) + ',' + str(y2) + \
- ' ' + str(x) + ',' + str(y))
-
- def qbezier(self, x1, y1, x, y):
- """quadratic bezier with xy1 to xy absolut"""
- self.path.append('Q' + str(x1) + ',' + str(y1) + \
- ' ' + str(x) + ',' + str(y))
-
- def relqbezier(self, x1, y1, x, y):
- """quadratic bezier with xy1 to xy relative"""
- self.path.append('q' + str(x1) + ',' + str(y1) + \
- ' ' + str(x) + ',' + str(y))
-
- def smqbezier(self, x, y):
- """smooth quadratic bezier to xy absolut"""
- self.path.append('T' + str(x) + ',' + str(y))
-
- def relsmqbezier(self, x, y):
- """smooth quadratic bezier to xy relative"""
- self.path.append('t' + str(x) + ',' + str(y))
-
- def ellarc(self, rx, ry, xrot, laf, sf, x, y):
- """elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy absolut"""
- self.path.append('A' + str(rx) + ',' + str(ry) + ' ' + str(xrot)
- + ' ' + str(laf) + ' ' + str(sf) + ' ' + str(x) + ' ' + str(y))
-
- def relellarc(self, rx, ry, xrot, laf, sf, x, y):
- """elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy relative"""
- self.path.append('a' + str(rx) + ',' + str(ry) + ' ' + str(xrot)
- + ' ' + str(laf) + ' ' + str(sf) + ' ' + str(x) + ' ' + str(y))
-
- def __repr__(self):
- return ' '.join(self.path)
-
-
-class SVGelement:
- """SVGelement(type,attributes,elements,text,namespace,**args)
- Creates a arbitrary svg element and is intended to be subclassed not used on its own.
- This element is the base of every svg element it defines a class which resembles
- a xml-element. The main advantage of this kind of implementation is that you don't
- have to create a toXML method for every different graph object. Every element
- consists of a type, attribute, optional subelements, optional text and an optional
- namespace. Note the elements==None, if elements = None:self.elements=[] construction.
- This is done because if you default to elements=[] every object has a reference
- to the same empty list."""
-
- def __init__(self, type='', attributes=None, elements=None, text='', namespace='', cdata=None, **args):
- self.type = type
- if attributes == None:
- self.attributes = {}
- else:
- self.attributes = attributes
- if elements == None:
- self.elements = []
- else:
- self.elements = elements
- self.text = text
- self.namespace = namespace
- self.cdata = cdata
- for arg in list(args.keys()):
- arg2 = arg.replace("__", ":")
- arg2 = arg2.replace("_", "-")
- self.attributes[arg2] = args[arg]
-
- def addElement(self, SVGelement):
- """adds an element to a SVGelement
-
- SVGelement.addElement(SVGelement)
- """
- self.elements.append(SVGelement)
-
- def toXml(self, level, f):
- f.write('\t' * level)
- f.write('<' + self.type)
- for attkey in list(self.attributes.keys()):
- f.write(' ' + _escape(str(attkey)) + '='
- + _quoteattr(str(self.attributes[attkey])))
- if self.namespace:
- f.write(' xmlns="' + _escape(str(self.namespace))
- + '" xmlns:xlink="http://www.w3.org/1999/xlink"')
- if self.elements or self.text or self.cdata:
- f.write('>')
- if self.elements:
- f.write('\n')
- for element in self.elements:
- element.toXml(level + 1, f)
- if self.cdata:
- f.write('\n' + '\t' * (level + 1) + '<![CDATA[')
- for line in self.cdata.splitlines():
- f.write('\n' + '\t' * (level + 2) + line)
- f.write('\n' + '\t' * (level + 1) + ']]>\n')
- if self.text:
- if isinstance(self.text, type('')): # If the text is only text
- f.write(_escape(str(self.text)))
- else: # If the text is a spannedtext class
- f.write(str(self.text))
- if self.elements:
- f.write('\t' * level + '</' + self.type + '>\n')
- elif self.text:
- f.write('</' + self.type + '>\n')
- elif self.cdata:
- f.write('\t' * level + '</' + self.type + '>\n')
- else:
- f.write('/>\n')
-
-
-class tspan(SVGelement):
- """ts=tspan(text='',**args)
-
- a tspan element can be used for applying formatting to a textsection
- usage:
- ts=tspan('this text is bold')
- ts.attributes['font-weight']='bold'
- st=spannedtext()
- st.addtspan(ts)
- t=text(3,5,st)
- """
-
- def __init__(self, text=None, **args):
- SVGelement.__init__(self, 'tspan', **args)
- if self.text != None:
- self.text = text
-
- def __repr__(self):
- s = "<tspan"
- for key, value in list(self.attributes.items()):
- s += ' %s="%s"' % (key, value)
- s += '>'
- s += self.text
- s += '</tspan>'
- return s
-
-
-class tref(SVGelement):
- """tr=tref(link='',**args)
-
- a tref element can be used for referencing text by a link to its id.
- usage:
- tr=tref('#linktotext')
- st=spannedtext()
- st.addtref(tr)
- t=text(3,5,st)
- """
-
- def __init__(self, link, **args):
- SVGelement.__init__(self, 'tref', {'xlink:href': link}, **args)
-
- def __repr__(self):
- s = "<tref"
-
- for key, value in list(self.attributes.items()):
- s += ' %s="%s"' % (key, value)
- s += '/>'
- return s
-
-
-class spannedtext:
- """st=spannedtext(textlist=[])
-
- a spannedtext can be used for text which consists of text, tspan's and tref's
- You can use it to add to a text element or path element. Don't add it directly
- to a svg or a group element.
- usage:
-
- ts=tspan('this text is bold')
- ts.attributes['font-weight']='bold'
- tr=tref('#linktotext')
- tr.attributes['fill']='red'
- st=spannedtext()
- st.addtspan(ts)
- st.addtref(tr)
- st.addtext('This text is not bold')
- t=text(3,5,st)
- """
-
- def __init__(self, textlist=None):
- if textlist == None:
- self.textlist = []
- else:
- self.textlist = textlist
-
- def addtext(self, text=''):
- self.textlist.append(text)
-
- def addtspan(self, tspan):
- self.textlist.append(tspan)
-
- def addtref(self, tref):
- self.textlist.append(tref)
-
- def __repr__(self):
- s = ""
- for element in self.textlist:
- s += str(element)
- return s
-
-
-class rect(SVGelement):
- """r=rect(width,height,x,y,fill,stroke,stroke_width,**args)
-
- a rectangle is defined by a width and height and a xy pair
- """
-
- def __init__(self, x=None, y=None, width=None, height=None, fill=None, stroke=None, stroke_width=None, **args):
- if width == None or height == None:
- raise ValueError('both height and width are required')
-
- SVGelement.__init__(
- self, 'rect', {'width': width, 'height': height}, **args)
- if x != None:
- self.attributes['x'] = x
- if y != None:
- self.attributes['y'] = y
- if fill != None:
- self.attributes['fill'] = fill
- if stroke != None:
- self.attributes['stroke'] = stroke
- if stroke_width != None:
- self.attributes['stroke-width'] = stroke_width
-
-
-class ellipse(SVGelement):
- """e=ellipse(rx,ry,x,y,fill,stroke,stroke_width,**args)
-
- an ellipse is defined as a center and a x and y radius.
- """
-
- def __init__(self, cx=None, cy=None, rx=None, ry=None, fill=None, stroke=None, stroke_width=None, **args):
- if rx == None or ry == None:
- raise ValueError('both rx and ry are required')
-
- SVGelement.__init__(self, 'ellipse', {'rx': rx, 'ry': ry}, **args)
- if cx != None:
- self.attributes['cx'] = cx
- if cy != None:
- self.attributes['cy'] = cy
- if fill != None:
- self.attributes['fill'] = fill
- if stroke != None:
- self.attributes['stroke'] = stroke
- if stroke_width != None:
- self.attributes['stroke-width'] = stroke_width
-
-
-class circle(SVGelement):
- """c=circle(x,y,radius,fill,stroke,stroke_width,**args)
-
- The circle creates an element using a x, y and radius values eg
- """
-
- def __init__(self, cx=None, cy=None, r=None, fill=None, stroke=None, stroke_width=None, **args):
- if r == None:
- raise ValueError('r is required')
- SVGelement.__init__(self, 'circle', {'r': r}, **args)
- if cx != None:
- self.attributes['cx'] = cx
- if cy != None:
- self.attributes['cy'] = cy
- if fill != None:
- self.attributes['fill'] = fill
- if stroke != None:
- self.attributes['stroke'] = stroke
- if stroke_width != None:
- self.attributes['stroke-width'] = stroke_width
-
-
-class point(circle):
- """p=point(x,y,color)
-
- A point is defined as a circle with a size 1 radius. It may be more efficient to use a
- very small rectangle if you use many points because a circle is difficult to render.
- """
-
- def __init__(self, x, y, fill='black', **args):
- circle.__init__(self, x, y, 1, fill, **args)
-
-
-class line(SVGelement):
- """l=line(x1,y1,x2,y2,stroke,stroke_width,**args)
-
- A line is defined by a begin x,y pair and an end x,y pair
- """
-
- def __init__(self, x1=None, y1=None, x2=None, y2=None, stroke=None, stroke_width=None, **args):
- SVGelement.__init__(self, 'line', **args)
- if x1 != None:
- self.attributes['x1'] = x1
- if y1 != None:
- self.attributes['y1'] = y1
- if x2 != None:
- self.attributes['x2'] = x2
- if y2 != None:
- self.attributes['y2'] = y2
- if stroke_width != None:
- self.attributes['stroke-width'] = stroke_width
- if stroke != None:
- self.attributes['stroke'] = stroke
-
-
-class polyline(SVGelement):
- """pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args)
-
- a polyline is defined by a list of xy pairs
- """
-
- def __init__(self, points, fill=None, stroke=None, stroke_width=None, **args):
- SVGelement.__init__(self, 'polyline', {
- 'points': _xypointlist(points)}, **args)
- if fill != None:
- self.attributes['fill'] = fill
- if stroke_width != None:
- self.attributes['stroke-width'] = stroke_width
- if stroke != None:
- self.attributes['stroke'] = stroke
-
-
-class polygon(SVGelement):
- """pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args)
-
- a polygon is defined by a list of xy pairs
- """
-
- def __init__(self, points, fill=None, stroke=None, stroke_width=None, **args):
- SVGelement.__init__(
- self, 'polygon', {'points': _xypointlist(points)}, **args)
- if fill != None:
- self.attributes['fill'] = fill
- if stroke_width != None:
- self.attributes['stroke-width'] = stroke_width
- if stroke != None:
- self.attributes['stroke'] = stroke
-
-
-class path(SVGelement):
- """p=path(path,fill,stroke,stroke_width,**args)
-
- a path is defined by a path object and optional width, stroke and fillcolor
- """
-
- def __init__(self, pathdata, fill=None, stroke=None, stroke_width=None, id=None, **args):
- SVGelement.__init__(self, 'path', {'d': str(pathdata)}, **args)
- if stroke != None:
- self.attributes['stroke'] = stroke
- if fill != None:
- self.attributes['fill'] = fill
- if stroke_width != None:
- self.attributes['stroke-width'] = stroke_width
- if id != None:
- self.attributes['id'] = id
-
-
-class text(SVGelement):
- """t=text(x,y,text,font_size,font_family,**args)
-
- a text element can bge used for displaying text on the screen
- """
-
- def __init__(self, x=None, y=None, text=None, font_size=None, font_family=None, text_anchor=None, **args):
- SVGelement.__init__(self, 'text', **args)
- if x != None:
- self.attributes['x'] = x
- if y != None:
- self.attributes['y'] = y
- if font_size != None:
- self.attributes['font-size'] = font_size
- if font_family != None:
- self.attributes['font-family'] = font_family
- if text != None:
- self.text = text
- if text_anchor != None:
- self.attributes['text-anchor'] = text_anchor
-
-
-class textpath(SVGelement):
- """tp=textpath(text,link,**args)
-
- a textpath places a text on a path which is referenced by a link.
- """
-
- def __init__(self, link, text=None, **args):
- SVGelement.__init__(self, 'textPath', {'xlink:href': link}, **args)
- if text != None:
- self.text = text
-
-
-class pattern(SVGelement):
- """p=pattern(x,y,width,height,patternUnits,**args)
-
- A pattern is used to fill or stroke an object using a pre-defined
- graphic object which can be replicated ("tiled") at fixed intervals
- in x and y to cover the areas to be painted.
- """
-
- def __init__(self, x=None, y=None, width=None, height=None, patternUnits=None, **args):
- SVGelement.__init__(self, 'pattern', **args)
- if x != None:
- self.attributes['x'] = x
- if y != None:
- self.attributes['y'] = y
- if width != None:
- self.attributes['width'] = width
- if height != None:
- self.attributes['height'] = height
- if patternUnits != None:
- self.attributes['patternUnits'] = patternUnits
-
-
-class title(SVGelement):
- """t=title(text,**args)
-
- a title is a text element. The text is displayed in the title bar
- add at least one to the root svg element
- """
-
- def __init__(self, text=None, **args):
- SVGelement.__init__(self, 'title', **args)
- if text != None:
- self.text = text
-
-
-class description(SVGelement):
- """d=description(text,**args)
-
- a description can be added to any element and is used for a tooltip
- Add this element before adding other elements.
- """
-
- def __init__(self, text=None, **args):
- SVGelement.__init__(self, 'desc', **args)
- if text != None:
- self.text = text
-
-
-class lineargradient(SVGelement):
- """lg=lineargradient(x1,y1,x2,y2,id,**args)
-
- defines a lineargradient using two xy pairs.
- stop elements van be added to define the gradient colors.
- """
-
- def __init__(self, x1=None, y1=None, x2=None, y2=None, id=None, **args):
- SVGelement.__init__(self, 'linearGradient', **args)
- if x1 != None:
- self.attributes['x1'] = x1
- if y1 != None:
- self.attributes['y1'] = y1
- if x2 != None:
- self.attributes['x2'] = x2
- if y2 != None:
- self.attributes['y2'] = y2
- if id != None:
- self.attributes['id'] = id
-
-
-class radialgradient(SVGelement):
- """rg=radialgradient(cx,cy,r,fx,fy,id,**args)
-
- defines a radial gradient using a outer circle which are defined by a cx,cy and r and by using a focalpoint.
- stop elements van be added to define the gradient colors.
- """
-
- def __init__(self, cx=None, cy=None, r=None, fx=None, fy=None, id=None, **args):
- SVGelement.__init__(self, 'radialGradient', **args)
- if cx != None:
- self.attributes['cx'] = cx
- if cy != None:
- self.attributes['cy'] = cy
- if r != None:
- self.attributes['r'] = r
- if fx != None:
- self.attributes['fx'] = fx
- if fy != None:
- self.attributes['fy'] = fy
- if id != None:
- self.attributes['id'] = id
-
-
-class stop(SVGelement):
- """st=stop(offset,stop_color,**args)
-
- Puts a stop color at the specified radius
- """
-
- def __init__(self, offset, stop_color=None, **args):
- SVGelement.__init__(self, 'stop', {'offset': offset}, **args)
- if stop_color != None:
- self.attributes['stop-color'] = stop_color
-
-
-class style(SVGelement):
- """st=style(type,cdata=None,**args)
-
- Add a CDATA element to this element for defing in line stylesheets etc..
- """
-
- def __init__(self, type, cdata=None, **args):
- SVGelement.__init__(self, 'style', {'type': type}, cdata=cdata, **args)
-
-
-class image(SVGelement):
- """im=image(url,width,height,x,y,**args)
-
- adds an image to the drawing. Supported formats are .png, .jpg and .svg.
- """
-
- def __init__(self, url, x=None, y=None, width=None, height=None, **args):
- if width == None or height == None:
- raise ValueError('both height and width are required')
- SVGelement.__init__(
- self, 'image', {'xlink:href': url, 'width': width, 'height': height}, **args)
- if x != None:
- self.attributes['x'] = x
- if y != None:
- self.attributes['y'] = y
-
-
-class cursor(SVGelement):
- """c=cursor(url,**args)
-
- defines a custom cursor for a element or a drawing
- """
-
- def __init__(self, url, **args):
- SVGelement.__init__(self, 'cursor', {'xlink:href': url}, **args)
-
-
-class marker(SVGelement):
- """m=marker(id,viewbox,refX,refY,markerWidth,markerHeight,**args)
-
- defines a marker which can be used as an endpoint for a line or other pathtypes
- add an element to it which should be used as a marker.
- """
-
- def __init__(self, id=None, viewBox=None, refx=None, refy=None, markerWidth=None, markerHeight=None, **args):
- SVGelement.__init__(self, 'marker', **args)
- if id != None:
- self.attributes['id'] = id
- if viewBox != None:
- self.attributes['viewBox'] = _viewboxlist(viewBox)
- if refx != None:
- self.attributes['refX'] = refx
- if refy != None:
- self.attributes['refY'] = refy
- if markerWidth != None:
- self.attributes['markerWidth'] = markerWidth
- if markerHeight != None:
- self.attributes['markerHeight'] = markerHeight
-
-
-class group(SVGelement):
- """g=group(id,**args)
-
- a group is defined by an id and is used to contain elements
- g.addElement(SVGelement)
- """
-
- def __init__(self, id=None, **args):
- SVGelement.__init__(self, 'g', **args)
- if id != None:
- self.attributes['id'] = id
-
-
-class symbol(SVGelement):
- """sy=symbol(id,viewbox,**args)
-
- defines a symbol which can be used on different places in your graph using
- the use element. A symbol is not rendered but you can use 'use' elements to
- display it by referencing its id.
- sy.addElement(SVGelement)
- """
-
- def __init__(self, id=None, viewBox=None, **args):
- SVGelement.__init__(self, 'symbol', **args)
- if id != None:
- self.attributes['id'] = id
- if viewBox != None:
- self.attributes['viewBox'] = _viewboxlist(viewBox)
-
-
-class defs(SVGelement):
- """d=defs(**args)
-
- container for defining elements
- """
-
- def __init__(self, **args):
- SVGelement.__init__(self, 'defs', **args)
-
-
-class switch(SVGelement):
- """sw=switch(**args)
-
- Elements added to a switch element which are "switched" by the attributes
- requiredFeatures, requiredExtensions and systemLanguage.
- Refer to the SVG specification for details.
- """
-
- def __init__(self, **args):
- SVGelement.__init__(self, 'switch', **args)
-
-
-class use(SVGelement):
- """u=use(link,x,y,width,height,**args)
-
- references a symbol by linking to its id and its position, height and width
- """
-
- def __init__(self, link, x=None, y=None, width=None, height=None, **args):
- SVGelement.__init__(self, 'use', {'xlink:href': link}, **args)
- if x != None:
- self.attributes['x'] = x
- if y != None:
- self.attributes['y'] = y
-
- if width != None:
- self.attributes['width'] = width
- if height != None:
- self.attributes['height'] = height
-
-
-class link(SVGelement):
- """a=link(url,**args)
-
- a link is defined by a hyperlink. add elements which have to be linked
- a.addElement(SVGelement)
- """
-
- def __init__(self, link='', **args):
- SVGelement.__init__(self, 'a', {'xlink:href': link}, **args)
-
-
-class view(SVGelement):
- """v=view(id,**args)
-
- a view can be used to create a view with different attributes"""
-
- def __init__(self, id=None, **args):
- SVGelement.__init__(self, 'view', **args)
- if id != None:
- self.attributes['id'] = id
-
-
-class script(SVGelement):
- """sc=script(type,type,cdata,**args)
-
- adds a script element which contains CDATA to the SVG drawing
-
- """
-
- def __init__(self, type, cdata=None, **args):
- SVGelement.__init__(
- self, 'script', {'type': type}, cdata=cdata, **args)
-
-
-class animate(SVGelement):
- """an=animate(attribute,from,to,during,**args)
-
- animates an attribute.
- """
-
- def __init__(self, attribute, fr=None, to=None, dur=None, **args):
- SVGelement.__init__(
- self, 'animate', {'attributeName': attribute}, **args)
- if fr != None:
- self.attributes['from'] = fr
- if to != None:
- self.attributes['to'] = to
- if dur != None:
- self.attributes['dur'] = dur
-
-
-class animateMotion(SVGelement):
- """an=animateMotion(pathdata,dur,**args)
-
- animates a SVGelement over the given path in dur seconds
- """
-
- def __init__(self, pathdata, dur, **args):
- SVGelement.__init__(self, 'animateMotion', **args)
- if pathdata != None:
- self.attributes['path'] = str(pathdata)
- if dur != None:
- self.attributes['dur'] = dur
-
-
-class animateTransform(SVGelement):
- """antr=animateTransform(type,from,to,dur,**args)
-
- transform an element from and to a value.
- """
-
- def __init__(self, type=None, fr=None, to=None, dur=None, **args):
- SVGelement.__init__(self, 'animateTransform', {
- 'attributeName': 'transform'}, **args)
- # As far as I know the attributeName is always transform
- if type != None:
- self.attributes['type'] = type
- if fr != None:
- self.attributes['from'] = fr
- if to != None:
- self.attributes['to'] = to
- if dur != None:
- self.attributes['dur'] = dur
-
-
-class animateColor(SVGelement):
- """ac=animateColor(attribute,type,from,to,dur,**args)
-
- Animates the color of a element
- """
-
- def __init__(self, attribute, type=None, fr=None, to=None, dur=None, **args):
- SVGelement.__init__(self, 'animateColor', {
- 'attributeName': attribute}, **args)
- if type != None:
- self.attributes['type'] = type
- if fr != None:
- self.attributes['from'] = fr
- if to != None:
- self.attributes['to'] = to
- if dur != None:
- self.attributes['dur'] = dur
-
-
-class set(SVGelement):
- """st=set(attribute,to,during,**args)
-
- sets an attribute to a value for a
- """
-
- def __init__(self, attribute, to=None, dur=None, **args):
- SVGelement.__init__(self, 'set', {'attributeName': attribute}, **args)
- if to != None:
- self.attributes['to'] = to
- if dur != None:
- self.attributes['dur'] = dur
-
-
-class svg(SVGelement):
- """s=svg(viewbox,width,height,**args)
-
- a svg or element is the root of a drawing add all elements to a svg element.
- You can have different svg elements in one svg file
- s.addElement(SVGelement)
-
- eg
- d=drawing()
- s=svg((0,0,100,100),'100%','100%')
- c=circle(50,50,20)
- s.addElement(c)
- d.setSVG(s)
- d.toXml()
- """
-
- def __init__(self, viewBox=None, width=None, height=None, **args):
- SVGelement.__init__(self, 'svg', **args)
- if viewBox != None:
- self.attributes['viewBox'] = _viewboxlist(viewBox)
- if width != None:
- self.attributes['width'] = width
- if height != None:
- self.attributes['height'] = height
- self.namespace = "http://www.w3.org/2000/svg"
-
-
-class drawing:
- """d=drawing()
-
- this is the actual SVG document. It needs a svg element as a root.
- Use the addSVG method to set the svg to the root. Use the toXml method to write the SVG
- source to the screen or to a file
- d=drawing()
- d.addSVG(svg)
- d.toXml(optionalfilename)
- """
-
- def __init__(self, entity={}):
- self.svg = None
- self.entity = entity
-
- def setSVG(self, svg):
- self.svg = svg
- # Voeg een element toe aan de grafiek toe.
- if use_dom_implementation == 0:
- def toXml(self, filename='', compress=False):
- import io
- xml = io.StringIO()
- xml.write("<?xml version='1.0' encoding='UTF-8'?>\n")
- xml.write(
- "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"")
- if self.entity:
- xml.write(" [\n")
- for item in list(self.entity.keys()):
- xml.write("<!ENTITY %s \"%s\">\n" %
- (item, self.entity[item]))
- xml.write("]")
- xml.write(">\n")
- self.svg.toXml(0, xml)
- if not filename:
- if compress:
- import gzip
- f = io.StringIO()
- zf = gzip.GzipFile(fileobj=f, mode='wb')
- zf.write(xml.getvalue())
- zf.close()
- f.seek(0)
- return f.read()
- else:
- return xml.getvalue()
- else:
- if filename[-4:] == 'svgz':
- import gzip
- f = gzip.GzipFile(filename=filename,
- mode="wb", compresslevel=9)
- f.write(xml.getvalue())
- f.close()
- else:
- f = file(filename, 'w')
- f.write(xml.getvalue())
- f.close()
-
- else:
- def toXml(self, filename='', compress=False):
- """drawing.toXml() ---->to the screen
- drawing.toXml(filename)---->to the file
- writes a svg drawing to the screen or to a file
- compresses if filename ends with svgz or if compress is true
- """
- doctype = implementation.createDocumentType(
- 'svg', "-//W3C//DTD SVG 1.0//EN""", 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd ')
-
- global root
- # root is defined global so it can be used by the appender. Its also possible to use it as an arugument but
- # that is a bit messy.
- root = implementation.createDocument(None, None, doctype)
- # Create the xml document.
- global appender
-
- def appender(element, elementroot):
- """This recursive function appends elements to an element and sets the attributes
- and type. It stops when alle elements have been appended"""
- if element.namespace:
- e = root.createElementNS(element.namespace, element.type)
- else:
- e = root.createElement(element.type)
- if element.text:
- textnode = root.createTextNode(element.text)
- e.appendChild(textnode)
- # in element.attributes is supported from python 2.2
- for attribute in list(element.attributes.keys()):
- e.setAttribute(attribute, str(
- element.attributes[attribute]))
- if element.elements:
- for el in element.elements:
- e = appender(el, e)
- elementroot.appendChild(e)
- return elementroot
- root = appender(self.svg, root)
- if not filename:
- import io
- xml = io.StringIO()
- PrettyPrint(root, xml)
- if compress:
- import gzip
- f = io.StringIO()
- zf = gzip.GzipFile(fileobj=f, mode='wb')
- zf.write(xml.getvalue())
- zf.close()
- f.seek(0)
- return f.read()
- else:
- return xml.getvalue()
- else:
- try:
- if filename[-4:] == 'svgz':
- import gzip
- import io
- xml = io.StringIO()
- PrettyPrint(root, xml)
- f = gzip.GzipFile(filename=filename,
- mode='wb', compresslevel=9)
- f.write(xml.getvalue())
- f.close()
- else:
- f = open(filename, 'w')
- PrettyPrint(root, f)
- f.close()
- except:
- print(("Cannot write SVG file: " + filename))
-
- def validate(self):
- try:
- import xml.parsers.xmlproc.xmlval
- except:
- raise exceptions.ImportError(
- 'PyXml is required for validating SVG')
- svg = self.toXml()
- xv = xml.parsers.xmlproc.xmlval.XMLValidator()
- try:
- xv.feed(svg)
- except:
- raise Exception("SVG is not well formed, see messages above")
- else:
- print("SVG well formed")
-
-
-if __name__ == '__main__':
-
- d = drawing()
- s = svg((0, 0, 100, 100))
- r = rect(-100, -100, 300, 300, 'cyan')
- s.addElement(r)
-
- t = title('SVGdraw Demo')
- s.addElement(t)
- g = group('animations')
- e = ellipse(0, 0, 5, 2)
- g.addElement(e)
- c = circle(0, 0, 1, 'red')
- g.addElement(c)
- pd = pathdata(0, -10)
- for i in range(6):
- pd.relsmbezier(10, 5, 0, 10)
- pd.relsmbezier(-10, 5, 0, 10)
- an = animateMotion(pd, 10)
- an.attributes['rotate'] = 'auto-reverse'
- an.attributes['repeatCount'] = "indefinite"
- g.addElement(an)
- s.addElement(g)
- for i in range(20, 120, 20):
- u = use('#animations', i, 0)
- s.addElement(u)
- for i in range(0, 120, 20):
- for j in range(5, 105, 10):
- c = circle(i, j, 1, 'red', 'black', .5)
- s.addElement(c)
- d.setSVG(s)
-
- print((d.toXml()))