Compare commits
2 Commits
d0013d41bb
...
881b8c0d60
| Author | SHA1 | Date | |
|---|---|---|---|
| 881b8c0d60 | |||
| 784f7ecb6b |
@@ -158,11 +158,7 @@ export function FamilyMemberTreeRoute(): React.ReactElement {
|
||||
{currTab === CurrTab.BasicTree ? (
|
||||
<BasicFamilyTree tree={tree!} depth={currDepth} />
|
||||
) : currTab === CurrTab.SimpleTree ? (
|
||||
<SimpleFamilyTree
|
||||
tree={tree!}
|
||||
isUp={currMode === TreeMode.Ascending}
|
||||
depth={currDepth}
|
||||
/>
|
||||
<SimpleFamilyTree tree={tree!} depth={currDepth} />
|
||||
) : (
|
||||
<ComplexFamilyTree
|
||||
tree={tree!}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,9 +1,18 @@
|
||||
import { mdiXml } from "@mdi/js";
|
||||
import Icon from "@mdi/react";
|
||||
import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf";
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
import jsPDF from "jspdf";
|
||||
import React from "react";
|
||||
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
||||
import { Couple } from "../../api/CoupleApi";
|
||||
import { Member } from "../../api/MemberApi";
|
||||
import { useDarkTheme } from "../../hooks/context_providers/DarkThemeProvider";
|
||||
import { FamilyTreeNode } from "../../utils/family_tree";
|
||||
import { downloadBlob } from "../../utils/files_utils";
|
||||
import { getTextWidth } from "../../utils/render_utils";
|
||||
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
||||
import "./simpletree.css";
|
||||
import "./Roboto-normal";
|
||||
|
||||
const FACE_WIDTH = 60;
|
||||
const FACE_HEIGHT = 70;
|
||||
@@ -76,7 +85,7 @@ function center(container_width: number, el_width: number): number {
|
||||
return Math.floor((container_width - el_width) / 2);
|
||||
}
|
||||
|
||||
function buildSimpleDownTreeNode(
|
||||
function buildSimpleTreeNode(
|
||||
tree: FamilyTreeNode,
|
||||
depth: number
|
||||
): SimpleTreeNode {
|
||||
@@ -94,8 +103,7 @@ function buildSimpleDownTreeNode(
|
||||
|
||||
const node: SimpleTreeNode = {
|
||||
down:
|
||||
childrenToProcess?.map((c) => buildSimpleDownTreeNode(c, depth - 1)) ??
|
||||
[],
|
||||
childrenToProcess?.map((c) => buildSimpleTreeNode(c, depth - 1)) ?? [],
|
||||
member: tree.member,
|
||||
spouse: lastCouple
|
||||
? {
|
||||
@@ -131,23 +139,6 @@ function buildSimpleDownTreeNode(
|
||||
return node;
|
||||
}
|
||||
|
||||
// TODO : if useless, remove and merge up and down techniques
|
||||
function buildSimpleUpTreeNode(
|
||||
tree: FamilyTreeNode,
|
||||
depth: number
|
||||
): SimpleTreeNode {
|
||||
/*if (depth === 0) throw new Error("Too much recursion reached!");
|
||||
|
||||
return {
|
||||
member: tree.member,
|
||||
children:
|
||||
depth === 1
|
||||
? []
|
||||
: tree.down?.map((c) => buildSimpleUpTreeNode(c, depth - 1)) ?? [],
|
||||
};*/
|
||||
return buildSimpleDownTreeNode(tree, depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple family tree
|
||||
*
|
||||
@@ -156,33 +147,88 @@ function buildSimpleUpTreeNode(
|
||||
|
||||
export function SimpleFamilyTree(p: {
|
||||
tree: FamilyTreeNode;
|
||||
isUp: boolean;
|
||||
depth: number;
|
||||
}): React.ReactElement {
|
||||
const darkTheme = useDarkTheme();
|
||||
|
||||
const tree = React.useMemo(
|
||||
() =>
|
||||
p.isUp
|
||||
? buildSimpleUpTreeNode(p.tree, p.depth)
|
||||
: buildSimpleDownTreeNode(p.tree, p.depth),
|
||||
[p.tree, p.isUp, p.depth]
|
||||
() => buildSimpleTreeNode(p.tree, p.depth),
|
||||
[p.tree, p.depth]
|
||||
);
|
||||
|
||||
const height = p.depth * (CARD_HEIGHT + LEVEL_SPACING) - LEVEL_SPACING;
|
||||
|
||||
console.info(`tree width=${tree.width} height=${height}`);
|
||||
|
||||
const doExport = async (onlySVG: boolean) => {
|
||||
const el = document.querySelector(".simpletree")!;
|
||||
const svg = el.outerHTML;
|
||||
|
||||
// Download in SVG format
|
||||
if (onlySVG) {
|
||||
const blob = new Blob([svg], {
|
||||
type: "image/svg+xml",
|
||||
});
|
||||
|
||||
downloadBlob(blob, "ArbreGenealogique.svg");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const PDF_MARGIN = 10;
|
||||
|
||||
// Download in PDF format
|
||||
const doc = new jsPDF({
|
||||
orientation: "l",
|
||||
format: [height + PDF_MARGIN * 2, tree.width + PDF_MARGIN * 2],
|
||||
});
|
||||
|
||||
doc.setFont("Roboto", "normal");
|
||||
|
||||
await doc.svg(el, {
|
||||
x: PDF_MARGIN,
|
||||
y: PDF_MARGIN,
|
||||
height: height,
|
||||
width: tree.width,
|
||||
});
|
||||
|
||||
// Save the created pdf
|
||||
doc.save("ArbreGenealogique.pdf");
|
||||
};
|
||||
|
||||
const exportPDF = () => doExport(false);
|
||||
|
||||
const exportSVG = () => doExport(true);
|
||||
|
||||
return (
|
||||
<TransformWrapper maxScale={15} minScale={0.2}>
|
||||
<TransformComponent wrapperStyle={{ width: "100%", flex: "1" }}>
|
||||
<svg
|
||||
width={tree.width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<NodeArea node={tree} x={0} y={0} />
|
||||
</svg>
|
||||
</TransformComponent>
|
||||
</TransformWrapper>
|
||||
<div>
|
||||
<div style={{ textAlign: "right" }}>
|
||||
<Tooltip title="Exporter le graphique au format PDF">
|
||||
<IconButton onClick={exportPDF}>
|
||||
<PictureAsPdfIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Exporter le graphique au format SVG">
|
||||
<IconButton onClick={exportSVG}>
|
||||
<Icon path={mdiXml} size={1} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<TransformWrapper maxScale={15} minScale={0.2}>
|
||||
<TransformComponent wrapperStyle={{ width: "100%", flex: "1" }}>
|
||||
<svg
|
||||
className={`simpletree ${
|
||||
darkTheme.enabled ? "simpletree-dark" : ""
|
||||
}`}
|
||||
width={tree.width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<NodeArea node={tree} x={0} y={0} />
|
||||
</svg>
|
||||
</TransformComponent>
|
||||
</TransformWrapper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
7
geneit_app/src/widgets/simple_family_tree/simpletree.css
Normal file
7
geneit_app/src/widgets/simple_family_tree/simpletree.css
Normal file
@@ -0,0 +1,7 @@
|
||||
.simpletree-dark path {
|
||||
stroke: white;
|
||||
}
|
||||
|
||||
.simpletree-dark tspan {
|
||||
fill: white;
|
||||
}
|
||||
Reference in New Issue
Block a user