Add 5 new statistics to StatisticsChart.py plugin
svn: r3988
This commit is contained in:
parent
3b7b70d606
commit
5bcbb04bb8
@ -1,3 +1,19 @@
|
|||||||
|
2005-01-29 Eero Tamminen <eerot@sf>
|
||||||
|
* src/plugins/StatisticsChart.py:
|
||||||
|
- Add first versions of following statistics:
|
||||||
|
- Child counts
|
||||||
|
- Marriage places
|
||||||
|
- Marriage ages
|
||||||
|
- Ages when first child was born
|
||||||
|
- Ages when last child was born
|
||||||
|
- Added a note that children can be either biological or adopted
|
||||||
|
(this relation can be gotten easily/fast only when going from child
|
||||||
|
to parents, not when going from parent to children like I need to)
|
||||||
|
- Take advantage of Don's age calculations function
|
||||||
|
-> Remove "Estimate" from the age descriptions
|
||||||
|
- Convert ages to correctly sortable strings
|
||||||
|
- Add a few TODO notes
|
||||||
|
|
||||||
2005-01-28 Alex Roitman <shura@alex.neuro.umn.edu>
|
2005-01-28 Alex Roitman <shura@alex.neuro.umn.edu>
|
||||||
* src/PedView.py: Fix remnants of gnome.canvas syntax.
|
* src/PedView.py: Fix remnants of gnome.canvas syntax.
|
||||||
* src/ReadGrdb.py: Add to CVS: native database importer.
|
* src/ReadGrdb.py: Add to CVS: native database importer.
|
||||||
|
@ -17,8 +17,10 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#
|
#
|
||||||
# Statistics plugin (w) 2004-2005 by Eero Tamminen.
|
# Statistics plugin (w) 2004-2005 by Eero Tamminen with lots of help
|
||||||
# Partially based on code from the Timeline graph plugin.
|
# from Alex Roitman.
|
||||||
|
#
|
||||||
|
# To see things still missing, search for "TODO"...
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
|
|
||||||
@ -46,8 +48,11 @@ import gtk
|
|||||||
# GRAMPS modules
|
# GRAMPS modules
|
||||||
#
|
#
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
import const # gender and report type names
|
|
||||||
from RelLib import Person # need Person internals for getting gender / gender name
|
# Person and relation types
|
||||||
|
from RelLib import Person, Family
|
||||||
|
# gender and report type names
|
||||||
|
import const
|
||||||
import BaseDoc
|
import BaseDoc
|
||||||
import Report
|
import Report
|
||||||
import ReportUtils
|
import ReportUtils
|
||||||
@ -108,15 +113,20 @@ class Extract:
|
|||||||
self.get_birth, self.get_place),
|
self.get_birth, self.get_place),
|
||||||
'data_dplace': ("Death places", _("Death places"),
|
'data_dplace': ("Death places", _("Death places"),
|
||||||
self.get_death, self.get_place),
|
self.get_death, self.get_place),
|
||||||
#'data_mplace': (self.marriage_place, "Marriage place", _("Marriage place")),
|
'data_mplace': ("Marriage places", _("Marriage places"),
|
||||||
#'data_fchild': (self.first_child_age, "Estimated ages for bearing the first child", _("Estimated ages for bearing the first child")),
|
self.get_marriage_handles, self.get_places),
|
||||||
#'data_lchild': (self.last_child_age, "Estimated Ages for bearing the last child", _("Estimated Ages for bearing the last child")),
|
'data_fchild': ("Ages when first child born", _("Ages when first child born"),
|
||||||
#'data_ccount': (self.child_count, "Number of children", _("Number of children")),
|
self.get_child_handles, self.get_first_child_age),
|
||||||
#'data_mage': (self.marriage_age, "Estimated (first) marriage ages", _("Estimated (first) marriage ages")),
|
'data_lchild': ("Ages when last child born", _("Ages when last child born"),
|
||||||
'data_dage': ("Estimated ages at death", _("Estimated ages at death"),
|
self.get_child_handles, self.get_last_child_age),
|
||||||
self.get_person, self.get_death_age),
|
'data_ccount': ("Number of children", _("Number of children"),
|
||||||
'data_age': ("Estimated ages", _("Estimated ages"),
|
self.get_child_handles, self.get_child_count),
|
||||||
self.get_person, self.get_person_age)
|
'data_mage': ("Marriage ages", _("Marriage ages"),
|
||||||
|
self.get_marriage_handles, self.get_event_ages),
|
||||||
|
'data_dage': ("Ages at death", _("Ages at death"),
|
||||||
|
self.get_person, self.get_death_age),
|
||||||
|
'data_age': ("Ages", _("Ages"),
|
||||||
|
self.get_person, self.get_person_age)
|
||||||
}
|
}
|
||||||
|
|
||||||
# ----------------- data extraction methods --------------------
|
# ----------------- data extraction methods --------------------
|
||||||
@ -124,6 +134,7 @@ class Extract:
|
|||||||
|
|
||||||
def get_title(self, person):
|
def get_title(self, person):
|
||||||
"return title for given person"
|
"return title for given person"
|
||||||
|
# TODO: return all titles, not just primary ones...
|
||||||
title = person.get_primary_name().get_title()
|
title = person.get_primary_name().get_title()
|
||||||
if title:
|
if title:
|
||||||
return [title]
|
return [title]
|
||||||
@ -132,7 +143,7 @@ class Extract:
|
|||||||
|
|
||||||
def get_forename(self, person):
|
def get_forename(self, person):
|
||||||
"return forenames for given person"
|
"return forenames for given person"
|
||||||
# because this returns list, other methods return list too
|
# TODO: return all forenames, not just primary ones...
|
||||||
firstnames = person.get_primary_name().get_first_name().strip()
|
firstnames = person.get_primary_name().get_first_name().strip()
|
||||||
if firstnames:
|
if firstnames:
|
||||||
return [name.capitalize() for name in firstnames.split()]
|
return [name.capitalize() for name in firstnames.split()]
|
||||||
@ -182,50 +193,97 @@ class Extract:
|
|||||||
if place:
|
if place:
|
||||||
return [place]
|
return [place]
|
||||||
return [_("Place missing")]
|
return [_("Place missing")]
|
||||||
|
|
||||||
|
def get_places(self, data):
|
||||||
|
"return places for given (person,event_handles)"
|
||||||
|
places = []
|
||||||
|
person, event_handles = data
|
||||||
|
for event_handle in event_handles:
|
||||||
|
event = self.db.get_event_from_handle(event_handle)
|
||||||
|
place_handle = event.get_place_handle()
|
||||||
|
if place_handle:
|
||||||
|
place = self.db.get_place_from_handle(place_handle).get_title()
|
||||||
|
if place:
|
||||||
|
places.append(place)
|
||||||
|
else:
|
||||||
|
places.append(_("Place missing"))
|
||||||
|
return places
|
||||||
|
|
||||||
def get_person_age(self, person):
|
def get_person_age(self, person):
|
||||||
"return age for given person, if alive"
|
"return age for given person, if alive"
|
||||||
death = self.get_death(person)
|
death = person.get_death_handle()
|
||||||
if not death:
|
if not death:
|
||||||
return self.estimate_age(person)
|
return [self.estimate_age(person)]
|
||||||
return [_("Already dead")]
|
return [_("Already dead")]
|
||||||
|
|
||||||
def get_death_age(self, person):
|
def get_death_age(self, person):
|
||||||
"return age at death for given person, if dead"
|
"return age at death for given person, if dead"
|
||||||
death = self.get_death(person)
|
death_handle = person.get_death_handle()
|
||||||
if death:
|
if death_handle:
|
||||||
return self.estimate_age(person)
|
return [self.estimate_age(person, death_handle)]
|
||||||
return [_("Still alive")]
|
return [_("Still alive")]
|
||||||
|
|
||||||
def marriage_age(self, person):
|
def get_event_ages(self, data):
|
||||||
return "TODO: Marriage age stat unimplemented"
|
"return ages at given (person,event_handles)"
|
||||||
|
ages = []
|
||||||
|
person, event_handles = data
|
||||||
|
for event_handle in event_handles:
|
||||||
|
ages.append(self.estimate_age(person, event_handle))
|
||||||
|
if ages:
|
||||||
|
return ages
|
||||||
|
return [_("Events missing")]
|
||||||
|
|
||||||
def marriage_place(self, person):
|
def get_first_child_age(self, data):
|
||||||
return "TODO: Marriage place stat unimplemented"
|
"return age when first child in given (person,child_handles) was born"
|
||||||
|
ages, errors = self.get_sorted_child_ages(data)
|
||||||
|
if ages:
|
||||||
|
errors.append(ages[0])
|
||||||
|
return errors
|
||||||
|
return [_("Children missing")]
|
||||||
|
|
||||||
def first_child_age(self, person):
|
def get_last_child_age(self, data):
|
||||||
return "TODO: First child bearing age stat unimplemented"
|
"return age when last child in given (person,child_handles) was born"
|
||||||
|
ages, errors = self.get_sorted_child_ages(data)
|
||||||
|
if ages:
|
||||||
|
errors.append(ages[-1])
|
||||||
|
return errors
|
||||||
|
return [_("Children missing")]
|
||||||
|
|
||||||
def last_child_age(self, person):
|
def get_child_count(self, data):
|
||||||
return "TODO: Last child bearing age stat unimplemented"
|
"return number of children in given (person,child_handles)"
|
||||||
|
return [str(len(data[1]))]
|
||||||
def child_count(self, person):
|
|
||||||
return "TODO: Child count stat unimplemented"
|
|
||||||
|
|
||||||
# ------------------- utility methods -------------------------
|
# ------------------- utility methods -------------------------
|
||||||
|
|
||||||
|
def get_sorted_child_ages(self, data):
|
||||||
|
"return (sorted_ages,errors) for given (person,child_handles)"
|
||||||
|
ages = []
|
||||||
|
errors = []
|
||||||
|
person, child_handles = data
|
||||||
|
for child_handle in child_handles:
|
||||||
|
child = self.db.get_person_from_handle(child_handle)
|
||||||
|
birth_handle = child.get_birth_handle()
|
||||||
|
if birth_handle:
|
||||||
|
ages.append(self.estimate_age(person, birth_handle))
|
||||||
|
else:
|
||||||
|
errors.append(_("Birth missing"))
|
||||||
|
continue
|
||||||
|
ages.sort()
|
||||||
|
return (ages, errors)
|
||||||
|
|
||||||
def estimate_age(self, person):
|
def estimate_age(self, person, end=None, begin=None):
|
||||||
"return estimated age (range) for given person or error message"
|
"""return estimated age (range) for given person or error message.
|
||||||
age = ReportUtils.estimate_age(self.db, person)
|
age string is padded with spaces so that it can be sorted"""
|
||||||
|
age = ReportUtils.estimate_age(self.db, person, end, begin)
|
||||||
if age[0] < 0 or age[1] < 0:
|
if age[0] < 0 or age[1] < 0:
|
||||||
# inadequate information
|
# inadequate information
|
||||||
return [_("Date(s) missing")]
|
return _("Date(s) missing")
|
||||||
if age[0] == age[1]:
|
if age[0] == age[1]:
|
||||||
# exact year
|
# exact year
|
||||||
return [str(age[0])]
|
return "%3d" % age[0]
|
||||||
else:
|
else:
|
||||||
# minimum and maximum
|
# minimum and maximum
|
||||||
return [str(age[0]) + "-" + str(age[1])]
|
return "%3d-%d" % (age[0], age[1])
|
||||||
|
|
||||||
# ------------------- type methods -------------------------
|
# ------------------- type methods -------------------------
|
||||||
# take db and person and return suitable gramps object(s)
|
# take db and person and return suitable gramps object(s)
|
||||||
@ -235,18 +293,48 @@ class Extract:
|
|||||||
return person
|
return person
|
||||||
|
|
||||||
def get_birth(self, person):
|
def get_birth(self, person):
|
||||||
"return birth event for given person or None"
|
"return birth event for given person or None"
|
||||||
birth_handle = person.get_birth_handle()
|
birth_handle = person.get_birth_handle()
|
||||||
if birth_handle:
|
if birth_handle:
|
||||||
return self.db.get_event_from_handle(birth_handle)
|
return self.db.get_event_from_handle(birth_handle)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_death(self, person):
|
def get_death(self, person):
|
||||||
"return death event for given person or None"
|
"return death event for given person or None"
|
||||||
death_handle = person.get_death_handle()
|
death_handle = person.get_death_handle()
|
||||||
if death_handle:
|
if death_handle:
|
||||||
return self.db.get_event_from_handle(death_handle)
|
return self.db.get_event_from_handle(death_handle)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_child_handles(self, person):
|
||||||
|
"return list of child handles for given person or None"
|
||||||
|
children = []
|
||||||
|
for fam_handle in person.get_family_handle_list():
|
||||||
|
fam = self.db.get_family_from_handle(fam_handle)
|
||||||
|
for child_handle in fam.get_child_handle_list():
|
||||||
|
children.append(child_handle)
|
||||||
|
# TODO: it would be good to return only biological children,
|
||||||
|
# but GRAMPS doesn't offer any efficient way to check that
|
||||||
|
# (I don't want to check each children's parent family mother
|
||||||
|
# and father relations as that would make this *much* slower)
|
||||||
|
if children:
|
||||||
|
return (person, children)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_marriage_handles(self, person):
|
||||||
|
"return list of marriage event handles for given person or None"
|
||||||
|
marriages = []
|
||||||
|
for family_handle in person.get_family_handle_list():
|
||||||
|
family = self.db.get_family_from_handle(family_handle)
|
||||||
|
if family.get_relationship() == Family.MARRIED:
|
||||||
|
for event_handle in family.get_event_list():
|
||||||
|
if event_handle:
|
||||||
|
event = self.db.get_event_from_handle(event_handle)
|
||||||
|
if event.get_name() == "Marriage":
|
||||||
|
marriages.append(event_handle)
|
||||||
|
if marriages:
|
||||||
|
return (person, marriages)
|
||||||
|
return None
|
||||||
|
|
||||||
# ----------------- data collection methods --------------------
|
# ----------------- data collection methods --------------------
|
||||||
|
|
||||||
@ -296,7 +384,7 @@ class Extract:
|
|||||||
# which methods to use
|
# which methods to use
|
||||||
for key in options:
|
for key in options:
|
||||||
if options[key] and key in self.extractors:
|
if options[key] and key in self.extractors:
|
||||||
# localized data title, value dict and method
|
# localized data title, value dict, type and data method
|
||||||
data.append((ext[key][1], {}, ext[key][2], ext[key][3]))
|
data.append((ext[key][1], {}, ext[key][2], ext[key][3]))
|
||||||
|
|
||||||
# go through the people and collect data
|
# go through the people and collect data
|
||||||
@ -697,6 +785,10 @@ class StatisticsChartOptions(ReportOptions.ReportOptions):
|
|||||||
dialog.add_frame_option("Chart Selection", "", hbox, tip)
|
dialog.add_frame_option("Chart Selection", "", hbox, tip)
|
||||||
hbox.show_all()
|
hbox.show_all()
|
||||||
|
|
||||||
|
# Note about children
|
||||||
|
label = gtk.Label(_("Note that children can be both biological or adopted."))
|
||||||
|
dialog.add_frame_option("Chart Selection", "", label)
|
||||||
|
|
||||||
|
|
||||||
def parse_user_options(self, dialog):
|
def parse_user_options(self, dialog):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user