The Lord in Aberdeenshire, Inventor and fine lad

On behalf of Established Titles



Project Kinflow: Architecting Chaos in Genealogy Visualisation

Standard family tree software works perfectly until it hits real life. Standard tools excel at visualizing nuclear families but fall apart when confronted with the beautiful complexity of modern relationships: divorces, remarriages, adoptions, surrogacy, and multi-generational unions (e.g., when a brother marries his brother's ex-wife, who is also his niece).

Project Kinflow was conceived to solve this. The goal was to build a dynamic, scalable genealogy renderer capable of handling "extreme" genealogical connections without turning into an unreadable "spaghetti graph."

Here is how we achieved it under the hood.


The Core Conception: Beyond the Tree

Traditional genealogy uses a "tree" structure. A tree is a specific type of graph where any two nodes are connected by exactly one path. Real families are not trees; they are Multi-Graphs containing cycles, complex bidirectional links, and parallel edges.

To visualize this, we had to stop thinking about hierarchical trees and start thinking about topological constraint solving.

The Architectural Pillars

  1. Strict Generational Layering (Y-Axis): Ancestors must be above descendants. We implemented a strict layering system where Y-coordinates are determined solely by the topological generation number.

  2. Horizontal Partnership Clustering (X-Axis): Partners must stand side-by-side. The distance between spouses must be minimized to avoid crossing parental lines down to children.

  3. Corridor-Based Edge Routing: Lines connecting nodes must never cut through intermediate nodes. They must occupy dedicated "lanes" between layers.


Implementation Details: The Algorithms

The most challenging part of the project was designing the layout engine. How do we place nodes and draw lines automatically based on a messy database of relationships?

1. Solving the Y-Axis: The Failure of BFS and the Shift to Relaxation

Initially, we tried using a standard Breadth-First Search (BFS) starting from roots (ancestors with no parents) to determine generational levels.

The Problem: In complex graphs with cross-generational marriages (e.g., Layer 1 marries Layer 2), standard BFS fails. If the graph traversal visits a node through a "spouse" edge before visiting it through a "child" edge, a child can end up on the same generation layer as their parent.

The Solution: Iterative Constraint Relaxation. We moved away from single-pass traversal. We constructed a graph with mixed edge weights:

We then implemented an iterative relaxation algorithm (similar to Bellman-Ford). The engine initializes all nodes at a default level and then iterates through the graph, forcing parent-child gaps to be exactly 1 and spouse gaps to be exactly 0, until the entire graph reaches an equilibrium state of correct generational layering.

2. Solving the X-Axis: Eulerian Paths and Partnership Chains

Once layers are established, we need to order nodes horizontally within each layer. We wanted to guarantee that spouses are always adjacent.

The Solution: Eulerian-Tour-Inspired Ordering. Instead of a standard tree traversal, we treat partnerships as primary chains. We construct a bipartite graph of People nodes and Union nodes.

By utilizing an ordering algorithm inspired by Eulerian paths, we can traverse the entire chain of a person's partnerships (Ex-wife 1 -> Ex-wife 2 -> Current Wife) and assign their horizontal order based strictly on adjacency in that path. This mathematically guarantees that no matter how many partners a person has, they all form a tight cluster on the X-axis.


Aesthetic "Приколы": Making it Readable

Placing the nodes was only half the battle. Standard graph lines (straight or raw Bézier) cut diagonally across the screen, passing over unrelated nodes and making the graph unreadable.

1. Orthogonal Routing with Fillets

We implemented Orthogonal Routing. Lines never travel diagonally. They move strictly vertically to exit a node, strictly horizontally through dedicated "corridors" between generational layers, and strictly vertically to enter the target node.

To make it look organic and modern (and less like a generic circuit board), we applied filleted corners using Quadratic Bézier curves. The layout engine calculates the 90-degree intersection points, backs off by a fixed radius, and draws a smooth, mathematical arc to connect the segments.

2. S-Curve Multi-Generation Union Routing

When an "extreme" connection occurs—such as a union between nodes on different layers—standard П-shaped orthogonal routing looks awful.

For these specific connections, we implemented dedicated Cubic Bézier S-curves. The engine detects the cross-layer gap, calculates a dedicated техніческий коридор (technical corridor) that is guaranteed to be empty between the specific X-coordinates of the partners, and routes a smooth S-curve from the bottom face of the upper partner to the top face of the lower partner.

3. Edge Stack Management (Anti-Collision)

When multiple children enter a single node (biological + adoptive lines) or multiple parental lines drop down, they inevitably overlap.

We implemented an Edge Tracker. When the rendering engine draws a line to or from a node, it increment a "stack count" for that node's specific face (top/bottom). Subsequent lines are dynamically offset by a fixed pixel amount along the edge of the node. Furthermore, child lines utilize the filleted П-routing to enter the side of the node rather than the top, reducing visual clutter.


Technical Stack & Workflow

Kinflow is a modern SPA (Single Page Application) built for performance and maintainability.

Human-AI Collaboration

This project was built using an advanced, iterative workflow between a human architect and large language models.

This collaboration allowed Project Kinflow to move from a concept to a functional, aesthetically pleasing multi-graph visualizer in record time.


Built with Gemini under the control of a human.