Programmatically generate SVG (vector) images, animations, and interactive Jupyter widgets

Add ability to specify extra arguments to the <svg> node in Drawing

Changed files
+15 -10
+5 -3
drawing.py
···
Supports iPython: If a Drawing is the last line of a cell, it will be
displayed as an SVG below. '''
-
def __init__(self, width, height, origin=(0,0)):
+
def __init__(self, width, height, origin=(0,0), **svgArgs):
assert float(width) == width
assert float(height) == height
self.width = width
···
self.pixelScale = 1
self.renderWidth = None
self.renderHeight = None
+
self.svgArgs = svgArgs
def setRenderSize(self, w=None, h=None):
self.renderWidth = w
self.renderHeight = h
···
imgWidth, imgHeight = self.calcRenderSize()
startStr = '''<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
-
width="{}" height="{}" viewBox="{} {} {} {}">'''.format(
+
width="{}" height="{}" viewBox="{} {} {} {}"'''.format(
imgWidth, imgHeight, *self.viewBox)
endStr = '</svg>'
outputFile.write(startStr)
-
outputFile.write('\n<defs>\n')
+
elementsModule.writeXmlNodeArgs(self.svgArgs, outputFile)
+
outputFile.write('>\n<defs>\n')
# Write definition elements
idIndex = 0
def idGen(base='d'):
+10 -7
elements.py
···
# TODO: Support drawing ellipses without manually using Path
+
def writeXmlNodeArgs(args, outputFile):
+
for k, v in args.items():
+
if v is None: continue
+
k = k.replace('__', ':')
+
k = k.replace('_', '-')
+
if isinstance(v, defs.DrawingDef):
+
v = 'url(#{})'.format(v.id)
+
outputFile.write(' {}="{}"'.format(k,v))
+
class DrawingElement:
''' Base class for drawing elements
···
def writeSvgElement(self, outputFile):
outputFile.write('<')
outputFile.write(self.TAG_NAME)
-
for k, v in self.args.items():
-
if v is None: continue
-
k = k.replace('__', ':')
-
k = k.replace('_', '-')
-
if isinstance(v, defs.DrawingDef):
-
v = 'url(#{})'.format(v.id)
-
outputFile.write(' {}="{}"'.format(k,v))
+
writeXmlNodeArgs(self.args, outputFile)
if not self.hasContent:
outputFile.write(' />')
else: