Dear all,
A side on which I think Veusz is weak is data management.
If you import data from many sources, it is then difficult to track down
the relation between the various datasets and effectively visualize and
use it.For example: to distinguish between datasets coming from the same file, one could use the prefix option while importing. This way of working rapidly lose effectiveness when importing many files, each of which generates many datasets. You will end up with a very long list of dataset names, and it may be unpractical to find the one you need to plot. I'm working with multiple files containing 20-100 fields (datasets) each, with long, structured names, and it really gets annoying to scroll down a list of 300 complex datasets names and associating the right two. I attach here a widget which I think could be useful to visualize the relations between datasets. Functionality and design are both poor, but I wanted to contribute it so someone may have ideas and better focus the problem. Also, I really don't know where it could be integrated in Veusz as I'm quite a novice and I'm beginning to understand now its internals. In my implementation I show it as a dock widget (screenshot). I added some example actions to the files and datasets (reload, close, edit, etc). I think something like that could be showed as an alternative way of choosing a dataset instead of using the current combobox selector. Something similar the label editing widget, which has a "..." button on the right that let you enter the text in a more comfortable area. Another useful function would be to display all related datasets in a table, where you can modify them, export them or do further calculations. It would be nice to establish relations between datasets which are not coming from the same file (eg, resulting from some calculation), and to build new relations which could then be displayed as tables. These thoughts and the example widget goes in the direction of adding to Veusz some data management capability, which is also the basis for effective data elaboration. What I'm trying to obtain is something similar to QtiPlot for powerful data management, visualization and elaboration, but with also the power, quality and flexibility of Veusz plotting (where QtiPlot is terribily limited by the qwtplot libraries). Any comment? Best regards, -- Daniele Paganelli Researcher Expert System Solutions S.r.l. Via Virgilio 58/L - 41100 Modena (ITALY) Tel: +39 0598860020 - Fax: +39 0598860024 Email: [email protected] Web: www.expertsystemsolutions.it
<<attachment: Schermata-Untitled - Veusz.png>>
# -*- coding: utf-8 -*-
class DatasetRelationModel(QtCore.QAbstractItemModel):
def __init__(self, doc):
QtCore.QAbstractItemModel.__init__(self)
self.relations={}
self.heads=[]
self.header=['Title', 'Prefix/Len']
self.root='root'
self.doc=doc
self.connect( doc, qt4.SIGNAL("sigModified"), self.refresh)
self.refresh()
def refresh(self):
rel={'unlinked':[]}
for ds in self.doc.data.itervalues():
if ds.linked:
if not rel.has_key(ds.linked): rel[ds.linked]=[]
rel[ds.linked].append(ds)
else:
rel['unlinked'].append(ds)
self.relations=rel
self.heads=rel.keys()
self.emit(QtCore.SIGNAL('modelReset()'))
def nodeFromIndex(self, index):
if index.isValid(): return index.internalPointer()
else: return self.root
def rowCount(self, parent):
node=self.nodeFromIndex(parent)
rc=0
if node==self.root: # List of opened files
rc=len(self.heads)
elif node in self.heads:
rc=len(self.relations[node]) # List of datasets from file
return rc
def columnCount(self, parent):
parent=self.nodeFromIndex(parent)
if parent==self.root or parent in self.heads:
return len(self.header)
return 1
def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if orientation!=QtCore.Qt.Horizontal:
return
if role==QtCore.Qt.DisplayRole:
return QtCore.QVariant(self.header[section])
def data(self, index, role=QtCore.Qt.DisplayRole):
col=index.column()
row=index.row()
assert row>=0 and col>=0
void=QtCore.QVariant()
if role not in [Qt.DisplayRole, 'data']: return void
node=self.nodeFromIndex(index)
if role=='data': return node
if node in self.heads:
assert node == self.heads[row], 'Incongruent node position'
if node=='unlinked': return QtCore.QVariant('/')
if col==0: return QtCore.QVariant(os.path.basename(node.filename))
elif col==1: return QtCore.QVariant(node.prefix)
else: return void
if getattr(node, 'datatype', False):
if col==0:
return QtCore.QVariant(node.document.datasetName(node))
elif col==1:
return QtCore.QVariant(len(node))
return void
def index(self, row, column, parent):
parent=self.nodeFromIndex(parent)
child=None
assert row>=0
if parent in self.heads:
assert row<len(self.relations[parent])
child=self.relations[parent][row]
elif parent==self.root:
assert row<len(self.heads)
child=self.heads[row]
assert child is not None
return self.createIndex(row, column, child)
def parent(self, child):
row, col, parent=0, 0, None
child=self.nodeFromIndex(child)
if getattr(child, 'datatype', False):
if child.linked:
row=self.relations[child.linked].index(child)
parent=child.linked
else:
row=self.relations['unlinked'].index(child)
parent='unlinked'
return self.createIndex(row, col, parent)
else:
return QtCore.QModelIndex()
class DatasetsNavigator(QtGui.QTreeView):
"""List of currently opened Misura4 Tests and reference to datasets names"""
def __init__(self, doc, parent=None):
QtGui.QTreeView.__init__(self, parent)
self.doc=doc
self.setModel(DatasetRelationModel(doc))
self.selection=QtGui.QItemSelectionModel(self.model())
self.setSelectionBehavior(QtGui.QTreeView.SelectItems)
self.setUniformRowHeights(True)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.connect(self, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.showContextMenu)
self.file_menu=QtGui.QMenu(self)
self.file_menu.addAction('Table View', self.viewFile)
self.file_menu.addAction('Reload', self.reload)
self.file_menu.addAction('Close', self.closeFile)
self.dataset_menu=QtGui.QMenu(self)
self.dataset_menu.addAction('Edit', self.editData)
self.dataset_menu.addAction('Delete', self.deleteData)
def showContextMenu(self, pt):
menu=False
node=self.model().data(self.currentIndex(), role='data')
if node in self.model().heads:
menu=self.file_menu
else:
menu=self.dataset_menu
assert menu
menu.popup(self.mapToGlobal(pt))
def refresh(self):
self.model().refresh()
def viewFile(self):
node=self.model().data(self.currentIndex(), role='data')
# Tabular view of data?
def reload(self):
node=self.model().data(self.currentIndex(), role='data')
node.reloadLinks()
def closeFile(self):
node=self.model().data(self.currentIndex(), role='data')
for ds in self.model().relations[node]:
self.doc.deleteDataset(self.doc.datasetName(ds))
self.refresh()
def editData(self):
pass
# Redirect to dataset edit window?
def deleteData(self):
node=self.model().data(self.currentIndex(), role='data')
self.doc.deleteDataset(self.doc.datasetName(ds))
_______________________________________________ Veusz-discuss mailing list [email protected] https://mail.gna.org/listinfo/veusz-discuss
