From 846d5504e076dc6cf698a998447a7d66cbf006c4 Mon Sep 17 00:00:00 2001 From: Acribbs Date: Thu, 4 Apr 2024 14:32:56 +0100 Subject: [PATCH] removed SCGdraw --- cgat/SVGdraw.py | 1155 ----------------------------------------------- 1 file changed, 1155 deletions(-) delete mode 100644 cgat/SVGdraw.py diff --git a/cgat/SVGdraw.py b/cgat/SVGdraw.py deleted file mode 100644 index aee891935..000000000 --- a/cgat/SVGdraw.py +++ /dev/null @@ -1,1155 +0,0 @@ -''' -SVGdraw.py - generate SVG drawings -====================================================== - -:Tags: Python - -This module has been copied from 3rd party resources. - -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 -''' - -from io import StringIO -import sys - -__version__ = "1.0" - -use_dom_implementation = 0 - -if use_dom_implementation != 0: - try: - from xml.dom import implementation - from xml.dom.ext import PrettyPrint - except: - raise ImportError("PyXML is required for using the dom implementation") - - -sys.setrecursionlimit = 50 - - -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("&", "&") - data = data.replace("<", "<") - data = data.replace(">", ">") - 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('"', """) - 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 is None: - self.attributes = {} - else: - self.attributes = attributes - if elements is None: - self.elements = [] - else: - self.elements = elements - self.text = text - self.namespace = namespace - self.cdata = cdata - for arg in list(args.keys()): - self.attributes[arg] = 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)) + '" ') - # added by Andreas Heger - f.write( - ' xmlns:xlink="' + _escape(str("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) + '\n') - if self.text: - if isinstance(self.text, str): # 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 + '\n') - elif self.text: - f.write('\n') - elif self.cdata: - f.write('\t' * level + '\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 is not None: - self.text = text - - def __repr__(self): - s = "\n") - xml.write( - "\n") - self.svg.toXml(0, xml) - if not filename: - if compress: - import gzip - f = 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: - xml = StringIO() - PrettyPrint(root, xml) - if compress: - import gzip - f = 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 - xml = 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 ImportError('PyXml is required for validating SVG') - svg = self.toXml() - xv = xml.parsers.xmlproc.xmlval.XMLValidator() - try: - xv.feed(svg) - except: - raise ValueError("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())