1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
'''
Plot graph node types.
All plot graph node types have a parent, primaries and secondaries, corresponding to
"click", "rclick" or "ctr-click" in a user interface.
The graph is directed from parents to (multiple) children.
Descendents also have a data handle instance or list. This facilitates deferred loading
by means of the getdata() data handle method.
'''
class PlotNode(object):
'''
Base class for plot graph nodes.
'''
def __init__(self):
self.parent = None
''' primary node children'''
self.primaries = []
''' alternative/secondary node children '''
self.secondaries = []
def set_primaries(self, node_lst):
self.primaries = node_lst
for node in node_lst:
node.parent = self
def get_primaries(self):
return self.primaries
def set_secondaries(self, node_lst):
self.secondaries = node_lst
for node in node_lst:
node.parent = self
def get_secondaries(self):
return self.secondaries
def get_parent(self):
return self.parent
def getdata_idx(self, idx):
''' must return a valid data handle index '''
def getdata_lst(self):
''' must return a list '''
def getnumdata(self):
''' must return the number of held data handles '''
class PNMultiple(PlotNode):
'''
A node containing multiple plot instances to be plotted simultaneously.
'''
def __init__(self, data_handle_lst):
self._data_handle_lst = data_handle_lst
super().__init__()
def getdata_idx(self, idx):
return self._data_handle_lst[idx].getdata()
def getdata_lst(self):
return [d.getdata() for d in self._data_handle_lst]
def getnumdata(self):
return len(self._data_handle_lst)
def __str__(self):
return 'PNMultiple'
class PNSingle(PlotNode):
'''
A node containing a data handle instance to be plotted singularly.
'''
def __init__(self, data_handle):
self._data_handle = data_handle
super().__init__()
def getdata_idx(self, idx):
if idx != 0: raise Exception('PNSingle: getdata_idx: idx must be zero.')
return self._data_handle.getdata()
def getdata_lst(self):
return [self._data_handle.getdata()]
def getnumdata(self):
return 1
def __str__(self):
return 'PNSingle'
class DataHandle(object):
'''
Proxy object enabling deferred loading through the use of "getdata".
Do not set the data property explicitly in the constructor unless you have a good reason.
'''
def __init__(self, load_fct, data=None):
self._load_fct = load_fct
self._data = data
def getdata(self):
if not self._data:
self._data = self._load_fct()
return self._data
class PlotGraphPrint(object):
'''
Simple plot graph visualization tool for debugging graph integrity.
NOTE: Iteration logics has not been implemented.
'''
def __init__(self, rootnode, indent_str=' '):
if indent_str == '' or type(indent_str) != str:
raise Exception('PlotGraphPrint: indent_str must be a non-empty string.')
self.indent_str = indent_str
self.root = rootnode
self.printed_ids = []
# execute
self.print_recurse(self.root, level=0)
def print_recurse(self, node, level):
''' node print recursion '''
self.printnode(node, level)
children = node.primaries + node.secondaries
for c in children:
self.print_recurse( c, level+1)
def printnode(self, node, level=0):
'''
Prints the node id, its children id's and data reference, respecting indent and
using self.indent_str.
'''
# only print nodes once
if id(node) in self.printed_ids:
return
indent = self.indent_str
# print the node
print()
print(indent*(level+0) + '%s (%d):' % (node, id(node)))
if node.parent:
print(indent*(level+1) + 'parent:')
print(indent*(level+2) + '%s (%d)' % (node.parent, id(node.parent)))
print(indent*(level+1) + 'data objects:')
for d in node.getdata_lst():
print(indent*(level+2) + '%s (%d)' % (d, id(d)))
if not len(node.primaries) == 0:
print(indent*(level+1) + 'primary children:')
for p in node.primaries:
print(indent*(level+2) + '%s (%d)' % (p, id(p)))
if not len(node.secondaries) == 0:
print(indent*(level+1) + 'secondary children:')
for s in node.secondaries:
print(indent*(level+2) + '%s (%d)' % (s, id(s)))
self.printed_ids.append(id(node))
|