more work-in-progress for GraphViz and FamilyLines

svn: r9650
This commit is contained in:
Stéphane Charette 2007-12-31 05:43:14 +00:00
parent 8855dd8a43
commit eb9d09aded
3 changed files with 90 additions and 56 deletions

View File

@ -1,3 +1,8 @@
2007-12-30 Stéphane Charette <stephanecharette@gmail.com>
* src/ReportBase/_GraphvizReportDialog.py:
* src/plugins/GVFamilyLines.py: more work-in-progress on GraphViz and
getting FamilyLines to function in the new framework
2007-12-30 Douglas S. Blank <dblank@cs.brynmawr.edu>
* src/Config/_GrampsConfigKeys.py: added MyGrampsView
* src/Config/_GrampsGconfKeys.py: added try/excepts on get_types

View File

@ -207,67 +207,69 @@ class GVDocBase(BaseDoc.BaseDoc,BaseDoc.GVDoc):
self.write( '}' )
def add_node(self, id, label, shape="", color = "",
style="", fillcolor="", url="" ):
def add_node(self, id, label, shape="", color="",
style="", fillcolor="", url="", htmloutput=False ):
"""
Add a node to this graph. Nodes can be different shapes like boxes and
circles.
Implementes BaseDoc.GVDoc.add_node().
Implements BaseDoc.GVDoc.add_node().
"""
line = ' "%s" [' % id
if label.startswith("<"):
# This must be HTML
line += 'label=<%s>' % label
else:
line += 'label="%s"' % label
text = '['
if shape:
line += ', shape="%s"' % shape
text += ' shape="%s"' % shape
if color:
line += ', color="%s"' % color
text += ' color="%s"' % color
if fillcolor:
line += ', fillcolor="%s"' % fillcolor
text += ' fillcolor="%s"' % fillcolor
if style:
line += ', style="%s"' % style
text += ' style="%s"' % style
# note that we always output a label -- even if an empty string --
# otherwise GraphViz uses the node ID as the label which is unlikely
# to be what the user wants to see in the graph
if label.startswith("<") or htmloutput:
text += ' label=<%s>' % label
else:
text += ' label="%s"' % label
if url:
line += ', URL="%s"' % url
text += ' URL="%s"' % url
line += '];\n'
text += " ]"
self.write(' %s %s;\n' % (id, text))
self.write(line)
def add_link(self, id1, id2, style="", head="", tail=""):
def add_link(self, id1, id2, style="", head="", tail="", comment=""):
"""
Add a link between two nodes.
Implementes BaseDoc.GVDoc.add_link().
"""
self.write(' "%s" -> "%s"' % (id1, id2))
self.write(' %s -> %s' % (id1, id2))
if style or head or tail:
self.write(' [')
if style:
self.write('style=%s' % style)
self.write(' style=%s' % style)
if head:
if style:
self.write(', ')
self.write('arrowhead=%s' % head)
self.write(' arrowhead=%s' % head)
if tail:
if style or head:
self.write(', ')
self.write('arrowtail=%s' % tail)
self.write(' arrowtail=%s' % tail)
self.write(']')
self.write(';\n')
self.write(' ]')
self.write(';')
if comment:
self.write(' // %s' % comment)
self.write('\n')
def start_subgraph(self,id):
self.write(' subgraph cluster_%s\n' % id)
self.write(' {\n')

View File

@ -69,14 +69,12 @@ from ReportBase import Report, MenuReportOptions, MODE_GUI, MODE_CLI, CATEGORY_G
from ReportBase._ReportDialog import ReportDialog
from PluginUtils import register_report, FilterListOption, EnumeratedListOption, BooleanOption, NumberOption, ColourButtonOption, PersonListOption
from QuestionDialog import ErrorDialog, WarningDialog
#from NameDisplay import displayer as _nd # Gramps version < 3.0
from BasicUtils import name_displayer as _nd # Gramps version >= 3.0
from BasicUtils import name_displayer as _nd
from DateHandler import displayer as _dd
from DateHandler import parser
from Selectors import selector_factory
#------------------------------------------------------------------------
#
# A quick overview of the classes we'll be using:
@ -111,11 +109,9 @@ class FamilyLinesOptions(MenuReportOptions):
category = _('People of Interest')
# --------------------------------
peoplePicker = PersonListOption( _('People of interest'),
'',
dbstate )
peoplePicker.set_help( _('People of interest are used as a starting point when determining \"family lines\".'))
menu.add_option(category, 'FLgidlist', peoplePicker)
personList = PersonListOption( _('People of interest'), '', dbstate)
personList.set_help( _('People of interest are used as a starting point when determining \"family lines\".'))
menu.add_option(category, 'FLgidlist', personList)
followParents = BooleanOption( _('Follow parents to determine family lines'), True)
followParents.set_help( _('Parents and their ancestors will be considered when determining "family lines".'))
@ -189,6 +185,13 @@ class FamilyLinesOptions(MenuReportOptions):
category = _('Options')
# ---------------------
useSubgraphs = BooleanOption(_('Use subgraphs'), False)
useSubgraphs.set_help(_("Subgraphs can help GraphViz position "
"certain linked nodes closer together, "
"but with non-trivial graphs will result "
"in longer lines and larger graphs."))
menu.add_option(category, "FLuseSubgraphs", useSubgraphs)
includeDates = BooleanOption( _('Include dates'), True)
includeDates.set_help( _('Whether to include dates for people and families.'))
menu.add_option(category, 'FLincludeDates', includeDates)
@ -209,13 +212,6 @@ class FamilyLinesOptions(MenuReportOptions):
includePrivate.set_help( _('Whether to include names, dates, and families that are marked as private.'))
menu.add_option(category, 'FLincludePrivate', includePrivate)
usesubgraphs = BooleanOption(_('Use subgraphs'), False)
usesubgraphs.set_help(_("Subgraphs can help GraphViz position "
"certain linked nodes closer together, "
"but with non-trivial graphs will result "
"in longer lines and larger graphs."))
menu.add_option(category, "usesubgraphs", usesubgraphs)
#------------------------------------------------------------------------
#
@ -243,7 +239,6 @@ class FamilyLinesReport(Report):
self.deletedPeople = 0
self.deletedFamilies = 0
self.useSubgraphs = options.handler.options_dict['usesubgraphs' ]
self.followParents = options.handler.options_dict['FLfollowParents' ]
self.followChildren = options.handler.options_dict['FLfollowChildren' ]
self.removeExtraPeople = options.handler.options_dict['FLremoveExtraPeople' ]
@ -258,6 +253,7 @@ class FamilyLinesReport(Report):
self.maxChildren = options.handler.options_dict['FLmaxChildren' ]
self.includeImages = options.handler.options_dict['FLincludeImages' ]
self.imageOnTheSide = options.handler.options_dict['FLimageOnTheSide' ]
self.useSubgraphs = options.handler.options_dict['FLuseSubgraphs' ]
self.includeDates = options.handler.options_dict['FLincludeDates' ]
self.includePlaces = options.handler.options_dict['FLincludePlaces' ]
self.includeNumChildren = options.handler.options_dict['FLincludeNumChildren' ]
@ -319,6 +315,21 @@ class FamilyLinesReport(Report):
# now that begin_report() has done the work, output what we've
# obtained into whatever file or format the user expects to use
self.doc.write('# Number of people in database: %d\n' % self.db.get_number_of_people())
self.doc.write('# Number of people of interest: %d\n' % len(self.peopleToOutput))
self.doc.write('# Number of families in database: %d\n' % self.db.get_number_of_families())
self.doc.write('# Number of families of interest: %d\n' % len(self.familiesToOutput))
if self.removeExtraPeople:
self.doc.write('# Additional people removed: %d\n' % self.deletedPeople)
self.doc.write('# Additional families removed: %d\n' % self.deletedFamilies)
self.doc.write('# Initial list of people of interest:\n')
for handle in self.interestSet:
person = self.db.get_person_from_handle(handle)
gid = person.get_gramps_id()
name = person.get_primary_name().get_regular_name()
self.doc.write('# -> %s, %s\n' % (gid, name))
self.writePeople()
self.writeFamilies()
self.progress.close()
@ -597,6 +608,9 @@ class FamilyLinesReport(Report):
def writePeople(self):
self.doc.write('\n')
# if we're going to attempt to include images, then use the HTML style of .dot file
bUseHtmlOutput = False
if self.includeImages:
@ -722,10 +736,18 @@ class FamilyLinesReport(Report):
if imagePath:
label += '</TD></TR></TABLE>'
self.doc.add_node(person.get_gramps_id(),label,"box","","filled",colour)
self.doc.add_node(
id=person.get_gramps_id(),
label=label,
shape='box',
fillcolor=colour,
htmloutput=bUseHtmlOutput)
def writeFamilies(self):
self.doc.write('\n')
# loop through all the families we need to output
for familyHandle in self.familiesToOutput:
self.progress.step()
@ -798,17 +820,21 @@ class FamilyLinesReport(Report):
if self.useSubgraphs and fatherHandle and motherHandle:
self.doc.start_subgraph(fgid)
self.doc.write('\n')
# see if we have a father to link to this family
if fatherHandle:
if fatherHandle in self.peopleToOutput:
father = self.db.get_person_from_handle(fatherHandle)
self.doc.add_link(fgid, father.get_gramps_id())
comment = "father: %s" % father.get_primary_name().get_regular_name()
self.doc.add_link(fgid, father.get_gramps_id(), comment=comment)
# see if we have a mother to link to this family
if motherHandle:
if motherHandle in self.peopleToOutput:
mother = self.db.get_person_from_handle(motherHandle)
self.doc.add_link(fgid, mother.get_gramps_id())
comment = "mother: %s" % mother.get_primary_name().get_regular_name()
self.doc.add_link(fgid, mother.get_gramps_id(), comment=comment)
if self.useSubgraphs and fatherHandle and motherHandle:
self.doc.end_subgraph()
@ -817,7 +843,8 @@ class FamilyLinesReport(Report):
for childRef in family.get_child_ref_list():
if childRef.ref in self.peopleToOutput:
child = self.db.get_person_from_handle(childRef.ref)
self.doc.add_link(child.get_gramps_id(), fgid)
comment = "child: %s" % child.get_primary_name().get_regular_name()
self.doc.add_link(child.get_gramps_id(), fgid, comment=comment)
#------------------------------------------------------------------------
@ -829,12 +856,12 @@ class FamilyLinesReport(Report):
#------------------------------------------------------------------------
register_report(
name = 'familylines_graph',
translated_name = _("Family Lines Graph"),
category = CATEGORY_GRAPHVIZ,
report_class = FamilyLinesReport, # must implement write_report(), called by report() in _ReportDialog.py
options_class = FamilyLinesOptions, # must implement add_menu_options(), called by MenuOptions::__init__()
modes = MODE_GUI,
status = _("Stable"),
translated_name = _("Family Lines Graph"),
author_name = "Stephane Charette",
author_email = "stephanecharette@gmail.com",
description =_("Generates family line graphs using GraphViz."),