Package rdkit :: Package DataStructs :: Module HierarchyVis
[hide private]
[frames] | no frames]

Source Code for Module rdkit.DataStructs.HierarchyVis

  1  # $Id$ 
  2  # 
  3  #  Copyright (C)2003-2006  Rational Discovery LLC 
  4  # 
  5  #   @@ All Rights Reserved @@ 
  6  #  This file is part of the RDKit. 
  7  #  The contents are covered by the terms of the BSD license 
  8  #  which is included in the file license.txt, found at the root 
  9  #  of the RDKit source tree. 
 10  # 
 11  """ functionality for drawing hierarchical catalogs on sping 
 12      canvases 
 13   
 14  """ 
 15  from sping import pid as piddle 
 16   
 17   
18 -class VisOpts(object):
19 circRad = 10 20 minCircRad = 4 21 maxCircRad = 16 22 circColor = piddle.Color(0.6, 0.6, 0.9) 23 terminalEmptyColor = piddle.Color(.8, .8, .2) 24 terminalOnColor = piddle.Color(0.8, 0.8, 0.8) 25 terminalOffColor = piddle.Color(0.2, 0.2, 0.2) 26 outlineColor = piddle.transparent 27 lineColor = piddle.Color(0, 0, 0) 28 lineWidth = 1 29 horizOffset = 5 30 vertOffset = 75 31 topMargin = 20 32 labelFont = piddle.Font(face='helvetica', size=10) 33 highlightColor = piddle.Color(1., 1., .4) 34 highlightWidth = 2
35 36 37 visOpts = VisOpts() 38 39
40 -def GetMinCanvasSize(adjList, levelList):
41 maxAcross = -1 42 for k in levelList.keys(): 43 nHere = len(levelList[k]) 44 maxAcross = max(maxAcross, nHere) 45 nLevs = len(levelList.keys()) 46 minSize = (maxAcross * (visOpts.minCircRad * 2 + visOpts.horizOffset), 47 visOpts.topMargin + nLevs * visOpts.vertOffset) 48 return minSize
49 50
51 -def DrawHierarchy(adjList, levelList, canvas, entryColors=None, bitIds=None, minLevel=-1, 52 maxLevel=1e8):
53 """ 54 55 Arguments: 56 57 - adjList: adjacency list representation of the hierarchy to be drawn 58 59 - levelList: dictionary mapping level -> list of ids 60 61 """ 62 if bitIds is None: 63 bitIds = [] 64 if entryColors is None: 65 entryColors = {} 66 67 levelLengths = levelList.keys() 68 levelLengths.sort() 69 minLevel = max(minLevel, levelLengths[0]) 70 maxLevel = min(maxLevel, levelLengths[-1]) 71 72 dims = canvas.size 73 drawLocs = {} 74 # start at the bottom of the hierarchy and work up: 75 for levelLen in range(maxLevel, minLevel - 1, -1): 76 nLevelsDown = levelLen - minLevel 77 pos = [0, visOpts.vertOffset * nLevelsDown + visOpts.topMargin] 78 79 ids = levelList.get(levelLen, []) 80 81 # FIX: we'll eventually want to figure out some kind of sorting here: 82 nHere = len(ids) 83 canvas.defaultFont = visOpts.labelFont 84 if nHere: 85 # figure the size of each node at this level: 86 spacePerNode = float(dims[0]) / nHere 87 spacePerNode -= visOpts.horizOffset 88 nodeRad = max(spacePerNode / 2, visOpts.minCircRad) 89 nodeRad = min(nodeRad, visOpts.maxCircRad) 90 spacePerNode = nodeRad * 2 + visOpts.horizOffset 91 # start in the midde of the canvas: 92 pos[0] = dims[0] / 2. 93 # maybe we need to offset a little: 94 if nHere % 2: 95 pos[0] -= spacePerNode / 2 96 97 # move to the left by half the number of nodes: 98 pos[0] -= (nHere // 2 - .5) * spacePerNode 99 100 # Find the locations and draw connectors: 101 for ID in ids: 102 if not bitIds or ID in bitIds: 103 # first do lines down to the next level: 104 if levelLen != maxLevel: 105 for neighbor in adjList[ID]: 106 if neighbor in drawLocs: 107 p2 = drawLocs[neighbor][0] 108 canvas.drawLine(pos[0], pos[1], p2[0], p2[1], visOpts.lineColor, visOpts.lineWidth) 109 drawLocs[ID] = tuple(pos), nodeRad 110 pos[0] += spacePerNode 111 112 for ID in drawLocs.keys(): 113 pos, nodeRad = drawLocs[ID] 114 x1, y1 = pos[0] - nodeRad, pos[1] - nodeRad 115 x2, y2 = pos[0] + nodeRad, pos[1] + nodeRad 116 drawColor = entryColors.get(ID, visOpts.circColor) 117 canvas.drawEllipse(x1, y1, x2, y2, visOpts.outlineColor, 0, drawColor) 118 label = str(ID) 119 # txtLoc = ( pos[0]-canvas.stringWidth(label)/2, 120 # pos[1]+canvas.fontHeight()/4 ) 121 txtLoc = (pos[0] + canvas.fontHeight() / 4, pos[1] + canvas.stringWidth(label) / 2) 122 canvas.drawString(label, txtLoc[0], txtLoc[1], angle=90) 123 124 return drawLocs
125