feat(stammbaum): highlight the selected person's bloodline (#703) #704

Merged
marcel merged 13 commits from feat/issue-703-stammbaum-lineage-highlight into main 2026-05-31 20:11:07 +02:00
Showing only changes of commit 7cc2ddc6ad - Show all commits

View File

@@ -106,8 +106,11 @@ const parentLinks = $derived.by<ParentLinks>(() => {
{@const aCenter = nodeCenter(group.parentA)}
{@const bCenter = nodeCenter(group.parentB)}
{@const childCenters = group.childIds
.map((id) => nodeCenter(id))
.filter((c): c is { x: number; y: number } => c !== null)}
.map((id) => {
const c = nodeCenter(id);
return c ? { id, x: c.x, y: c.y } : null;
})
.filter((c): c is { id: string; x: number; y: number } => c !== null)}
{#if aCenter && bCenter && childCenters.length > 0}
{@const midX = (aCenter.x + bCenter.x) / 2}
{@const parentBottomY = aCenter.y + NODE_H / 2}
@@ -138,13 +141,14 @@ const parentLinks = $derived.by<ParentLinks>(() => {
/>
{/if}
</g>
{#each childCenters as cc, i (group.childIds[i])}
{#each childCenters as cc (cc.id)}
<!-- Each vertical joins the parent pair to one child: active only when
both parents and that child are active, so the same bar can stay lit
to the lineage child while dimming to a collateral sibling. -->
to the lineage child while dimming to a collateral sibling. The child
id rides on the centre object, so it never desyncs from the filtered
centres (a child without a position drops out of both together). -->
{@const childActive =
isConnectorActive(group.parentA, group.childIds[i]) &&
isConnectorActive(group.parentB, group.childIds[i])}
isConnectorActive(group.parentA, cc.id) && isConnectorActive(group.parentB, cc.id)}
<g class="lineage-fade" opacity={connectorOpacity(childActive)}>
<line
x1={cc.x}