-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy patholvDataTable.py
186 lines (143 loc) · 6.41 KB
/
olvDataTable.py
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import wx
import logging
# from odmtools.common.logger import LoggerTool
from odmtools.lib.ObjectListView import VirtualObjectListView, ObjectListView, ColumnDefn
import pandas as pd
# tool = LoggerTool()
# logger = tool.setupLogger(__name__, __name__ + '.log', 'w', logging.DEBUG)
logger =logging.getLogger('main')
__author__ = 'jmeline'
class OLVDataTable(VirtualObjectListView):
def __init__(self, parent, **kwargs):
VirtualObjectListView.__init__(self, parent, **kwargs)
self.SetEmptyListMsg("No Series Selected for Editing")
self.EnableSorting()
self.sortedColumnIndex = -1
self.currentItem = None
self.dataframe = None
self.annotations = None
self.annotations_grouped = {}
def init(self, memDB):
self.memDB = memDB
self.useAlternateBackColors = True
self.oddRowsBackColor = wx.Colour(191, 217, 217)
self.dataframe = self.memDB.getDataValuesDF()
self.annotations = self.memDB.get_annotations()
sort_by_index = self.dataframe.columns.tolist().index("valuedatetime")
self.dataframe.sort_values(self.dataframe.columns[sort_by_index], inplace=True)
self.annotations_grouped = self.__group_annotations()
self.dataObjects = self.__merge_dataframe_with_annotations()
col = self.memDB.get_columns_with_annotations()
columns = \
[ColumnDefn(x.strip(), align="left", valueGetter=i, minimumWidth=125, width=125,
stringConverter='%Y-%m-%d %H:%M:%S' if "valuedatetime" == x.lower() else '%s')
for x, i in col]
self.SetColumns(columns)
self.SetObjectGetter(self.ObjectGetter)
self.SetItemCount(len(self.dataObjects))
def __merge_dataframe_with_annotations(self):
data_list = self.dataframe.values.tolist()
data = data_list
for key, value in self.annotations_grouped.iteritems():
for i in range(0, len(data_list)):
if key in data[i]:
data[i].append(value)
break
return data
def __group_annotations(self):
"""
Ideally, this method should only be called once. Use self.grouped_annotations after calling this method
:return:
"""
anno_list = self.annotations.values.tolist()
anno = {}
for i in range(0, len(anno_list)):
value_id = anno_list[i][1]
annotation_code = anno_list[i][-1]
if value_id in anno:
anno[value_id].append(annotation_code)
else:
anno[value_id] = [annotation_code]
return anno
def EnableSorting(self):
self.Bind(wx.EVT_LIST_COL_CLICK, self.on_column_selected)
if not self.smallImageList:
self.SetImageLists()
if (not self.smallImageList.HasName(ObjectListView.NAME_DOWN_IMAGE) and
self.smallImageList.GetSize(0) == (16, 16)):
self.RegisterSortIndicators()
def ObjectGetter(self, index):
"""
A Virtual list has to have a callable installed that says which model object is shown
at a given index
"""
return self.dataObjects[index % len(self.dataObjects)]
def on_column_selected(self, event):
"""
Allows users to sort by clicking on columns
"""
if not isinstance(self.dataframe, pd.DataFrame):
return
if self.dataframe.empty:
return
if not len(self.dataObjects):
return
self.sortColumn(event.Column)
def sortColumn(self, selected_column):
self.sortAscending = not self.sortAscending
oldSortColumnIndex = self.sortedColumnIndex
self.sortedColumnIndex = selected_column
self._UpdateColumnSortIndicators(selected_column, oldSortColumnIndex)
if selected_column >= len(self.dataframe.columns):
self.dataObjects = self.sort_columns_by_annotation_code(reverse=self.sortAscending)
else:
self.dataframe.sort_values(self.dataframe.columns[selected_column], ascending=self.sortAscending, inplace=True)
self.dataObjects = self.__merge_dataframe_with_annotations()
if self.GetItemCount():
itemFrom = self.GetTopItem()
itemTo = self.GetTopItem() + 1 + self.GetCountPerPage()
itemTo = min(itemTo, self.GetItemCount() - 1)
self.RefreshItems(itemFrom, itemTo)
def sort_columns_by_annotation_code(self, reverse=False):
rows_with_annotation = []
rows_without_annotation = []
column_number_of_dataframe = len(self.dataframe.columns)
for i in self.dataObjects:
if len(i) > column_number_of_dataframe:
rows_with_annotation.append(i)
else:
rows_without_annotation.append(i)
if reverse:
return rows_without_annotation + rows_with_annotation
else:
return rows_with_annotation + rows_without_annotation
def onItemSelected(self, event):
"""
Disable selecting of an item in the DataTable, only sorting is available
"""
if not self.enableSelectDataTable:
self.SetItemState(event.m_itemIndex, 0, wx.LIST_STATE_SELECTED)
def onDeselectAll(self):
selected_item = self.GetFirstSelected()
while selected_item != -1:
self.SetItemState(selected_item, 0, wx.LIST_STATE_SELECTED)
selected_item = self.GetNextSelected(selected_item)
def _rowFormatter(self, listItem, object):
"""Handles the formatting of rows for object list view
:param: wx.ListCtrl listitem
:param: ModelObject object
:rtype: None
"""
objects = self.GetSelectedObjects()
# if self.currentItem and object in self.currentItem:
if objects and object in objects:
# font type: wx.DEFAULT, wx.DECORATIVE, wx.ROMAN, wx.SCRIPT, wx.SWISS, wx.MODERN
# slant: wx.NORMAL, wx.SLANT or wx.ITALIC
# weight: wx.NORMAL, wx.LIGHT or wx.BOLD
#font1 = wx.Font(10, wx.SWISS, wx.ITALIC, wx.NORMAL)
# use additional fonts this way ...
#font1 = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, False, u'Comic Sans MS')
listItem.SetFont(
wx.Font(9, wx.DECORATIVE, wx.ITALIC, wx.BOLD))
else:
listItem.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL, False, u'Tahoma'))