Esempio n. 1
0
    def __call__(self,
                 table: Table,
                 root: Person,
                 x0: int = 0,
                 y0: int = 0
                ) -> List[Union[PersonBox, SpouseLink, ParentChildLink]]:

        # handle single person
        spouse = table.get_spouse(root)
        if spouse is None:
            x = x0 + self.x_margin
            y = y0 + self.y_margin
            elements = [self.person_box_class(root, x, y)]
            return elements

        # get family members from the table
        if root.gender == 'M':
            parents = [root, spouse]
        else:
            parents = [spouse, root]
        children = table.find_children(*parents)
        children = sorted(children,
                          key=lambda p: (p.birth_order, p.id_))

        elements = []
        x = x0

        # elements for children
        for child in children:
            elems = self(table, child, x0=x, y0=y0 + self.unit_h)
            x = max([e.xmax for e in _get_person_boxes(elems)])
            x += self.x_margin
            elements += elems
        child_elements = [e for e in _get_person_boxes(elements)
                          if e.person in children]

        # elements for parents
        center = (x0 + x) // 2
        x = max(x0, center - self.unit_w)
        x1 = x + self.x_margin
        x2 = x + self.x_margin + self.unit_w
        y = y0 + self.y_margin
        elements.append(self.person_box_class(parents[0], x1, y))
        elements.append(self.person_box_class(parents[1], x2, y))

        # parent and child link
        ym = y0 + self.person_box_class.height // 2
        for child_elem in child_elements:
            x1 = x + self.unit_w
            y1 = ym
            x2 = (child_elem.xmin + child_elem.xmax) // 2
            y2 = child_elem.ymin
            elements.append(self.parent_child_link_class(x1, y1, x2, y2))

        # spouse link
        elements.append(self.spouse_link_class(
            x + self.unit_w - self.x_margin, ym,
            x + self.unit_w + self.x_margin, ym))

        return elements
Esempio n. 2
0
    def __call__(self, table: Table, target: Person) -> List[Element]:
        # a) single
        #   - with parent info -> tree(father)
        #   - no parent info -> tree(target)
        spouse = table.get_spouse(target)
        if spouse is None:
            parents = table.get_parents(target)
            if parents[0] and parents[1]:
                return self.tree_layout_func(table, parents[0])
            else:
                return self.tree_layout_func(table, target)

        if target.gender == 'M':
            husband = target
            wife = spouse
        else:
            husband = spouse
            wife = target

        parents1 = table.get_parents(husband)
        parents2 = table.get_parents(wife)

        # b) couple, no parents info -> tree(target)
        if ((parents1[0] is None or parents1[1] is None)
                and (parents2[0] is None or parents2[1] is None)):
            return self.tree_layout_func(table, target)

        # c) couple, with parents info -> butterfly layout
        children1 = _get_brothers_and_sisters(table, husband)
        children2 = _get_brothers_and_sisters(table, wife)

        elements = []

        # layout children
        x = 0
        elements, x = self._layout_children(elements, x, table, children1)
        elements, x = self._layout_children(elements, x, table, [husband])
        elements, x = self._layout_children(elements, x, table, children2)

        # layout parents
        x = 0
        elements, x = self._layout_parents(elements, x, table, parents1,
                                           children1 + [husband])
        elements, x = self._layout_parents(elements, x, table, parents2,
                                           [wife] + children2)

        return elements
Esempio n. 3
0
 def test_get_spouse_key_error(self):
     person = Person(1, "Name", spouse_id=999)
     table = Table([person])
     with pytest.raises(KeyError):
         table.get_spouse(person)
Esempio n. 4
0
 def test_get_spouse_no_result(self):
     person = Person(1, "Name")
     table = Table([person])
     assert table.get_spouse(person) == None
Esempio n. 5
0
 def test_get_spouse(self):
     husband = Person(1, "Husband", spouse_id=2)
     wife = Person(2, "Wife", spouse_id=1)
     table = Table([husband, wife])
     assert table.get_spouse(husband) == wife
     assert table.get_spouse(wife) == husband