Projects/laydi
Projects
/
laydi
Archived
7
0
Fork 0

Changed generic observer pattern and project dependency in plots to be a two-way selection-listener model.

The project listens to selections done in plot and broadcasts it back to all plots (including source) which allows them to redraw properly.
This commit is contained in:
Truls Alexander Tangstad 2006-04-27 14:38:48 +00:00
parent c6ef6cdb07
commit 5bb93af6f0
2 changed files with 26 additions and 37 deletions

View File

@ -60,7 +60,7 @@ class Plot (gtk.Frame):
self.sel_obj = None self.sel_obj = None
self.active = False self.active = False
self.title = title self.title = title
self.project = None self.selection_listener = None
def get_title(self): def get_title(self):
return self.title return self.title
@ -76,11 +76,17 @@ class Plot (gtk.Frame):
self.set_shadow_type(gtk.SHADOW_OUT) self.set_shadow_type(gtk.SHADOW_OUT)
self.active = active self.active = active
def update(self, key): def selection_changed(self, selection):
pass pass
def set_project(self, project): def set_selection_listener(self, listener):
self.project = project """Allow project to listen to selections.
The selection will propagate back to all plots through the
selection_changed() method. The listener will be called as
listener(dimension_name, ids).
"""
self.selection_listener = listener
def get_toolbar(self): def get_toolbar(self):
return None return None
@ -365,8 +371,9 @@ class LinePlot(Plot):
silent_eval("k <- sapply(1:length(res), function(id) rev(res[[id]]$y))") silent_eval("k <- sapply(1:length(res), function(id) rev(res[[id]]$y))")
self._bg_matrix = bg_matrix = rpy.r("k") self._bg_matrix = bg_matrix = rpy.r("k")
rpy.r.rm(["k", "res", "m"]) rpy.r.rm(["k", "res", "m"])
self.update(None) # Hack - we draw plot in selection_changed()
self.selection_changed(None)
self.add(self.canvas) self.add(self.canvas)
self.canvas.show() self.canvas.show()
@ -379,15 +386,14 @@ class LinePlot(Plot):
self.canvas.draw() self.canvas.draw()
return self._toolbar return self._toolbar
def update(self, key): def selection_changed(self, selection):
self.ax.clear() self.ax.clear()
rows, cols = self._bg_matrix.shape rows, cols = self._bg_matrix.shape
self.ax.imshow(self._bg_matrix, cmap=cm.Greys, extent=(0.5, cols+0.5, self._ymin, self._ymax)) self.ax.imshow(self._bg_matrix, cmap=cm.Greys, extent=(0.5, cols+0.5, self._ymin, self._ymax))
if self.project: if selection:
curr_sel = self.project.get_selection() # get selection object ids = selection['ids'] # current identifiers
ids = curr_sel['ids'] # current identifiers
index = [ind for id,ind in self._dataset['ids'].items() if id in ids] #conversion to index index = [ind for id,ind in self._dataset['ids'].items() if id in ids] #conversion to index
for i in index: for i in index:
line = self._dataset.get_matrix()[i] line = self._dataset.get_matrix()[i]
@ -457,11 +463,10 @@ class ScatterPlot(Plot):
for ind in index: for ind in index:
ids.append(reverse[ind]) ids.append(reverse[ind])
self.project.set_selection(self.current_dim,ids) self.selection_listener(self.current_dim,ids)
def update(self, key): def selection_changed(self, selection):
curr_sel = self.project.get_selection() # get selection object ids = selection[self.current_dim] # current identifiers
ids = curr_sel[self.current_dim] # current identifiers
index = [ind for id,ind in self.dataset[self.current_dim].items() if id in ids] #conversion to index index = [ind for id,ind in self.dataset[self.current_dim].items() if id in ids] #conversion to index
xdata_new = scipy.take(self.xaxis_data,index) #take data xdata_new = scipy.take(self.xaxis_data,index) #take data

View File

@ -12,35 +12,20 @@ class Project:
self.name = name self.name = name
self.dim_names = [] self.dim_names = []
self._observers = {} self._selection_observers = []
self.current_data = None self.current_data = None
self.datasets = [] self.datasets = []
self.sel_obj = dataset.Selection() self.sel_obj = dataset.Selection()
def attach(self,observer,key): def notify_selection_listeners(self):
"""Attach observer for selection updates"""
if not self._observers.has_key(key):
self._observers[key]=[]
if not observer in self._observers[key]:
self._observers[key].append(observer)
def detach(self,observer,key):
"""Detach observer for selection updates"""
try:
self._observers[key].remove(observer)
except ValueError:
pass
def notify(self,key,modifier=None):
"""Notifies observers""" """Notifies observers"""
for observer in self._observers[key]: for observer in self._selection_observers:
if modifier != observer: observer.selection_changed(self.get_selection())
observer.update(key)
def set_selection(self,dim_name,selection): def set_selection(self,dim_name,selection):
"""Sets a current selection and notify observers""" """Sets a current selection and notify observers"""
self.sel_obj.current_selection[dim_name] = set(selection) self.sel_obj.current_selection[dim_name] = set(selection)
self.notify('selection_update') self.notify_selection_listeners()
def get_selection(self): def get_selection(self):
"""Returns the current selection object""" """Returns the current selection object"""
@ -71,10 +56,9 @@ class Project:
self.add_dataset(d) self.add_dataset(d)
self.data_tree_insert(it, d.get_name(), d) self.data_tree_insert(it, d.get_name(), d)
elif isinstance(d, plots.Plot): elif isinstance(d, plots.Plot):
# self.add_view(d)
self.data_tree_insert(it, d.get_title(), d) self.data_tree_insert(it, d.get_title(), d)
d.set_project(self) d.set_selection_listener(self.set_selection)
self.attach(d, 'selection_update') self._selection_observers.append(d)
def data_tree_insert(self, parent, text, data): def data_tree_insert(self, parent, text, data):
tree = self.data_tree tree = self.data_tree