GeneIT/geneit_app/src/widgets/complex_family_tree/ComplexFamilyTree.tsx

160 lines
4.3 KiB
TypeScript
Raw Normal View History

2023-08-22 14:12:55 +00:00
import React from "react";
2023-08-22 15:17:36 +00:00
import f3, { f3Data } from "family-chart";
2023-08-22 14:12:55 +00:00
import "./family-chart.css";
2023-08-23 08:27:51 +00:00
import { FamilyTreeNode } from "../../utils/family_tree";
import { fmtDate } from "../../api/MemberApi";
2023-08-22 14:12:55 +00:00
2023-08-23 08:27:51 +00:00
export function ComplexFamilyTree(p: {
tree: FamilyTreeNode;
}): React.ReactElement {
const refCb = (container: HTMLDivElement) => {
if (!container) return;
2023-08-22 14:12:55 +00:00
const store = f3.createStore({
2023-08-23 08:27:51 +00:00
data: treeToF3Data(p.tree),
2023-08-22 14:12:55 +00:00
node_separation: 250,
level_separation: 150,
}),
view = f3.d3AnimationView({
store,
cont: document.querySelector("#FamilyChart"),
}),
Card = f3.elements.Card({
store,
svg: view.svg,
card_dim: {
w: 220,
h: 70,
text_x: 75,
text_y: 15,
img_w: 60,
img_h: 60,
img_x: 5,
img_y: 5,
},
card_display: [
2023-08-22 15:17:36 +00:00
(d) => `${d.data.first_name || ""} ${d.data.last_name || ""}`,
2023-08-22 14:12:55 +00:00
(d) => `${d.data["birthday"] || ""}`,
],
mini_tree: true,
link_break: false,
});
view.setCard(Card);
store.setOnUpdate((props) => view.update(props || {}));
store.update.tree({ initial: true });
};
2023-08-22 14:12:55 +00:00
return <div className="f3" id="FamilyChart" ref={refCb}></div>;
}
2023-08-22 14:57:41 +00:00
2023-08-23 08:27:51 +00:00
function treeToF3Data(node: FamilyTreeNode): f3Data[] {
const availableMembers = new Set<number>();
getAvailableMembers(node, availableMembers);
const list: f3Data[] = [];
treeToF3DataRecurse(node, list, availableMembers);
console.info(list);
return list;
}
function getAvailableMembers(t: FamilyTreeNode, s: Set<number>) {
s.add(t.member.id);
t.couples?.forEach((c) => {
s.add(c.member.id);
c.down.forEach((e) => getAvailableMembers(e, s));
});
t.down?.forEach((e) => getAvailableMembers(e, s));
}
function treeToF3DataRecurse(
node: FamilyTreeNode,
array: f3Data[],
availableMembers: Set<number>
) {
// Get all members ids
const children = node?.down?.map((c) => c.member.id.toString()) ?? [];
node.couples?.map((c) =>
c.down.forEach((m) => children.push(m.member.id.toString()))
);
array.push({
2023-08-22 15:17:36 +00:00
data: {
2023-08-23 08:27:51 +00:00
first_name: node.member.first_name ?? "_",
last_name: node.member.last_name ?? "_",
gender: node.member.sex ?? "M",
avatar: node.member.thumbnailURL ?? undefined,
birthday: node.member.dateOfBirth
? fmtDate(node.member.dateOfBirth)
: undefined,
},
id: node.member.id.toString(),
2023-08-22 15:17:36 +00:00
rels: {
2023-08-23 08:27:51 +00:00
father:
node.member.father && availableMembers.has(node.member.father)
? node.member.father.toString()
: undefined,
mother:
node.member.mother && availableMembers.has(node.member.mother)
? node.member.mother.toString()
: undefined,
spouses: node.couples?.map((c) => c.member.id.toString()),
children: children,
2023-08-22 15:17:36 +00:00
},
2023-08-23 08:27:51 +00:00
});
node?.down?.forEach((e) => treeToF3DataRecurse(e, array, availableMembers));
if (node.couples) {
for (const c of node.couples) {
array.push({
data: {
first_name: c.member.first_name ?? "_",
last_name: c.member.last_name ?? "_",
gender: c.member.sex ?? "M",
avatar: c.member.thumbnailURL ?? undefined,
birthday: c.member.dateOfBirth
? fmtDate(c.member.dateOfBirth)
: undefined,
},
id: c.member.id.toString(),
rels: {
father:
c.member.father && availableMembers.has(c.member.father)
? c.member.father.toString()
: undefined,
mother:
c.member.mother && availableMembers.has(c.member.mother)
? c.member.mother.toString()
: undefined,
spouses: [node.member.id.toString()],
children: c.down.map((c) => c.member.id.toString()),
},
});
c.down.forEach((e) => treeToF3DataRecurse(e, array, availableMembers));
}
}
}
/*
import { jsPDF } from "jspdf";
import "svg2pdf.js";
setTimeout(() => {
2023-08-22 14:57:41 +00:00
const doc = new jsPDF({
orientation: "l",
format: [1000, 1000],
});
const element = document.getElementById("FamilyChart");
console.log(element);
doc.svg(element!.children[0], { height: 1000, width: 1000 }).then(() => {
// save the created pdf
//doc.save("myPDF.pdf");
2023-08-22 14:57:41 +00:00
});
}, 6000);*/