Applied upstream as r3028 r3025 r3024
[PyX/mjg.git] / test / experimental / genealogy.py
blob2e55138983a86397160e7be247135711cd80df6b
1 import sys; sys.path.insert(0, "../..")
2 from pyx import *
4 def bracepath(w1, w2, h=0.1, slant=0.1):
5 p1 = path.path(path.moveto(-w1, -h),
6 path.lineto(-w1+slant, 0),
7 path.lineto(-slant, 0),
8 path.lineto(0, h))
9 p2 = path.path(path.moveto(0, h),
10 path.lineto(slant, 0),
11 path.lineto(w2-slant, 0),
12 path.lineto(w2, -h))
13 p1 = deformer.smoothed(10*h).deform(p1)
14 p2 = deformer.smoothed(10*h).deform(p2)
15 p = p1 << p2
16 p = deformer.smoothed(0.1*h).deform(p)
17 return p.split([0.05, p.end()-0.05])[1]
19 def brace(c, x, y, w1, w2):
20 # This is a well known trick to draw a line with an eliptic pen.
21 # you just stroke the path with a circular pen and transform the
22 # result. Since we only do a horizontal scaling here, the widths
23 # w1 and w2 don't need to be adjusted.
24 sc = canvas.canvas([trafo.translate(x, y), trafo.scale(1, 2)])
25 c.insert(sc)
26 sc.stroke(bracepath(w1, w2), [style.linecap.round])
28 linespacing = 1.4*text.text(0, 0, "X").height
30 class person(canvas.canvas):
32 def __init__(self, lines, childs=[],
33 distance=0.5, relpos=0.5):
34 canvas.canvas.__init__(self)
35 self.width = 0
36 y = 0
37 for line in lines:
38 t = text.text(0, y, line, [text.halign.center])
39 if t.width > self.width:
40 self.width = t.width
41 self.insert(t)
42 y -= linespacing
43 if childs:
44 width = sum([child.width for child in childs], 0)
45 width += distance*(len(childs)-1)
46 brace(self, 0, y, relpos*width, (1-relpos)*width)
47 x = -relpos*width
48 for child in childs:
49 x += 0.5*child.width
50 self.insert(child, [trafo.translate(x, y-2*linespacing)])
51 x += 0.5*child.width + distance
53 p = person([r"Otto III.", r"* 1215 -- $\dagger$ 1267"],
54 [person(["Johann III."]),
55 person(["Otto V. der Lange"],
56 [person(["Otto"]),
57 person(["Albrecht"]),
58 person(["Hermann"]),
59 person(["Beatrix", "etc."])],
60 relpos=0.8),
61 person(["Albrecht III."],
62 [person(["Otto"]),
63 person(["Johann"]),
64 person(["Beatrix"]),
65 person(["Margarette"])],
66 relpos=0.2),
67 person(["Otto IV. der Kleine"]),
68 person(["Kunigunde"])])
69 p.writeEPSfile("genealogy")