Genogram Controller
The GenogramController
manages data and layout for family trees, handling complex relationships like marriages, parental connections, and gender-based positioning.
Creating a Controller
final controller = GenogramController<Person>(
items: familyMembers,
idProvider: (person) => person.id.toString(),
fatherProvider: (person) => person.fatherId?.toString(),
motherProvider: (person) => person.motherId?.toString(),
spousesProvider: (person) => person.spouseIds?.map((id) => id.toString()).toList(),
genderProvider: (person) => person.isMale ? 0 : 1,
boxSize: const Size(150, 150),
spacing: 30,
runSpacing: 60,
);
Constructor Parameters
Parameter | Type | Description |
---|---|---|
items | List<E> | Data items to display in the family tree |
idProvider | String Function(E) | Function to extract unique ID from an item |
fatherProvider | String? Function(E) | Function to extract father's ID from an item |
motherProvider | String? Function(E) | Function to extract mother's ID from an item |
spousesProvider | List<String>? Function(E) | Function to extract spouse IDs from an item |
genderProvider | int Function(E) | Function to determine gender (0=male, 1=female) |
boxSize | Size | Size of each node box (default: Size(150, 150) ) |
spacing | double | Horizontal spacing between nodes (default: 30 ) |
runSpacing | double | Vertical spacing between rows (default: 60 ) |
orientation | GraphOrientation | Layout direction (default: topToBottom ) |
Key Methods
Family Relationship Methods
// Get root nodes (individuals with no parents)
List<Node<Person>> roots = controller.roots;
// Get children of specific individuals
List<Node<Person>> children = controller.getChildren([fatherNode, motherNode]);
// Get parents of an individual
List<Node<Person>> parents = controller.getParents(childNode);
// Get spouses of an individual
List<Node<Person>> spouses = controller.getSpouseList(personData);
// Gender helper methods
bool isMale = controller.isMale(personData);
bool isFemale = controller.isFemale(personData);
Layout Algorithm
The genogram controller implements a sophisticated layout algorithm that:
-
Places couples (spouses) next to each other:
- Husbands and wives are positioned side-by-side
- Multiple spouses are arranged in sequence
-
Groups children together:
- Children of the same parents are positioned together
- Half-siblings are ordered by their mother's position
-
Positions generations hierarchically:
- Oldest generation at the top/left (based on orientation)
- Each subsequent generation below/right of their parents
-
Centers parents above their children:
- The algorithm balances the parent group to be centered above the child group
The positioning supports both orientations:
GraphOrientation.topToBottom
: Parents above childrenGraphOrientation.leftToRight
: Parents to the left of children
Sibling Ordering
The controller has special logic to keep siblings visually grouped:
// The controller automatically sorts siblings by:
// 1. Children of the same father and mother stay together
// 2. Children with the same father are grouped by mother
// 3. Siblings are ordered based on their mother's position
Cache Optimization
For performance with large family trees, an internal cache is maintained:
// Access methods use caching for better performance
List<Node<Person>> spouses = controller.getSpouseList(person); // Uses cache
// Clear caches when data changes significantly
controller.items = updatedFamilyMembers; // Automatically clears caches