1
2
3
4
5
6
7 """ functionality for drawing hierarchical catalogs on sping
8 canvases
9
10 """
11 from sping import pid as piddle
12
14 circRad = 10
15 minCircRad = 4
16 maxCircRad = 16
17 circColor = piddle.Color(0.6,0.6,0.9)
18 terminalEmptyColor = piddle.Color(.8,.8,.2)
19 terminalOnColor = piddle.Color(0.8,0.8,0.8)
20 terminalOffColor = piddle.Color(0.2,0.2,0.2)
21 outlineColor = piddle.transparent
22 lineColor = piddle.Color(0,0,0)
23 lineWidth = 1
24 horizOffset = 5
25 vertOffset = 75
26 topMargin = 20
27 labelFont = piddle.Font(face='helvetica',size=10)
28 highlightColor = piddle.Color(1.,1.,.4)
29 highlightWidth = 2
30
31 visOpts = VisOpts()
32
42
43 -def DrawHierarchy(adjList,levelList,canvas,entryColors=None,
44 bitIds=None,minLevel=-1,maxLevel=1e8):
45 """
46
47 Arguments:
48
49 - adjList: adjacency list representation of the hierarchy to be drawn
50
51 - levelList: dictionary mapping level -> list of ids
52
53 """
54 if bitIds is None:
55 bitIds = []
56 if entryColors is None:
57 entryColors = {}
58
59 levelLengths = levelList.keys()
60 levelLengths.sort()
61 minLevel = max(minLevel,levelLengths[0])
62 maxLevel = min(maxLevel,levelLengths[-1])
63
64 dims = canvas.size
65 drawLocs = {}
66
67 for levelLen in range(maxLevel,minLevel-1,-1):
68 nLevelsDown = levelLen-minLevel
69 pos = [0,visOpts.vertOffset*nLevelsDown+visOpts.topMargin]
70
71 ids = levelList.get(levelLen,[])
72
73
74 nHere = len(ids)
75 canvas.defaultFont=visOpts.labelFont
76 if nHere:
77
78 spacePerNode = float(dims[0]) / nHere
79 spacePerNode -= visOpts.horizOffset
80 nodeRad = max(spacePerNode/2,visOpts.minCircRad)
81 nodeRad = min(nodeRad,visOpts.maxCircRad)
82 spacePerNode = nodeRad*2+visOpts.horizOffset
83
84 pos[0] = dims[0]/2.
85
86 if nHere%2:
87 pos[0] -= spacePerNode/2
88
89
90 pos[0] -= (nHere // 2 - .5) * spacePerNode
91
92
93 for id in ids:
94 if not bitIds or id in bitIds:
95
96 if levelLen != maxLevel:
97 for neighbor in adjList[id]:
98 if drawLocs.has_key(neighbor):
99 p2 = drawLocs[neighbor][0]
100 canvas.drawLine(pos[0],pos[1],p2[0],p2[1],
101 visOpts.lineColor,visOpts.lineWidth)
102 drawLocs[id] = tuple(pos),nodeRad
103 pos[0] += spacePerNode
104
105 for id in drawLocs.keys():
106 pos,nodeRad = drawLocs[id]
107 x1,y1 = pos[0]-nodeRad,pos[1]-nodeRad
108 x2,y2 = pos[0]+nodeRad,pos[1]+nodeRad
109 drawColor = entryColors.get(id,visOpts.circColor)
110 canvas.drawEllipse(x1,y1,x2,y2,visOpts.outlineColor,
111 0,drawColor)
112 label = str(id)
113
114
115 txtLoc = ( pos[0]+canvas.fontHeight()/4,
116 pos[1]+canvas.stringWidth(label)/2)
117 canvas.drawString(label,txtLoc[0],txtLoc[1],angle=90)
118
119 return drawLocs
120