1 import math
2
3 from obitools.svg import Scene,Circle,Line,Rectangle,Text
4 from obitools.tree import Tree
5
7 '''
8 Convert a tree layout object in an svg file.
9
10 @param layout: the tree layout object
11 @type layout: obitools.tree.layout.TreeLayout
12 @param width: svg document width
13 @type width: int
14 @param height: svg document height
15 @type height: int
16 @param radius: default radius of node in svg unit (default 3)
17 @type radius: int
18 @param scale: scale factor applied to the svg coordinates (default 1.0)
19 @type scale: float
20
21 @return: str containing svg code
22 '''
23 xmin = min(layout.getAttribute(n,'x') for n in layout)
24 xmax = max(layout.getAttribute(n,'x') for n in layout)
25 ymin = min(layout.getAttribute(n,'y') for n in layout)
26 ymax = max(layout.getAttribute(n,'y') for n in layout)
27
28 dx = xmax - xmin
29 dy = ymax - ymin
30
31 xscale = width * 0.95 / dx * scale
32 yscale = height * 0.95 / dy * scale
33
34 def X(x):
35 return (x - xmin ) * xscale + width * 0.025
36
37 def Y(y):
38 return (y - ymin ) * yscale + height * 0.025
39
40 scene = Scene('unrooted', height, width)
41
42 for n in layout:
43 if n._parent is not None:
44 parent = n._parent
45 xf = layout.getAttribute(n,'x')
46 yf = layout.getAttribute(n,'y')
47 xp = layout.getAttribute(parent,'x')
48 yp = layout.getAttribute(parent,'y')
49 scene.add(Line((X(xf),Y(yf)),(X(xp),Y(yp))))
50
51 for n in layout:
52 xf = layout.getAttribute(n,'x')
53 yf = layout.getAttribute(n,'y')
54 cf = layout.getAttribute(n,'color')
55 sf = layout.getAttribute(n,'shape')
56 if layout.hasAttribute(n,'radius'):
57 rf=layout.getAttribute(n,'radius')
58 else:
59 rf=radius
60
61 if sf=='circle':
62 scene.add(Circle((X(xf),Y(yf)),rf,cf))
63 else:
64 scene.add(Rectangle((X(xf)-rf,Y(yf)-rf),2*rf,2*rf,cf))
65
66
67 return ''.join(scene.strarray())
68