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

Répondre à