mirror of
https://github.com/vcscsvcscs/GenerationsHeritage.git
synced 2025-08-12 22:09:07 +02:00
add edges
This commit is contained in:
@@ -1,7 +1,26 @@
|
||||
<script>
|
||||
import { Handle, Position } from '@xyflow/svelte';
|
||||
<script lang="ts">
|
||||
import { Handle, Position, type NodeProps } from '@xyflow/svelte';
|
||||
type $$Props = NodeProps;
|
||||
|
||||
export let person = {
|
||||
export let id: $$Props['id'];
|
||||
id;
|
||||
export let dragHandle: $$Props['dragHandle'] = undefined;
|
||||
dragHandle;
|
||||
export let type: $$Props['type'] = undefined;
|
||||
type;
|
||||
export let selected: $$Props['selected'] = undefined;
|
||||
selected;
|
||||
export let width: $$Props['width'] = undefined;
|
||||
width;
|
||||
export let height: $$Props['height'] = undefined;
|
||||
height;
|
||||
export let dragging: $$Props['dragging'];
|
||||
dragging;
|
||||
export let targetPosition: $$Props['targetPosition'] = undefined;
|
||||
targetPosition;
|
||||
export let sourcePosition: $$Props['sourcePosition'] = undefined;
|
||||
sourcePosition;
|
||||
export let data = {
|
||||
ID: '',
|
||||
Lastname: 'Nem',
|
||||
Firstname: 'Ismert',
|
||||
@@ -10,43 +29,43 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="rounded-badge card card-compact bg-primary">
|
||||
<div class="rounded-badge card card-compact bg-base-300">
|
||||
<div class="card-body items-center text-center w-30">
|
||||
<div class="avatar">
|
||||
<figure class="w-24 mask mask-squircle">
|
||||
<img src={person.ProfilePicture} alt="Picture of {person.Lastname} {person.Firstname}" />
|
||||
<img src={data.ProfilePicture} alt="Picture of {data.Lastname} {data.Firstname}" />
|
||||
</figure>
|
||||
</div>
|
||||
<h2 class="card-title text-primary-content">
|
||||
{person.Lastname}
|
||||
{person.Firstname}
|
||||
{person.Middlename}
|
||||
<h2 class="card-title text-base-content">
|
||||
{data.Lastname}
|
||||
{data.Firstname}
|
||||
{data.Middlename}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Top}
|
||||
id="sibling"
|
||||
id="spouse"
|
||||
style="transform: translate(10px, 50%); left: 0;"
|
||||
/>
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Top}
|
||||
id="sibling"
|
||||
id="spouse"
|
||||
style="transform: translate(0, 50%); left: auto; right: 10px"
|
||||
/>
|
||||
<Handle type="target" position={Position.Top} id="parent" style="transform: translate(0, 50%);" />
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
id="right"
|
||||
style="transform: translate(-3px, 50%);"
|
||||
/>
|
||||
<Handle type="target" position={Position.Left} id="left" style="transform: translate(3px, 50%);" />
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Bottom}
|
||||
id="child"
|
||||
style="transform: translate(0, -3px);"
|
||||
/>
|
||||
<Handle type="target" position={Position.Top} id="child" style="transform: translate(0, 50%);" />
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Bottom}
|
||||
id="parent"
|
||||
style="transform: translate(0, -3px);"
|
||||
/>
|
@@ -4,8 +4,8 @@ import { Position, type Node, type Edge } from '@xyflow/svelte';
|
||||
const dagreGraph = new dagre.graphlib.Graph();
|
||||
dagreGraph.setDefaultEdgeLabel(() => ({}));
|
||||
|
||||
const nodeWidth = 172;
|
||||
const nodeHeight = 36;
|
||||
const nodeWidth = 250;
|
||||
const nodeHeight = 250;
|
||||
|
||||
function getLayoutedElements(nodes: Node[], edges: Edge[], direction = 'TB') {
|
||||
const isHorizontal = direction === 'LR';
|
||||
|
57
frontend/src/lib/family_tree/dataAdapter.ts
Normal file
57
frontend/src/lib/family_tree/dataAdapter.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { type Node, type Edge } from '@xyflow/svelte';
|
||||
|
||||
function AddToNodesData(data: any, i: number, pushToNodesCallback: (arg: Node) => void) {
|
||||
if (data[0].Values[i] != null) {
|
||||
if (Object.prototype.toString.call(data[0].Values[i]) === '[object Array]') {
|
||||
data[0].Values[i].forEach((person: { ElementId: string; Props: {} }) => {
|
||||
pushToNodesCallback({
|
||||
id: person.ElementId,
|
||||
type: 'custom',
|
||||
data: person.Props,
|
||||
position: { x: 0, y: 0 }
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log(data[0].Values[i]);
|
||||
pushToNodesCallback({
|
||||
id: data[0].Values[i].ElementId,
|
||||
type: 'custom',
|
||||
data: data[0].Values[i].Props,
|
||||
position: { x: 0, y: 0 }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function AddToEdgesData(data: any, i: number, pushToEdgesCallback: (arg: Edge) => void) {
|
||||
if (data[0].Values[i] != null) {
|
||||
if (Object.prototype.toString.call(data[0].Values[i]) === '[object Array]') {
|
||||
data[0].Values[i].forEach((edge: { ElementId: string; StartElementId: string; EndElementId: string; Type: string; Props: {} }) => {
|
||||
pushToEdgesCallback({
|
||||
id: edge.ElementId,
|
||||
source: edge.StartElementId,
|
||||
sourceHandle: edge.Type === 'Parent' ? 'parent' : edge.Type === 'Child' ? 'child' : 'spouse',
|
||||
target: edge.EndElementId,
|
||||
targetHandle: edge.Type === 'Parent' ? 'child' : edge.Type === 'Child' ? 'parent' : 'spouse',
|
||||
label: edge.Type,
|
||||
data: edge.Props,
|
||||
zIndex: edge.Type === 'Spouse' ? 1 : 0
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log(data[0].Values[i]);
|
||||
pushToEdgesCallback({
|
||||
id: data[0].Values[i].ElementId,
|
||||
source: data[0].Values[i].StartElementId,
|
||||
sourceHandle: data[0].Values[i].Type === 'Parent' ? 'parent' : data[0].Values[i].Type === 'Child' ? 'child' : 'spouse',
|
||||
target: data[0].Values[i].EndElementId,
|
||||
targetHandle: data[0].Values[i].Type === 'Parent' ? 'child' : data[0].Values[i].Type === 'Child' ? 'parent' : 'spouse',
|
||||
label: data[0].Values[i].Type,
|
||||
data: data[0].Values[i].Props,
|
||||
zIndex: data[0].Values[i].Type === 'Spouse' ? 1 : 0
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { AddToNodesData, AddToEdgesData };
|
@@ -10,12 +10,14 @@ user.subscribe((value) => {
|
||||
});
|
||||
|
||||
async function fetch_family_tree() {
|
||||
console.log(PUBLIC_API_URL);
|
||||
|
||||
const response = await fetch(
|
||||
{ PUBLIC_API_URL } + '/familyTree?id=8a8b9b05bdc24550a5cc73e0b55e8d7d',
|
||||
PUBLIC_API_URL + '/familyTree?id=8a8b9b05bdc24550a5cc73e0b55e8d7d',
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
Authorization: auth_token
|
||||
}
|
||||
}
|
||||
|
@@ -1,14 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { writable } from 'svelte/store';
|
||||
import { onMount } from 'svelte';
|
||||
import { SvelteFlowProvider, SvelteFlow, Controls, MiniMap } from '@xyflow/svelte';
|
||||
import { SvelteFlowProvider, SvelteFlow, Controls, MiniMap, Background } from '@xyflow/svelte';
|
||||
import type { Node, Edge, NodeTypes } from '@xyflow/svelte';
|
||||
import { isAuthenticated } from '../lib/stores';
|
||||
import PersonNode from './../lib/family_tree/PersonNode.svelte';
|
||||
import { login } from '../lib/auth';
|
||||
import { fetch_family_tree } from '$lib/family_tree/getFamilyTree';
|
||||
import { getLayoutedElements } from '$lib/family_tree/dagreLayout';
|
||||
|
||||
import { AddToNodesData, AddToEdgesData } from '$lib/family_tree/dataAdapter';
|
||||
let edges_data: {
|
||||
id: string;
|
||||
source: string;
|
||||
@@ -25,36 +25,26 @@
|
||||
console.log('user authenticated:', $isAuthenticated);
|
||||
console.log('fetching nodes');
|
||||
fetch_family_tree().then((data) => {
|
||||
let Position = { x: 0, y: 0 };
|
||||
let nodes_data: Node[] = [];
|
||||
function AddToNodesData(data: any, i: number) {
|
||||
if (data[0].Values[i] != null) {
|
||||
if (Object.prototype.toString.call(data[0].Values[i]) === '[object Array]') {
|
||||
data[0].Values[i].forEach((person: { ElementId: string; Props: {} }) => {
|
||||
nodes_data.push({
|
||||
id: person.ElementId,
|
||||
type: 'custom',
|
||||
data: person.Props,
|
||||
position: Position
|
||||
});
|
||||
});
|
||||
} else {
|
||||
nodes_data.push({
|
||||
id: data[0].Values[i].ElementId,
|
||||
type: 'custom',
|
||||
data: data[0].Values[i].Props,
|
||||
position: Position
|
||||
});
|
||||
}
|
||||
}
|
||||
function pushNodeToData(node: Node) {
|
||||
nodes_data.push(node);
|
||||
}
|
||||
AddToNodesData(data, 0);
|
||||
AddToNodesData(data, 2);
|
||||
AddToNodesData(data, 4);
|
||||
AddToNodesData(data, 6);
|
||||
AddToNodesData(data, 8);
|
||||
|
||||
edges_data = [];
|
||||
AddToNodesData(data, 0, pushNodeToData);
|
||||
AddToNodesData(data, 2, pushNodeToData);
|
||||
AddToNodesData(data, 4, pushNodeToData);
|
||||
AddToNodesData(data, 6, pushNodeToData);
|
||||
AddToNodesData(data, 8, pushNodeToData);
|
||||
|
||||
let edges_data: Edge[] = [];
|
||||
function pushEdgeToData(edge: Edge) {
|
||||
edges_data.push(edge);
|
||||
}
|
||||
|
||||
AddToEdgesData(data, 1, pushEdgeToData);
|
||||
AddToEdgesData(data, 3, pushEdgeToData);
|
||||
AddToEdgesData(data, 5, pushEdgeToData);
|
||||
AddToEdgesData(data, 7, pushEdgeToData);
|
||||
|
||||
const layoutedElements = getLayoutedElements(nodes_data, edges_data, 'TB');
|
||||
|
||||
@@ -67,13 +57,37 @@
|
||||
const nodeTypes: NodeTypes = {
|
||||
custom: PersonNode
|
||||
};
|
||||
|
||||
let menu: { id: string; top?: number; left?: number; right?: number; bottom?: number } | null;
|
||||
let width: number;
|
||||
let height: number;
|
||||
|
||||
function handleContextMenu({ detail: { event, node } }) {
|
||||
// Prevent native context menu from showing
|
||||
event.preventDefault();
|
||||
|
||||
// Calculate position of the context menu. We want to make sure it
|
||||
// doesn't get positioned off-screen.
|
||||
menu = {
|
||||
id: node.id,
|
||||
top: event.clientY < height - 200 ? event.clientY : undefined,
|
||||
left: event.clientX < width - 200 ? event.clientX : undefined,
|
||||
right: event.clientX >= width - 200 ? width - event.clientX : undefined,
|
||||
bottom: event.clientY >= height - 200 ? height - event.clientY : undefined
|
||||
};
|
||||
}
|
||||
|
||||
// Close the context menu if it's open whenever the window is clicked.
|
||||
function handlePaneClick() {
|
||||
menu = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div style="height:100vh;">
|
||||
<SvelteFlowProvider>
|
||||
<SvelteFlow {nodes} {nodeTypes} {edges} class="bg-base-100" fitView onlyRenderVisibleElements>
|
||||
<Controls class="bg-base-300 text-primary-content" />
|
||||
<MiniMap />
|
||||
<Controls class="bg-base-300 text-base-content" />
|
||||
<MiniMap class="bg-base-200"/>
|
||||
</SvelteFlow>
|
||||
</SvelteFlowProvider>
|
||||
</div>
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ['./src/**/*.{html,svelte,js,ts}'],
|
||||
important: true,
|
||||
theme: {
|
||||
extend: {}
|
||||
},
|
||||
|
Reference in New Issue
Block a user