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