mirror of
https://github.com/vcscsvcscs/GenerationsHeritage.git
synced 2025-08-11 21:39:06 +02:00
better edge layout
This commit is contained in:
@@ -28,22 +28,31 @@
|
||||
let srcPos: Position = $state(sourcePosition || Position.Bottom);
|
||||
let tgtPos: Position = $state(targetPosition || Position.Top);
|
||||
|
||||
// Determine edge styling and positioning based on relationship type
|
||||
// Determine edge styling and positioning based on relationship type and handles
|
||||
if (edgeType === 'spouse') {
|
||||
edgeColor = 'stroke: red;';
|
||||
edgeLabel = spouse();
|
||||
// For spouse connections, use horizontal positioning
|
||||
if (sourceX < targetX) {
|
||||
// Use handle-based positioning for spouses
|
||||
if (sourceHandleId === 'spouse-right') {
|
||||
srcPos = Position.Right;
|
||||
tgtPos = Position.Left;
|
||||
} else {
|
||||
} else if (sourceHandleId === 'spouse-left') {
|
||||
srcPos = Position.Left;
|
||||
tgtPos = Position.Right;
|
||||
} else {
|
||||
// Fallback to position-based logic
|
||||
if (sourceX < targetX) {
|
||||
srcPos = Position.Right;
|
||||
tgtPos = Position.Left;
|
||||
} else {
|
||||
srcPos = Position.Left;
|
||||
tgtPos = Position.Right;
|
||||
}
|
||||
}
|
||||
} else if (edgeType === 'child') {
|
||||
edgeColor = 'stroke: blue;';
|
||||
edgeLabel = child();
|
||||
// Use the handles set by the layout: child handle (bottom) to parent handle (top)
|
||||
// Parent-child: from parent's bottom (child handle) to child's top (parent handle)
|
||||
srcPos = Position.Bottom;
|
||||
tgtPos = Position.Top;
|
||||
} else if (edgeType === 'parent') {
|
||||
@@ -55,13 +64,22 @@
|
||||
} else if (edgeType === 'sibling') {
|
||||
edgeColor = 'stroke: orange;';
|
||||
edgeLabel = sibling();
|
||||
// For siblings, use horizontal positioning
|
||||
if (sourceX < targetX) {
|
||||
// Use handle-based positioning for siblings
|
||||
if (sourceHandleId === 'spouse-right') {
|
||||
srcPos = Position.Right;
|
||||
tgtPos = Position.Left;
|
||||
} else {
|
||||
} else if (sourceHandleId === 'spouse-left') {
|
||||
srcPos = Position.Left;
|
||||
tgtPos = Position.Right;
|
||||
} else {
|
||||
// Fallback to position-based logic
|
||||
if (sourceX < targetX) {
|
||||
srcPos = Position.Right;
|
||||
tgtPos = Position.Left;
|
||||
} else {
|
||||
srcPos = Position.Left;
|
||||
tgtPos = Position.Right;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
edgeColor = 'stroke: gray;';
|
||||
@@ -71,13 +89,25 @@
|
||||
tgtPos = targetPosition || Position.Top;
|
||||
}
|
||||
|
||||
// Override with handle-specific positioning if handles are specified
|
||||
// Explicit handle overrides (these should take precedence)
|
||||
if (sourceHandleId === 'child') {
|
||||
srcPos = Position.Bottom;
|
||||
}
|
||||
if (targetHandleId === 'parent') {
|
||||
tgtPos = Position.Top;
|
||||
}
|
||||
if (sourceHandleId === 'spouse-left') {
|
||||
srcPos = Position.Left;
|
||||
}
|
||||
if (sourceHandleId === 'spouse-right') {
|
||||
srcPos = Position.Right;
|
||||
}
|
||||
if (targetHandleId === 'spouse-left') {
|
||||
tgtPos = Position.Left;
|
||||
}
|
||||
if (targetHandleId === 'spouse-right') {
|
||||
tgtPos = Position.Right;
|
||||
}
|
||||
|
||||
let [path, labelX, labelY] = $derived(
|
||||
getSmoothStepPath({
|
||||
|
@@ -26,6 +26,38 @@
|
||||
class={'card card-compact flex h-40 w-40 flex-col items-center justify-center rounded-full shadow-lg' +
|
||||
nodeColor}
|
||||
>
|
||||
<Handle
|
||||
class="customHandle"
|
||||
id="spouse-left"
|
||||
{isValidConnection}
|
||||
position={Position.Left}
|
||||
isConnectable={true}
|
||||
type="source"
|
||||
/>
|
||||
<Handle
|
||||
class="customHandle"
|
||||
id="spouse-right"
|
||||
{isValidConnection}
|
||||
position={Position.Right}
|
||||
isConnectable={true}
|
||||
type="source"
|
||||
/>
|
||||
<Handle
|
||||
class="customHandle"
|
||||
id="spouse-left"
|
||||
{isValidConnection}
|
||||
position={Position.Left}
|
||||
isConnectable={true}
|
||||
type="target"
|
||||
/>
|
||||
<Handle
|
||||
class="customHandle"
|
||||
id="spouse-right"
|
||||
{isValidConnection}
|
||||
position={Position.Right}
|
||||
isConnectable={true}
|
||||
type="target"
|
||||
/>
|
||||
<Handle
|
||||
class="customHandle"
|
||||
id="child"
|
||||
@@ -81,7 +113,7 @@
|
||||
/>
|
||||
|
||||
<div class="avatar mb-2" style="z-index: 2; cursor: pointer;">
|
||||
<div class={"w-24 rounded-full border-0 ring-offset-1"+nodeColor}>
|
||||
<div class={'w-24 rounded-full border-0 ring-offset-1' + nodeColor}>
|
||||
<img
|
||||
src={data.profile_picture || 'https://cdn-icons-png.flaticon.com/512/10628/10628885.png'}
|
||||
alt="Picture of {data.last_name} {data.first_name}"
|
||||
@@ -90,7 +122,7 @@
|
||||
</div>
|
||||
|
||||
<div class="px-2 text-center" style="z-index: 2; cursor: pointer;">
|
||||
<h2 class="text-sm leading-tight font-semibold">
|
||||
<h2 class="text-sm font-semibold leading-tight">
|
||||
{data.first_name}
|
||||
{data.middle_name ? data.middle_name : ''}
|
||||
{data.last_name}
|
||||
|
@@ -174,6 +174,7 @@ export class FamilyTree extends dagre.graphlib.Graph {
|
||||
let newEdge = { ...edge };
|
||||
|
||||
if (String(edge.data?.type).toLowerCase() === 'child') {
|
||||
// Parent to child: source (parent) uses 'child' handle (bottom), target (child) uses 'parent' handle (top)
|
||||
newEdge.sourceHandle = 'child';
|
||||
newEdge.targetHandle = 'parent';
|
||||
} else if (String(edge.data?.type).toLowerCase() === 'parent') {
|
||||
@@ -185,6 +186,28 @@ export class FamilyTree extends dagre.graphlib.Graph {
|
||||
return; // Skip this duplicate spouse edge
|
||||
}
|
||||
processedSpouseEdges.add(spouseKey);
|
||||
|
||||
// Set spouse handles based on position
|
||||
const sourceNode = this.node(edge.source);
|
||||
const targetNode = this.node(edge.target);
|
||||
if (sourceNode.x < targetNode.x) {
|
||||
newEdge.sourceHandle = 'spouse-right';
|
||||
newEdge.targetHandle = 'spouse-left';
|
||||
} else {
|
||||
newEdge.sourceHandle = 'spouse-left';
|
||||
newEdge.targetHandle = 'spouse-right';
|
||||
}
|
||||
} else if (String(edge.data?.type).toLowerCase() === 'sibling') {
|
||||
// Set sibling handles based on position
|
||||
const sourceNode = this.node(edge.source);
|
||||
const targetNode = this.node(edge.target);
|
||||
if (sourceNode.x < targetNode.x) {
|
||||
newEdge.sourceHandle = 'spouse-right';
|
||||
newEdge.targetHandle = 'spouse-left';
|
||||
} else {
|
||||
newEdge.sourceHandle = 'spouse-left';
|
||||
newEdge.targetHandle = 'spouse-right';
|
||||
}
|
||||
}
|
||||
|
||||
newEdge.hidden = false;
|
||||
|
Reference in New Issue
Block a user